#36444 wallet: Store information about created and imported multipath descriptors
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #36444 wallet: Store information about created and imported multipath descriptors | Needs rebase | 0 | Positive | 1,047 + 389 tests | |||
|
|
|
| ||||
Reviewability: ReadyStalePaused Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs. Size: lines added or modified outside tests, then in tests; greener = smaller. | |||||||
Goal
Stores multipath relationship metadata in the wallet for both imported and automatically generated descriptors. Updates `WalletDescriptor` to store the sibling `ScriptPubKeyMan` IDs resulting from an expansion, allowing the wallet to reconstruct original multipath descriptors using `ReconstructMultipath`. Exposes the reconstructed string via an optional `multipath_descriptor` field in `listdescriptors` and includes it in `exportwatchonly` outputs.
Problem: When multipath descriptors are imported into a wallet, they are expanded and stored as independent descriptors without preserving their relationship. Users coordinating with hardware signers that require policy registration cannot retrieve or re-verify the original multipath descriptor through RPC, and automatically generated wallet descriptors have no multipath association.
Evidence of importance:
- Author notes: 'This is useful for working with hardware wallets that require policy registration, particularly those that require resending the descriptor that was registered.'
- Author notes: 'The wallet does not store any information about multipath descriptors. When a multipath descriptor is imported, it is first expanded, then the expansion descriptors are imported into the wallet.'
Scope: Includes commits from base PRs #36442 (refactoring `Parse` and BIP32 key paths to represent multipaths in a single `Descriptor` object) and #36443 (multipath reconstruction), making the diff substantially larger than just wallet storage changes.
Risk of a mistake: medium (wallet, wallet_storage, rpc_api). Modifies descriptor parsing and serialization/storage within WalletDescriptor and ScriptPubKeyMan, where bugs could corrupt wallet records or break descriptor exports.
Reviewability
Ready · Needs rebase
Conflicts with master; review the logic now, the rebase is mechanical.
Waiting on (from the thread read):
- nothing
Agreement
Positive
support without stated reasons, no open objection (w0xlt)
Thread notes: Initial record. w0xlt provided a bare Concept ACK. / Initial record. w0xlt posted a Concept ACK with no rationale or code discussion.
Objections, suggestions, and questions: none recorded.
Support:
- w0xlt (contributor) (Concept ACK, 2026-10-08): (no reason given) [not substantive]
Participants:
- w0xlt (contributor, support, 1 statements 2026-10-08 to 2026-10-08): Concept ACK
Dependencies
Files
565 lines under test/bench/ci.
- src/script/descriptor.cpp +517/-408
- src/test/descriptor_tests.cpp +194/-37
- src/util/bip32.cpp +149/-27
- src/test/bip32_tests.cpp +77/-79
- src/util/bip32.h +113/-10
- src/wallet/scriptpubkeyman.cpp +63/-11
- src/wallet/wallet.cpp +40/-18
- test/functional/wallet_listdescriptors.py +40/-10
- src/wallet/walletutil.h +30/-10
- src/wallet/export.cpp +30/-5
- src/wallet/imports.cpp +23/-12
- src/rpc/output_script.cpp +14/-19
- src/test/fuzz/descriptor_parse.cpp +20/-2
- src/wallet/walletdb.cpp +12/-10
- test/functional/wallet_importdescriptors.py +16/-4
- src/rpc/util.cpp +8/-8
- src/test/fuzz/parse_hd_keypath.cpp +8/-6
- src/script/descriptor.h +9/-1
- src/test/psbt_tests.cpp +5/-5
- src/wallet/test/util.cpp +4/-6
- src/wallet/rpc/spend.cpp +4/-4
- src/wallet/test/fuzz/scriptpubkeyman.cpp +4/-4
- src/wallet/test/wallet_tests.cpp +3/-5
- src/wallet/test/walletload_tests.cpp +5/-3
- src/key.cpp +4/-3
- src/qt/test/wallettests.cpp +3/-4
- src/rpc/mining.cpp +3/-4
- src/script/sign.cpp +3/-3
- src/wallet/test/psbt_wallet_tests.cpp +2/-3
- src/bench/descriptors.cpp +2/-2
- src/bench/wallet_encrypt.cpp +2/-2
- src/bench/wallet_ismine.cpp +2/-2
- src/wallet/rpc/backup.cpp +4/-0
- src/wallet/rpc/wallet.cpp +2/-2
- src/wallet/scriptpubkeyman.h +4/-0
- src/wallet/wallet.h +2/-2
- src/wallet/walletutil.cpp +2/-2
- src/key.h +2/-1
- src/rpc/util.h +2/-1
- src/script/keyorigin.h +2/-1
- src/wallet/export.h +3/-0
- src/psbt.h +1/-1
- src/test/fuzz/util/wallet.h +1/-1
- src/wallet/rpc/addresses.cpp +1/-1
- test/functional/rpc_getdescriptorinfo.py +1/-1
Card
The short text the ranking pass compares across PRs.
This pull request stores multipath descriptor relationships in the wallet database and exposes the reconstructed multipath descriptor in listdescriptors and watch-only exports. Currently, Bitcoin Core expands multipath descriptors on import and discards their relationship, preventing users from retrieving the registered multipath descriptor needed for hardware signer policy verification. By saving relative ScriptPubKeyMan IDs in WalletDescriptor, the wallet can reconstruct and report the original multipath strings. It depends on #36442 and #36443.
Data
thread read through 2026-10-08 (1 statements), head a49e42b8bb
labels: Wallet, Needs rebase, CI failed · draft
Categories
Wallet
P2 · new feature
Preserves multipath descriptor relationships upon import and creation to enable hardware wallet policy registration workflows. Author notes that 'This is useful for working with hardware wallets that require policy registration, particularly those that require resending the descriptor that was registered.'
Membership: Carries the Wallet label, updates WalletDescriptor storage in ScriptPubKeyMan, and exposes reconstructed multipaths via listdescriptors and exportwatchonly.
Factors: security/stability 0, bug 0, performance 0, user value 2, leverage 1