Duplicate-key sanity for multipath Miniscript descriptors only checks branch 0, so nonzero-branch key collisions are accepted #35629

issue Nuhiat-Arefin opened this issue on July 1, 2026
  1. Nuhiat-Arefin commented at 11:42 AM on July 1, 2026: none

    Is there an existing issue for this?

    • I have searched the existing issues

    Current behaviour

    Current Bitcoin Core accepts a multipath Miniscript descriptor when duplicate public keys appear only in a nonzero multipath branch, even though the identical concrete branch descriptor is rejected when written directly.

    Verified locally on Core commit 400aa68b4aa8de52c1a8bf543dd195cd1b2b1f32.

    In the repro below:

    branch 0 is sane: /0 vs /2
    branch 1 collides: /1 vs /1
    

    The multipath descriptor is accepted and expanded into 2 concrete descriptors, but the explicit branch-1 descriptor is rejected with:

    ... is not sane: contains duplicate public keys
    

    From local source review, this appears to happen because duplicate-key sanity is evaluated once on the template node before multipath expansion, and the key comparison samples only branch 0 / child 0.

    This looks like a low-severity sanity-check completeness gap, not a validity or consensus issue. Duplicate keys are rejected under !IsSane(), not !IsValid().

    Expected behaviour

    If any concrete multipath branch is not sane due to duplicate public keys, the textual descriptor should be rejected. At minimum, duplicate-key sanity should be checked across the finite multipath dimension for all materialized branches, rather than only for branch 0. This does not require enumerating unbounded ranged children; it only requires checking the finite multipath <...> dimension that Core already expands.

    Steps to reproduce

    Reproduction

    Build Bitcoin Core from source at commit 400aa68b4aa8de52c1a8bf543dd195cd1b2b1f32.

    Call the descriptor parser on this multipath descriptor:

    wsh(or_i(pk(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/<0;1>),pk(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/<2;1>)))
    

    Observed locally:

    parse succeeds
    the descriptor expands into 2 concrete descriptors
    

    Call the same parser on the explicit branch-1 expansion:

    wsh(or_i(pk(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/1),pk(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/1)))
    

    Observed locally:

    parse fails with:
    ... is not sane: contains duplicate public keys
    

    Optional control: the explicit branch-0 form is accepted as expected:

    wsh(or_i(pk(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0),pk(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/2)))
    

    This same pattern also reproduces under tr(...).

    Relevant log output

    No response

    How did you obtain Bitcoin Core

    Compiled from source

    What version of Bitcoin Core are you using?

    Built from source at commit 400aa68b4aa8de52c1a8bf543dd195cd1b2b1f32

    Operating system and version

    MacOS 26.5.1

    Machine specifications

    No response

  2. willcl-ark added the label Descriptors on Jul 8, 2026
Contributors

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-07-09 06:47 UTC