-
Notifications
You must be signed in to change notification settings - Fork 44
Support For Arbitrary Number of Keychains #318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Support For Arbitrary Number of Keychains #318
Conversation
Pull Request Test Coverage Report for Build 18619531443Details
💛 - Coveralls |
7059451 to
0df1a2a
Compare
|
The next few commits:
|
524d4df to
6c50f00
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quick review on 6c50f00: given your commit message I thought you were adding the Wallet::new constructor here, but the commit only contains the addition of the KeyRing to the Wallet type. Mind you this might be enough for this commit. Feel free to add a new commit with the constructor, or add it to this commit; whatever you think works best.
Also note that fa984e6 and 6c50f00 don't compile because of
impl AsRef<bdk_chain::tx_graph::TxGraph<ConfirmationBlockTime>> for Wallet {
fn as_ref(&self) -> &bdk_chain::tx_graph::TxGraph<ConfirmationBlockTime> {
self.keychain_tx_graph.graph()
}
}on line 2638 of wallet/mod.rs. You could comment it out with the rest to ensure everything builds.
wallet/src/wallet/changeset.rs
Outdated
| pub keyring: keyring::changeset::ChangeSet<K>, | ||
| /// Changes to the [`LocalChain`](local_chain::LocalChain). | ||
| pub local_chain: local_chain::ChangeSet, | ||
| pub chain: local_chain::ChangeSet, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if the renaming of this field is intentional and I don't have an opinion on whether it's a good idea or not yet, but it probably belongs in a different PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did the rename since the corresponding field in Wallet is so. reverted the rename in 588121b.
7c976e1 to
588121b
Compare
|
I am so sorry 😢 . I completely messed dividing the commits into two. Things should be fixed now! |
|
This one now needs a big ol' rebase @110CodingP. |
added #![allow(unused)] to circumvent clippy errors.
Modified the `ChangeSet` accordingly.
Also added default version of `reveal_next_address`.
So that advanced users can specify custom genesis_hash and lookahead or enable spk_cache.
dfdcd83 to
4a3486e
Compare
|
Wow! this one was HUGE! For the first few commits I did something like |
|
Adding an example like this fails: // Simple KeyRing, allowing us to build a standard 2-descriptor wallet.
let external_descriptor: &str = "tr(tpubD6NzVbkrYhZ4WyC5VZLuSJQ14uwfUbus7oAFurAFkZA5N3groeQqtW65m8pG1TT1arPpfWu9RbBsc5rSBncrX2d84BAwJJHQfaRjnMCQwuT/86h/1h/0h/0/*)";
let internal_descriptor: &str = "tr(tpubD6NzVbkrYhZ4WyC5VZLuSJQ14uwfUbus7oAFurAFkZA5N3groeQqtW65m8pG1TT1arPpfWu9RbBsc5rSBncrX2d84BAwJJHQfaRjnMCQwuT/86h/1h/0h/1/*)";
let mut keyring: KeyRing<KeychainKind> = KeyRing::new(Network::Regtest, KeychainKind::External, external_descriptor);
keyring.add_descriptor(KeychainKind::Internal, internal_descriptor, false);
let mut wallet = Wallet::new(keyring);With a stacktrace containing: thread 'main' panicked at /Users/user/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/miniscript-12.3.5/src/descriptor/key.rs:687:14:
The key should not contain any wildcards at this pointAfter a bit of poking around I found that this is coming from the descriptor_id() method called inside insert_descriptor(): pub fn insert_descriptor(
&mut self,
keychain: K,
descriptor: Descriptor<DescriptorPublicKey>,
) -> Result<bool, InsertDescriptorError<K>> {
let did = descriptor.descriptor_id();I don't have time to finish the investigation today, but just pointing it out. I'm not sure yet why this worked well in the multi-keychain-wallet crate and not here, nor why the code for the constructor is so different than the other previous constructors like |
|
This almost scared me for a moment 😅 ! Using descriptors with unhardened paths seems to work. |
|
Total facepalm. Sorry @110CodingP! Ok so I simplified the example a little bit just to keep a really neat version of how to build a wallet as close as you can from the 2.0 approach. |
23d0e7a to
20096ff
Compare
Also added a folder to consolidate example utilities.
9134ce2 to
ac4c44f
Compare
042f5e2 to
4403cdb
Compare
4403cdb to
16d6f8c
Compare
As policy is anyway being phased out in 3.0
Incorporated `check_wallet_descriptor` in `KeyRing::new` and `KeyRing::add_descriptor` to catch multipath and hardened descriptors. Introduced new variants to `DescriptorError` to report cases when trying to add duplicate desc or keychain. Did not provide the other desc inside `KeychainAlreadyExists` variant (similar other keychain inside `DescAlreadyExists`) because introducing type parameter to `DescriptorError` implies introducing one to `IntoWalletDescriptor`. The add_descriptor function returns a `KeyRing::Changeset` since this would eventually be required when we introducing APIs to add descriptors to `Wallet.keyring`.
af0e9eb to
4177147
Compare
Completes first 2 of the Todos? |
Also refactored corresponding function for `KeyRing` and associated error types.
Also modified `simple_keyring.rs` to incorporate the new persistence functions.
for e33e007 : Also ig |
|
Also is |
and implemented `apply_update`
which in turn calls `Wallet::balance_with_params_conf_threshold` under the hood. Also added some test utilities and a test to check the implementation of the new methods.
Description
This PR allows the
Wallettype to track any number of keychains (descriptors). It is a breaking change. Because of the size of the diff, we'll try to make it reviewable 1 commit at a time. See "Reviewing the Diff" section for a breakdown of each commit.Related Issues: #188, #227
Related PRs: #230, #226
Exploratory Crate: multi-keychain-wallet
Read this one-pager for an overview of user-facing impacts of the proposed feature.
Todo
KeyRing::newshould throw an errors on certain conditionsWalletAPI docs (Kneeds to beOrdfor example)SyncRequestandSyncResponseneed to be generic inKWallet::newshould callWallet::create_with_paramsChangeSet.Reviewing the Diff
The diff on this PR is fairly big because it touches a lot of the wallet, even if the changes are not that "deep" in terms of business logic.
In order to make it easy for reviewers, we'll be trying to keep the commit history easy to review one commit at a time. Once the PR is ready to merge, we can squash some of those commits in order to simplify the commit history if need be.
The following is a table that outlines what each commit does.
KeyRingtype.ChangeSetrequired for the `KeyRing.Wallet::newwhich takes a single argument, aKeyRing.AddressInfoto take in a generic keychain. AddWallet::reveal_next_address,Wallet::reveal_next_default_addressAPIs.Wallet::with_custom_params.Changelog notice
TODO
Deployment Strategy
As per discussions over different dev calls, this feature is proposed as a breaking change on the
WalletAPI, since the old constructors are removed. It might not be ready in time for the 3.0 release (given the size of the diff and its relative position on the totem pole of priorities). If it does not make the cut for the 3.0 release, it will simply be kept updated and rebased on master until it is ready for merging into a breaking change ready branch for the 4.0 release.