-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Native descriptor wallets #15764
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
Native descriptor wallets #15764
Conversation
e27cf04 to
ef2236a
Compare
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
|
Concept ACK
We'll need to support non-descriptor based wallets for some time to come. I don't think these tests should be removed. |
There's currently no way to create a wallet with older wallet versions. Since descriptor wallets are used by default, the tests won't work with |
I think that's a hard requirement. Native descriptor wallet is such a large change that we need to maintain full test coverage of the old wallet version. |
|
I had a look over the PR and it's surprisingly clean and simple. But while I understand the impulse to want to replace old code with new code and drop support for things like creating wallets in the current format, I think the PR could be actually simpler, and users would be better off if this took a more conservative approach and just added descriptor functionality as a new optional feature alongside existing functionality, rather than trying to:
all in a single PR. It seems to me if this PR just stuck to (1) and saved (2) and (3) for later followup this would be easier to review, and we would have more opportunity to iterate and hammer out any problems with the new descriptor code and design while leaving existing functionality intact. Andrew could correct me if I'm wrong, but I think in practice doing what I'm suggesting wouldn't involve big changes to the PR. Mostly just restoring removed code, and maybe copying and updating existing python tests instead of updating them in place. Or adding --descriptor options to the python tests and running both variants. |
|
Really the only reason 2 and 3 were needed is because descriptor wallets bumped the wallet version number. I could instead make it a wallet flag and make descriptors something that users can choose to enable or disable in createwallet. However I felt it would be more sensible to make this a new wallet version since it does fundamentally change the definitions of ismine and watchonly. |
|
@practicalswift - it's too early to be adding nit code style comments when the concept and approach is still being discussed. Please hold back until concept discussion is over. |
|
Impressive work. Concept ACK. |
|
Obvious concept ACK. See also my (partial) attempt at #15487. We discussed some differences in todays wallet meeting on IRC. Will study this PR in more detail later. |
|
Lots of discussion on this in today's IRC meeting: http://www.erisian.com.au/meetbot/bitcoin-core-dev/2019/bitcoin-core-dev.2019-04-12-19.00.log.html#l-46 Conclusion is that @achow101 will rework this PR to use feature flags, restore the tests and remove the upgrade code. |
|
Obvious concept ACK |
|
Concept ACK on:
We need to track if a descriptor is change / receive, and whether it's active (like the keypool) or archived. This PR handles that with One thing I'm not a fan of:
To keep this PR small I suggest, in additon to what @jnewbery summarizes:
|
ef2236a to
3e0e3c2
Compare
|
I've made the changes that were discussed last Friday. I've also split up some of the commits so that they are smaller and easier to review. I'll be working on adding tests for all of this. |
3e0e3c2 to
da06671
Compare
d9b9564 to
35030a2
Compare
|
Rebased, fixed a couple of bugs, and added some tests. I'll be adding more tests soon, particularly for
No. That wouldn't make this any smaller, and I think that having private key support is an important part of descriptor wallets.
Expanding the descriptors and adding scripts and keys to the global wallet allows us to have |
67ffa66 to
1ac17ca
Compare
Store the id of the descriptor and the position in that descriptor that the scriptPubKey was derived from.
0086279 to
1326f1e
Compare
1326f1e to
8634a6b
Compare
| Needs rebase |
|
Closing this for now while the wallet restructure takes place. |
|
I think this was superseded by #16528 in case anybody is wondering why it wasn't reopened. |
Introducing the wallet of the glorious future: native descriptor wallets. With native descriptor wallet, addresses are generated from descriptors. Instead of generating keys and deriving addresses from keys, addresses come from the scriptPubKeys produced by a descriptor.
Descriptor wallets will now store only keys, keymetadata, and descriptors. Keys are derived from descriptors but those keys are also stored in order to make signing work faster and be less complicated. In order to allow choosing different address types, 6 descriptors are needed for normal use. There is a pair of primary and change descriptors for each of the 3 address types. With the default keypool size of 1000, each descriptor has 1000 keys and scriptPubKeys pregenerated. This has a side effect of making wallets very large since 6000 keys are generated by default, instead of the current 2000. This can probably be improved in the future as we probably don't need so many addresses for each address type.
Descriptors can also be imported with a new
importdescriptorRPC.Native descriptor wallets also redefines how ismine and watchonly work. Ismine is changing to the simpler model of "does this scriptPubKey exist in this wallet". To facilitate this, all of the scriptPubKeys for all of the descriptors are computed on wallet loading. A scriptPubKey is considered
ISMINE_SPENDABLEif it appears in the set of scriptPubKeys for the wallet. Because of this ismine change, watchonly is also redefined. A wallet can no longer contains watchonly things and non-watchonly things. Instead wallets are either watchonly (by having private keys disabled) or not. There is no mixing of watchonly and non-watchonly in a wallet. Some tests that relied on watchonly behavior had to be removed (i.e. part offeature_segwit.py)Additionally several RPCs related to importing and dumping data from a wallet are incompatible with descriptor wallets. These RPCs (
addmultisigaddress,importaddress,importpubkey,importmulti,importprivkey, anddumpprivkey) are disabled for normal use.This PR is built on #15741 for batched writing to the wallet so
TopUpKeyPoolworks faster, and on #15761 for upgrading wallets with a RPC.