fix(wallet): remove the generic from wallet#1387
fix(wallet): remove the generic from wallet#1387evanlinjin merged 1 commit intobitcoindevkit:masterfrom
Conversation
|
Thanks for working on this. In the future, please state in the ticket that you'll be working on it, otherwise we'll result in duplicate work. |
|
Will do! Thanks for the tip |
|
It is not obvious why this change is useful for removing |
|
Broke no_std with an error variant. Will fix soon. |
|
So after looking and thinking about this more closely I'd expect two error enums, one for each interaction: enum LoadError {
#[cfg(feature = "std")]
StdIo(std::io::Error),
Other(String),
}
enum CommitError {
#[cfg(feature = "std")]
StdIo(std::io::Error),
Other(String),
Inconsistent(String) // maybe?
}But looking at it we don't really get much value from this structure unless we add specific error variants that occur with our changesets that we can report and react to. But our changeset API is (mostly) makes invalid representations impossible. In so far as invalid representations are possible they depend on the concrete changeset which the backend doesn't have access to. The correct thing to do here I think is to return cc @evanlinjin |
|
Added my interpretation of how we would use |
LLFourn
left a comment
There was a problem hiding this comment.
This looks great. Main question is whether we're comfortable with this in bdk_chain or we should just make a new bdk_persist crate which defines this trait. It is rather orthogonal to everything else in bdk_chain and now it adds another dependency. If bdk_core existed (#1155) likely it wouldn't even depend on bdk_chain. "persist" could also be a feature flag in bdk_chain.
As a side note, for some reason we use this trait in the bdk_chain examples but I'm not sure why. They could easily be rewritten to not depend on this trait.
cc @thunderbiscuit wdyt about anyhow::Error. How do you handle errors in the FFI?
evanlinjin
left a comment
There was a problem hiding this comment.
This looks great! However, I'm wondering whether it's better to introduce our own lightweight trait instead on using anyhow (which is another dependency).
pub trait PersistError: core::any::Any + Debug {}
pub fn an_example_method() -> Result<(), Box<dyn PersistError>> { todo!() }The downsides of this is that the PersistenceBackend implementations may need to wrap their returned errors in a new type to implement PersistError. However, I see this as a minor compromise as they need to implement PersistenceBackend anyway?
|
Committed those changes for review |
I don't think this is a minor downside for the implementer. It means wrapping all errors from the underlying backend in a type and implementing a trait on the wrapped types. Also then what about downcasting? What about backtraces? I'm leaning towards putting the persist trait in its own crate |
|
Should I continue by breaking out into a bdk persist crate? Or is that best left for another PR? |
I'd be in favor of finding a solution that doesn't require anyhow, if possible. Currently, the pub struct PersistError(pub Box<dyn fmt::Debug + Send + Sync>);and make The persist module could also just live in |
|
@rustaceanrob we haven't reached a consensus on this. Feel free to put in your input. |
Replicating what anyhow does 100% is definitely not in scope. You can attach context anyhow errors and backtraces are automatically attached if your rust version is new enough. Of course we don't need this but it is nice to have.
And also
Yes that could also work but I have a feeling the persist trait will be updated much less frequently than |
I'm not familiar with anyhow but reading up on it now. In general I favour not reimplementing the wheel, and think that using tried-and-true libraries is more robust over time (i.e., I am in favour of using anyhow instead of building similar behaviour in-house). One question I'd ask is if we add the anyhow dependency here, does it mean we'll have 2 approaches to errors across the codebase? Or would it be used in this single instance only? As for FFI, we can't pass the errors directly (very!) unfortunately, so we roughly have to create new ones and map the Rust errors to those. This change would not impact us too much either way; do whatever is best for the Rust side of things and we'll adapt. |
|
I understand the reluctance to bring in a new dependency, but as @LLFourn described, the behavior that we are looking for would just be a re-implementation of what On structure, I am not seeing
I have contributed to code with public |
There was a problem hiding this comment.
Fine to leave it here for now. I still have a weak preference for moving it into bdk_persist rather than bdk_core (don't really want bdk_core to depend on anyhow).
ACK bfadae7
Might be nice to clean up the commit history before merging. I think this should just be one commit on top of master if we can manage it.
ValuedMammal
left a comment
There was a problem hiding this comment.
I acknowledge all the points in the previous discussion, and I can offer these review comments :)
|
Should I squash commits locally? I only ask because I think there's also a feature to do it on the merge GUI. |
ValuedMammal
left a comment
There was a problem hiding this comment.
Sorry, I have a couple more notes.
Primary suggestions are for store.rs, and I'm also wondering whether the From impl in wallet::error module is needed. Any nits are definitely not blockers.
As far as squashing, my preference is to use git rebase --interactive.
d012041 to
c958fb4
Compare
|
Squashed to c958fb4 with changes suggested from @ValuedMammal. Should be ready for CI |
jirijakes
left a comment
There was a problem hiding this comment.
This change silently removes Sync and Send auto traits from Persist and therefore from anything that uses it (e. g. Wallet).
One way to deal with it could be:
pub struct Persist<C> {
backend: Box<dyn PersistBackend<C> + Send + Sync>,
stage: C,
}but that would require every backend to be Send + Sync, even when not needed.
I am not sure how big of a problem this is, but given that Wallet until now tried to be Sync + Send, it may be an issue.
|
As far as I can tell |
It is in alpha.8. But I really don't know whether this was some accident or deliberate action. I don't know whether this is something to care about or not. |
|
Interesting. I tried messing with it and I am not aware of any other work-arounds besides the one you proposed. Between |
|
That's a great point @jirijakes what made you realize that? I mean is it evident from looking at the code, or is there something more subtle going on? I do think it's generally desirable to maintain thread safety of the wallet. |
Rather a coincidence. A few days ago I read articles (mainly this) about this kind of semver breakage. Having the articles fresh in mind and seeing |
|
I updated the PR to include the |
|
Yeah this change implies that we must force |
c46e5b9 to
f18372f
Compare
f18372f to
e51af49
Compare
evanlinjin
left a comment
There was a problem hiding this comment.
ACK e51af49
This is good work. However, I'm really not a fan of introducing the anyhow dependency to the bdk_chain crate.
I think we should create a separate RP which introduces a separate bdk_persist crate.
81de8f6 feat(bdk-persist): extract persistence traits to new crate (Rob N) Pull request description: ### Description #1387 introduced `anyhow` as a dependency to remove generics from `Wallet`. Introducing a new crate for persistence types removes the dependency on `anyhow` for `bdk_chain`. Resolves #1409, as well as removing the old documentation for "tracker". ### Notes to the reviewers Open for any comments. ### Changelog notice - Introduce `bdk-persist` crate ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### New Features: * [ ] I've added tests for the new feature * [ ] I've added docs for the new feature #### Bugfixes: * [ ] This pull request breaks the existing API * [ ] I've added tests to reproduce the issue which are now passing * [x] I'm linking the issue being fixed by this PR ACKs for top commit: evanlinjin: ACK 81de8f6 Tree-SHA512: 29b192b13f3951cc67c06bec7f788d8d7a4aeaf2ffcbf9476d4a6567529d284a93594c8d94b69741a68a9aadfdc9f6c4178084a2298c505e8e0d505219400382
db47347 test(wallet): add thread safety test (Rob N) Pull request description: ### Description `Wallet` auto-implements `Send` and `Sync` after removing the generic. This test is a compile time error if there are changes to `Wallet` in the future that make it unsafe to send between threads. See #1387 for discussion. ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### New Features: * [x] I've added tests for the new feature * [ ] I've added docs for the new feature #### Bugfixes: * [ ] This pull request breaks the existing API * [ ] I've added tests to reproduce the issue which are now passing * [ ] I'm linking the issue being fixed by this PR ACKs for top commit: evanlinjin: ACK db47347 Tree-SHA512: 490e666bc503f15286268db7e5e2f75ee44ad2f80251d6f7a01af2a435023b87607eee33623712433ea8d27511be63c6c1e9cad4159b3fe66a4644cfa9e344fb
Description
The
PersistenceBackenduses generics to describe errors returned while applying the change set to the persistence layer. This change removes generics wherever possible and introduces a new public error enum. Removing the generics fromPersistenceBackenderrors is the first step towards #1363Update: I proceeded with removing the generics from
Walletby introducing aBox<dyn PersistenceBackend>.Notes to the reviewers
This one sort of blew up in the number of changes due to the use of generics for most of the
Walleterror variants. The generics were only used for the persistence errors, so I removed the generics from higher level errors whenever possible. The error variants ofPersistenceBackendmay also be more expressive, but I will level that up for discussion and make any changes required.Changelog notice
PersistenceBackenderrors to depend on theanyhowcrate.TfromWalletChecklists
All Submissions:
cargo fmtandcargo clippybefore committingNew Features:
Bugfixes: