-
Notifications
You must be signed in to change notification settings - Fork 127
btc: descriptor wallet support #1659
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
Conversation
39a40a8
to
ed93468
Compare
NOTE: ./alpha -named createwallet wallet_name=desc descriptors=true
cp alpha desc
# edit desc with "-rpcwallet=desc" I'm contemplating either: (a) regenerating one of the alpha/beta/gamma/delta wallets to be a descriptor wallet, but I'm not excited about a big binary update of the chain data tarball, or (b) |
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.
Can we create a descriptor wallet in the harness?
Yes, question is this: #1659 (comment) New "epsilon" wallet or regenerate harnesschain tarbal with say, beta, turned into a descriptor wallet? I wanted opinions on that choice. |
On second thought, regenerating the harness chain archive with v23 is likely to make it unusable for say v0.21. I think making another wallet in the shell script is best. |
Oops. I should have seen that. I don't have a strong preference either way. Do we even need to commit the tarball? It's about 5 MB. |
Time to start harness with tarball: ~13 sec (not counting the history command at the end) |
🤣 yeah. |
Not surprisingly, The BTC harnesschain.tar.gz is now deleted. The harness directory has a version file to detect if it was extracted from out out-of-date archive. Tested the BTC, LTC, and BCH harnesses. DOGE is independent, so unaffected. |
I made this comment on another recent pr, but if someone were to make an internal descriptor wallet with this version of the client and then tried to go back to an earlier version of dexc, they could no longer use the wallet. I think there could be some version saved in the database that is upped to stop the user at start-up and tell them that they must use a newer dexc version. |
34ae4dd
to
1147489
Compare
Personally don't think that's needed. The check for descriptor wallets in older dexc also stops the user at start-up. I think the README can warn that if you use a descriptor wallet with 0.5, you won't be able to use it with 0.4. |
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've got my head around the basics now. This is looking good. I'll swing back on this within a day or two.
// Fingerprint is "Exactly 8 hex characters for the fingerprint of the key | ||
// where the derivation starts". | ||
Fingerprint string |
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.
Notably,
unsigned char fingerprint[4]; //!< First 32 bits of the Hash160 of the public key at the root of the path
So one could conceivably devise a scheme where we don't do path examination of the listdescriptors true
result, but instead just match a key to the fingerprint. I only mention this because when I run listdescriptors true
on the beta wallet, I notice that the same private key is listed for all functions.
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.
That's generally correct in practice. The search loop I have in the RPC code really could stop after finding the xprv with the matching fingerprint, and checking that it is indeed a private key instead of proceeding to match the path too.
I decided to match the paths since we are required to tolerate fingerprint collisions (although it's fairly unlikely), and the different address types are allowed to use descriptors with different fingerprints (you can import one of your choice just for say wpkh and make it 'active' even though bitcoind uses the same master for all by default)
Namely, right after IsPrivate
passes here we could just go straight to DeepChild
to get the private key and verify the public key matches. If the keys match, they match.
For reference, the fingerprint is computed below:
dcrdex/dex/networks/btc/descriptors.go
Lines 90 to 92 in b19f258
func keyFingerprint(key *hdkeychain.ExtendedKey) []byte { | |
return btcutil.Hash160(pubKeyBytes(key))[:4] | |
} |
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.
Beautiful!
ParentDesc string `json:"parent_desc"` // e.g. "wpkh([b940190e/84'/1'/0']tpubDCo.../0/*)#xn4kr3dw" meaning range of external addresses | ||
HDKeyPath string `json:"hdkeypath"` // e.g. "m/84'/1'/0'/0/0" | ||
HDMasterFingerprint string `json:"hdmasterfingerprint"` // e.g. "b940190e" |
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.
Three fields aren't actually used.
client/asset/btc/wallettypes.go
Outdated
type listDescriptorsResult struct { | ||
WalletName string `json:"wallet_name"` | ||
Descriptors []*struct { | ||
Descriptor string `json:"desc"` // public or private depending on private RPC arg |
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.
This is the only field actually used, I think.
dex/testing/btc/harness.sh
Outdated
# descriptors and no passphrase. $1 is the node to create the wallet on. | ||
# Possible arguments to createwallet are: | ||
# "wallet_name" ( disable_private_keys blank(boolean) "passphrase" avoid_reuse descriptors load_on_startup external_signer ) | ||
export NEW_WALLET_CMD="./\$1 -named createwallet wallet_name=\$2 descriptors=false load_on_startup=true" |
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.
Would be good to have a descriptors=true
alternative so we can test plumb into e2e and loadbot tests.
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.
Added an optional arg
8c31e24
to
6d862ef
Compare
dex/networks/btc: descriptor parsing primitives This adds descriptor parsing functions and types. See https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md client/asset/btc: listdescriptors and get priv key This adds the RPC code to find the matching private key descriptor from the listdescriptors response to the address public key in the getaddressinfo response. Double check private key accessibility if wallet is unlocked. harness: make btc descriptor wallets This makes the beta and gamma wallets into descriptor wallets. This also removes the BTC test chain archive. The new-wallet script has an optional $3 arg for the descriptors bool.
This works toward supporting Bitcoin descriptor wallets. Resolves #1601.
listdescriptors private=true
andgetaddressinfo
getaddressinfo
with the extended private key fromlistdescriptors
(*rpcClient).privKeyForAddress
to switch between eitherdumpprivkey
or above approach depending on configSee https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md