#36143 descriptor: add CreateMultisigDescriptor()

ReviewabilityReviewsAgreementSize
#36143 rxbryan descriptor: add CreateMultisigDescriptor()Ready0 -1Mild116 + 85 tests
  • Avoid errors from manually assembling multisig descriptor strings during wallet setup
  • Validates cosigner keys and builds multisig descriptors safely to support multisig setup tools
  • Ready to review
  • Nothing known that would invalidate a review now
  • Unaddressed objection: adding unused C++ helper code is premature before flow validation in Python (Sjors)
  • The author answered proposing callers including createmultisig, awaiting reviewer response (Sjors)
  • Concept approval because the GUI needs this helper and createmultisig should be modernized (achow101)
  • 116 lines added or modified outside tests
  • 85 lines added or modified in tests
  • 0 lines removed in total
  • 3 files, 2 commits
Wallet#54 of 92
P3 · new feature
  • P3 because safe descriptor creation avoids setup errors but lacks direct end-user callers so far
  • Unblocks multisig wizard tooling and planned modernization of createmultisig
  • Ranking pass: Kept adjacent to the other #35645 wizard prerequisites.
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

Adds CreateMultisigDescriptor() to script/descriptor to assemble and validate ranged, multipath multisig descriptors with checksums from a list of cosigner xpubs. The function constructs P2WSH (wsh(sortedmulti(...))) and P2TR (tr(musig(...), sortedmulti_a(...))) descriptors. It enforces setup constraints including bare account xpubs with origin info, duplicate key rejection, threshold bounds, and exclusion of private keys.

Problem: Multisig setup flows have had to assemble descriptor strings manually, risking errors from unvalidated string interpolation, duplicate cosigners, invalid thresholds, or improper derivation paths.

Evidence of importance:

  • PR description notes multisig setup flows need to assemble descriptors without hand-crafting strings: 'today means bash interpolation with no validation of key forms, duplicates, or threshold'
  • Author references the multisig wizard backend tracking issue #35645 and GUI/contrib PR #36325

Scope: The function introduces Taproot descriptor creation using MuSig2 key path aggregation (musig(...)) combined with a sortedmulti_a script path.

Risk of a mistake: medium (wallet, tests). A flaw in descriptor generation or key path aggregation logic could produce invalid or unspendable multisig wallet policies, potentially leading to fund loss for users of downstream multisig setup tooling.

Changed since the previous assessment: Switched the Taproot descriptor key path from a NUMS point to an aggregated MuSig2 key expression (musig(...)/<0;1>/*).

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • reviewer: Sjors to respond to author and achow101's replies regarding callers and delegating createmultisig 2026-10-06

Agreement

Mild

objection that needs a change was answered, no reply from the objector (Sjors (NACK): adding unused C++ helper code is premature and risks a large commit stack before the setup flow is validated via a flexi)

Thread notes: Added author reply c:6016756650 proposing createmultisig delegate to CreateMultisigDescriptor(). The PR remains waiting on reviewer response.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
Sjors (member)objection, approachadding unused C++ helper code is premature and risks a large commit stack before the setup flow is validated via a flexible Python utilityanswered · author replied explaining flow validation via Python wizard #36325, real consumers, and delegating createmultisig; achow101 also supported the C++ utilitychangedyes2026-09-02: 'Concept NACK, unless this is part of a larger end-to-end implementation (with some buy-in), like a GUI or RPC that actually uses this new method. But I also think that's premature.'
Status from: 2026-09-26: rxbryan: 'Following the Python wizard #36325, which exercises the actual setup flow, the contract for `createMultisigDescriptor()`'

Support:

  • achow101 (member) (2026-09-29) [read]: GUI needs a utility function like this one to construct descriptors for import, and createmultisig RPC should be modernized

Participants:

  • Sjors (member, objection, 2 statements 2026-09-02 to 2026-09-03): Concept NACK on adding C++ helper without a caller or end-to-end implementation
  • achow101 (member, support, 1 statements 2026-09-29 to 2026-09-29): supports C++ utility function for GUI descriptor construction and modernizing createmultisig RPC

Dependencies

Enables:

Files

85 lines under test/bench/ci.

  • src/script/descriptor.cpp +103/-0
  • src/test/descriptor_tests.cpp +85/-0
  • src/script/descriptor.h +13/-0

Card

The short text the ranking pass compares across PRs.

Adds CreateMultisigDescriptor() to validate cosigner keys and construct ranged multipath multisig descriptors with checksums for P2WSH and Taproot (MuSig2 key path with sortedmulti_a script path). Multisig setup workflows currently lack a backend helper to safely assemble descriptors, resorting to ad-hoc string formatting that risks unvalidated thresholds, duplicate keys, or malformed derivation paths. This change provides validated descriptor construction for the multisig wizard tracked in issue #35645 and PR #36325.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-08T01:17, confidence high, input hash 1e66d51c17efda37
thread read through 2026-10-06 (7 statements), head 589f3fe6b5
labels: Descriptors

Categories

Wallet

P3 · new feature (ranking pass: Kept adjacent to the other #35645 wizard prerequisites.)

Adds helper logic to safely construct ranged multipath multisig descriptors without string interpolation errors. The PR addresses setup risks where callers had to manually assemble descriptors without validation, paving the way for multisig wizard tooling (#35645, #36325), but is not yet wired to end-user wallet flows directly.

Membership: Wallet covers descriptor management; this PR adds descriptor creation logic in src/script/descriptor.{h,cpp} for multisig setup flows

Factors: security/stability 1, bug 0, performance 0, user value 1, leverage 2