-
Notifications
You must be signed in to change notification settings - Fork 330
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
[wallet] Enable support for single descriptor wallets #1533
[wallet] Enable support for single descriptor wallets #1533
Conversation
Much love for this one 😉 |
What should be the function signature and behavior of |
Thanks for the input Evan about the new/load taking only and all that's required to build, and further methods that provide setter/validators to be optional. While we're on the topic and refactoring of the builder I figured I would just ask here instead of opening a new issue: Q1Most of the fields on the Q2I see that the
Don't we scan up to the stop gap? I know this from experience when looking at the Esplora logs on full scan and syncs (for example a stop gap of 3 with a lookahead of 100 will query the Esplora instance for only 4 addresses), so not sure if maybe it refers to something else?
Wait so is it persisted then? Or by that do we mean it can't be altered per session but altered on every Q3Related to (Q2), I know (think?) the Sorry I know it's a lot but I did not have time to review #1514 and I'm just now after the week in Nashville confident enough to ask my questions and comment on the shape of the API. Cheers! |
The docs describing the "lookahead" pertain specifically to the correct functioning of an edit: see below
I think it's a valid question.. |
Since single descriptor wallets are the advanced user/unusual case I think any |
That sort of makes it sound like it could be a pretty good footgun then no? Big stop gap, tiny lookahead, your wallet not finding your txs? I have not, however, been able to reproduce this locally, so I'm still unclear about what this lookahead is doing, and because it's part of the public API of the
More notes on this: the docs here say:
Again this makes it sound close to the concept of the stop gap, but I assume it's different somehow or a more generalized version of it that can be used in the deeper logic of the KeychainIndex? That's as far as the API docs go. I'll try to look at where it's actually used in the chain crate tomorrow and report back. |
@thunderbiscuit Ah, you're right, the lookahead doesn't appear to have a role during full scan for esplora because we get the SPKs to sync by calling For sync it's also not relevant because we only sync SPKs that are already revealed. In short, the lookahead defines a number of scripts to derive ahead of time without revealing them. If you do a full scan with the default lookahead of 25 and persist the wallet, then on subsequent loads edit: Nope that's also wrong. we don't persist derived SPKs, only the value of One way to illustrate the effect of the lookahead is to create a wallet with the default value of 25. Then peek at address index 25. The method For context one of the reasons we chose to make the lookahead configurable is because for a short time we had it set to 1000 and users reported unbearably long load times. Beyond that, I don't think it's something users should generally care about other than to know it exists |
This comment was marked as outdated.
This comment was marked as outdated.
Would it be easier to just bring back the |
@ValuedMammal I think I agree with you here. What I am suggesting requires too much work. What you suggest works good enough to make the users happy. |
After sleeping on it I also support avoiding the panics by just pulling from the I can also see that @evanlinjin's suggested builder change of making We should finalize these decisions first thing in tomorrow's dev call so @ValuedMammal can finish up this PR. |
5fc32da
to
bf35d00
Compare
I didn't touch the method names for |
858aafc
to
a723269
Compare
Attempting to load a persisted wallet with no change desc caused an error when reading from sqlite - currently investigating Pushed a fix in d4fbe66 |
As requested over the dev call my comment above about the method names on the load builder does not need to be addressed here, and instead can be reviewed in a separate PR: #1537. |
d5a023f
to
914316f
Compare
Followup question: when loading a single descriptor wallet
|
00d4c1f
to
035b329
Compare
I think we should error since we are meant to check the loaded changeset's descriptor against the provided descriptor. Also refer to my comment #1537 (comment) which would (in my opinion) make our API communicate the "checking" part more clearer. |
I also think we should error if LoadParams doesn't exactly match what's in the loaded file, including if the change_descriptor value in file not matching LoadParams as Some or None. |
I think we need to rethink the pub fn check_descriptor<D>(mut self, keychain: KeychainKind, exp: Option<D>, extract_keys: bool) -> Self {
todo!()
} I think an API like this makes sense for what you are proposing. |
that allows creating a wallet with a single descriptor.
when selecting a wallet row from sqlite. This is consistent with the structure of the wallet `ChangeSet` where the fields `descriptor`, `change_descriptor`, and `network` are all optional.
31cef22
to
62f143e
Compare
@evanlinjin I added your suggestion, happy to make further tweaks if anything is missing. Edit: still needs work |
to just `descriptor` that takes a `KeychainKind` and optional `D: IntoWalletDescriptor` representing the expected value of the descriptor in the changeset. Add method `LoadParams::extract_keys` that will use any private keys in the provided descriptors to add a signer to the wallet.
62f143e
to
3951110
Compare
I changed the |
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.
ACK 3951110
This turned out bigger than I expected but should be a good solution for the projects that need it.
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.
ACK 13e7008
…ate rather than set 2391b76 refactor(wallet)!: rename LoadParams methods (thunderbiscuit) Pull request description: This PR is a follow up to the dev call discussion where we decided it was better to PR these changes separate from #1533. This is a breaking change, but I think it's worth it because those will potentially cause runtime errors for users that expect one thing to happen and realize it's something else. Left out of this PR but as surfaced in the call probably worth discussing is whether these methods make sense at all or whether they should be removed entirely. What does it mean to return an error when someone loads a wallet from persistence for which the genesis hash doesn't match the one persisted? Maybe worth a new issue; this PR simply attempts to name them correctly. ### Description See [Q1 in comment here](#1533 (comment)) for more context into the initial question. Two of the methods on the builder that loads a wallet were checkers/validators rather than setters: - `network()` - `genesis_hash()` This is confusing for users because when loading a wallet from persistence those things are persisted and cannot be changed, and yet seemingly the option to do that is there with those methods (so now you're re-thinking what you think you know about the changeset and persistence). Moreover, the fields on the [`LoadParams` type](https://docs.rs/bdk_wallet/1.0.0-beta.1/src/bdk_wallet/wallet/params.rs.html#116-124) are correctly named `check_network` and `check_genesis_hash`. This PR simply brings those two methods in line with what they actually do and set on the struct they modify. This modification was not done on the `descriptors()` method, because that one is both a validator and a setter if the descriptors passed contain private keys. Note that I chose the names `validate_network` and `validate_genesis_hash` but I'm not married to them. If others prefer `check_network` and `check_genesis_hash`, I'm happy to fix them that way instead! ### Changelog notice ```md Breaking: - The `LoadParams` type used in the wallet load builder renamed its `network()` and `genesis_hash` methods to `check_network()` and `check_genesis_hash`. [#1537] [#1537]: #1537 ``` ### 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: * [x] 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: notmandatory: ACK 2391b76 Tree-SHA512: 6852ad165bab230a003b92ae0408176055f8c9101a0936d2d5a41c2a3577e258b045a7f4b796d9bab29ed261caf80b738c4338d4ff9322fbddc8c273ab0ff914
// Create a new wallet from descriptors | ||
let mut wallet = Wallet::create(descriptor, internal_descriptor) | ||
let mut wallet = Wallet::create_single(descriptor) |
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.
Nice! This looks great.
The change descriptor is made optional, making this an effective reversion of #1390 and enables creating wallets with a single descriptor.
fixes #1511
Notes to the reviewers
PR 1390 also removed an error case
ChangePolicyDescriptor
and this can possibly be added back. In the case the wallet only has a single descriptor we allow any utxos to fund a tx that aren't specifically marked unspendable regardless of the change spend policy.Changelog notice
Wallet::create_single
that expects a singleD: IntoWalletDescriptor
as input and enables building a wallet with no internal keychain.Checklists
All Submissions:
cargo fmt
andcargo clippy
before committingNew Features: