descriptor: Reconstruct a multipath descriptor from its expansion #36443

pull achow101 wants to merge 12 commits into bitcoin:master from achow101:multipath-reconstruction changing 39 files +1231 −709
  1. achow101 commented at 10:16 PM on October 5, 2026: member

    #36442 allows multipath descriptors to be represented in a single Descriptor object. GetMultipathExpansion returns the multiple descriptors represented by a multipath descriptor. This expansion is reversible - given the expansion in the order of the multipath elements, it is possible to determine what the original multipath descriptor was. This PR adds ReconstructMultipath to produce a new Descriptor representing the multipath descriptor that produced the expansion.

    Depends on #36442

  2. DrahtBot added the label Descriptors on Oct 5, 2026
  3. DrahtBot commented at 10:16 PM on October 5, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--006a51241073e994b41acfe9ec718e94-->

    External sites

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    Concept ACK w0xlt

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #36442 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36442.svg"></sub> (descriptor: Represent multipath descriptors in a single Descriptor object by achow101)
    • #36122 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36122.svg"></sub> (BIP460: CISA for Taproot key path spends by fjahr)
    • #36070 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36070.svg"></sub> (wallet: Add deriveHDKey interface by PraneethGunas)
    • #35377 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/35377.svg"></sub> (wallet: Allow importing of descriptors without private keys when the wallet has the private keys by achow101)
    • #35170 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/35170.svg"></sub> (test: Better test coverage for ParseHDKeypath() by optout21)
    • #34909 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/34909.svg"></sub> (wallet, refactor: modularise wallet by extracting out legacy wallet migration by rkrux)

    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.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

    LLM Linter (✨ experimental)

    Possible typos and grammar issues:

    • src/util/bip32.h: for a give multipath position → for a given multipath position [“give” is a typo]
    • src/test/descriptor_tests.cpp: Failed reconstrcted to private string → Failed reconstructed to private string [“reconstrcted” is misspelled]

    Possible places where named args for integral literals may be used (e.g. func(x, /*named_arg=*/0) in C++, and func(x, named_arg=0) in Python):

    • src/scriptpubkeyman.cpp: Parse(desc_str, provider, error, false) (combo descriptor)
    • src/scriptpubkeyman.cpp: Parse(desc_str, provider, error, false) (chain descriptor)
    • src/scriptpubkeyman.cpp: WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0)
    • src/scriptpubkeyman.cpp: WalletDescriptor w_desc(std::move(desc), 0, 0, chain_counter, 0)
    • src/wallet/rpc/spend.cpp: Parse(desc_str, desc_out, error, true)
    • src/wallet/test/fuzz/scriptpubkeyman.cpp: Parse(desc_str.value(), keys, error, false)
    • src/wallet/test/util.cpp: Parse(desc_str, keys, error, false)
    • src/wallet/walletutil.cpp: Parse(desc_str, keys, error, false)
    • src/wallet/walletutil.cpp: WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0)

    <sup>2026-10-07 18:03:03</sup>

  4. achow101 marked this as a draft on Oct 5, 2026
  5. achow101 force-pushed on Oct 5, 2026
  6. DrahtBot added the label CI failed on Oct 5, 2026
  7. DrahtBot commented at 10:36 PM on October 5, 2026: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task macOS-cross to arm64: https://github.com/bitcoin/bitcoin/actions/runs/37381386585/job/112003972868</sub> <sub>LLM reason (✨ experimental): CI failed to compile walletload_tests.cpp: Parse() returns a std::unique_ptr<Descriptor>, but the code assigns it to a vector of those pointers.</sub>

    <details><summary>Hints</summary>

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

    </details>

  8. DrahtBot added the label Needs rebase on Oct 7, 2026
  9. util: Make KeyPathElement class with private members 2ff1009dbe
  10. util: Change all key path operations to operate with std::vector<KeyPathElement> 9353f7986c
  11. util: Make KeyPath a subclass of std::vector and not only a typedef
    We will want to have member functions on KeyPath later, so make it a
    class now.
    611b2b9f16
  12. util: Store hardened character in KeyPathElement 192c38bb11
  13. util: Make KeyPathElement handle multipaths
    Moves all of the multipath parsing into ParseHDKeypath, and let
    KeyPathElement be a multipath element.
    2f7d95b319
  14. descriptor: Get the multipath expansion from a multipath descriptor 010a986ad3
  15. descriptor: Produce multipath descriptor in ParseScript
    Internally, descriptor parsing will produce multipath descriptor objects
    rather than std::vector<DescriptorImpl>. This single multipath
    descriptor becomes std::vector<Descriptor> within Parse. Future commits
    will return the single multipath descriptor object for all descriptor parsing.
    fa1b3002b4
  16. descriptor: Return multipath descriptor from Parse
    Instead of a std::vector<std::unique_ptr<Descriptor>>, Parse can return
    a single std::unique_ptr<Descriptor> that contains the multipath
    information if the descriptor was multipath. Callers that
    require the multipath expansion use GetMultipathExpansion() to get the
    expanded descriptors.
    b7980165b2
  17. descriptor: Implement multipath reconstruction 5c0b1e77a6
  18. test: Add multipath reconstruction round trip checks e2d78b3edd
  19. fuzz: Check multipath descriptor reconstruction 8aba47abf1
  20. test: Invalid multipath reconstruction tests 62e70eb6f0
  21. achow101 force-pushed on Oct 7, 2026
  22. DrahtBot removed the label Needs rebase on Oct 7, 2026
  23. w0xlt commented at 6:06 PM on October 8, 2026: contributor

    Concept ACK


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-10-11 11:51 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me