Skip to content

Conversation

Sjors
Copy link
Member

@Sjors Sjors commented Jun 25, 2021

Depends on #26728.

This PR expands the wallet RPC gethdkey introduced in #26728. It takes a BIP32 path as argument and returns the xpub, along with the master key fingerprint.

To test this PR:

  • create a regular descriptor wallet
  • call getxpub m/86h/0h/0h
  • call listdescriptors, compare the xpub in the tr() descriptor with the previous step

Bigger picture

This paves the way for using Bitcoin Core as one signer in a multisig setup. It simplifies the proposed flow in #22067.

The eventual flow would be:

  1. Create a blank wallet with a seed (either with no descriptors, or where its single key descriptors are not active, so they don't get used when calling getnewaddress).
  2. Call getxpub m/87h/0h/0h (as suggested in BIP 87)
  3. (Manually, with Specter or with a simple Python utility - TBD): craft a multisig descriptor containing this xpub
  4. Call importdescriptors which will allow the import if its own fingerprint is recognized (and after checking the xpub)
  5. The usual flow with getnewaddress, send and walletprocesspsbt (and their GUI equivalents)

This PR makes step (2) possible.

Step (1) would require a followup, because blank wallets currently can't have a seed. Step 4 would also require a followup, so that importdescriptors treats an xpub as if it was an xpriv, after checking that it can derive the xpub from the seed (that matches the fingerprint)

On the GUI side a wizard could perform the above steps and guide the user, where they either:

  • export their own xpub and then import a descriptor from somewhere else (performing some sanity checks); or
  • import xpub(s) from other wallets, compose a multisig and get the descriptors for export; or
  • get xpub(s) from connected hardware devices and configure a multisig (with or without a key on their machine)

@DrahtBot
Copy link
Contributor

DrahtBot commented Jun 25, 2021

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
Concept ACK fjahr, Zero-1729, JeremyRubin, aureleoules, jonatack
Approach ACK w0xlt
Stale ACK lsilva01, mjdietzx, Rspigler

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #29154 (tests: improve wallet multisig descriptor test and docs by mjdietzx)
  • #29136 (wallet: addhdkey RPC to add just keys to wallets via new void(KEY) descriptor by achow101)
  • #29130 (wallet: Add createwalletdescriptor and gethdkeys RPCs for adding new automatically generated descriptors by achow101)
  • #29124 (wallet: Automatically repair corrupted metadata with doubled derivation path by achow101)
  • #29016 (RPC: add new listmempooltransactions by niftynei)
  • #28976 (wallet: Fix migration of blank wallets by achow101)
  • #28868 (wallet: Fix migration of wallets with txs that have both spendable and watchonly outputs by achow101)
  • #28710 (Remove the legacy wallet and BDB dependency by achow101)
  • #28610 (wallet: Migrate entire address book entries to watchonly and solvables too by achow101)
  • #28574 (wallet: optimize migration process, batch db transactions by furszy)
  • #28333 (wallet: Construct ScriptPubKeyMans with all data rather than loaded progressively by achow101)
  • #28192 (ParseHDKeypath: support h as hardened marker by Sjors)
  • #27865 (wallet: Track no-longer-spendable TXOs separately by achow101)
  • #27286 (wallet: Keep track of the wallet's own transaction outputs in memory by achow101)
  • #26008 (wallet: cache IsMine scriptPubKeys to improve performance of descriptor wallets by achow101)
  • #24748 (test/BIP324: functional tests for v2 P2P encryption by stratospher)
  • #22838 (descriptors: Be able to specify change and receiving in a single descriptor string by achow101)

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.

@jonatack
Copy link
Member

Thanks for working on this!

@Rspigler
Copy link
Contributor

Thanks so much for continuing to work on this! Love the use of BIP 87 :)

Call importdescriptors which will allow the import if its own fingerprint is recognized (and after checking the xpub)

Yes, important to check the xpub also, not just the fingerprint, which is easy to spoof

  • export their own xpub and then import a descriptor...
  • import xpub(s) from other wallets, compose a multisig...
  • get xpub(s) from connected hardware devices...

I agree that the above 3 encompasses all use cases/needs for Bitcoin Core being a coordinator and a signer in a multisig setup.

importdescriptors should treat an xpub as if it was an xpriv, after checking that it can derive the xpub from the seed (that matches the fingerprint); it needs to copy the seed from a sibling descriptor??

Can you explain this to me more?

As for the blank wallets, why do we need to be working from blank wallets, and if xprivs are derived from seeds, how can a blank wallet have a seed?

@Sjors
Copy link
Member Author

Sjors commented Jul 1, 2021

It depends on how we want to define blank. It would be empty except for a seed, so without any descriptors in it.

If a wallet has a seed and you call importdescriptors on it with some multisig descriptor, it should check the fingerprint(s) and path(s) mentioned in that descriptor. It should then derive the xpriv & xpub for that path, from the wallet seed, and check if it matches the descriptor xpub. In that case, the wallet should replace that xpub with the xpriv, as if the user provided it upon import. This avoid the dangerous act of exporting and re-importing an xpriv. That way, if you want to sign a transaction, the wallet knows it can provide one of the signatures.

@Rspigler
Copy link
Contributor

Rspigler commented Jul 6, 2021

Thank you, makes a lot of sense!

And what about sibling descriptors?

Copy link
Contributor

@lsilva01 lsilva01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review ACK 1ff7a25

@mjdietzx
Copy link
Contributor

Concept ACK

I'll be sure to update the tests/docs in #22067 to use this when this PR gets merged

@fjahr
Copy link
Contributor

fjahr commented Aug 1, 2021

Concept ACK

1 similar comment
@Zero-1729
Copy link
Contributor

Concept ACK

@Sjors
Copy link
Member Author

Sjors commented Oct 21, 2021

I managed to reconstruct the master extended private key, by combining the key part of the descriptor CExtKey with the chaincode part of the CExtPubKey stored inside that descriptor. This code is absolute trash though. I'll try to reuse some of @achow101's work in https://github.com/achow101/bitcoin/commits/upgrade-to-tr-1 which tries to solve a similar problem, for adding a taproot descriptor to an existing descriptor wallet.

@Sjors
Copy link
Member Author

Sjors commented Dec 22, 2023

I plan to re-work this on top of #29130 with a similar interface to createwalletdescriptor. That is, if you have a regular wallet with normal descriptors, it will Just Work(tm). Otherwise you need to specify which master key to use.

Initially I'll make a separate PR. If #26728 is closed in favor of the new approach in #29130 then this PR can be closed too.

@ryanofsky
Copy link
Contributor

ryanofsky commented Dec 23, 2023

Initially I'll make a separate PR. If #26728 is closed in favor of the new approach in #29130 then this PR can be closed too.

It seems like you could just rebase this on top of #29130, since the description of the PR and new commits aren't going to change that much, they will just be based on #29130 instead of #26728. Either way seems fine, though.

@Sjors
Copy link
Member Author

Sjors commented Dec 27, 2023

@ryanofsky building on #29130 introduces a new argument to specify which master key you intend to use.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jan 8, 2024

🐙 This pull request conflicts with the target branch and needs rebase.

@Sjors
Copy link
Member Author

Sjors commented Jan 12, 2024

Given that #26728 was closed, I'll just modify this PR to build on top of #29130.

(bit busy with stratum v2 stuff, but it will happen)

@Sjors
Copy link
Member Author

Sjors commented Feb 13, 2024

This seems more involved than a simple rebase. #29130 changes gethdkey to gethdkeys making it a less obvious choice to add a path argument to. We probably need a new RPC that's more similar to createwalletdescriptor in how it's called.

I probably won't have time for this in the near future, so I'm closing this as up for grabs.

@Sjors Sjors closed this Feb 13, 2024
fanquake added a commit that referenced this pull request Jul 31, 2024
…k to closed PR

3cd24aa doc: remove obsolete mention and link to closed PR (Marnix)

Pull request description:

  Remove the mention and link as the PR (#22341) is closed and the description is wrong/outdated anyway.

ACKs for top commit:
  BrandonOdiwuor:
    ACK 3cd24aa
  tdb3:
    ACK 3cd24aa

Tree-SHA512: 5cd97029337f0cdfe81b6be9401adc4fe51ae2868f8fcadcb03828531a38380a587c32840850a924b6428f62df7d20a1e16ef7414d4078e7bb2c4e359b1fae40
@bitcoin bitcoin locked and limited conversation to collaborators Feb 12, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.