psbt: avoid duplicate global xpub keys when merging #35665

pull thomasbuilds wants to merge 3 commits into bitcoin:master from thomasbuilds:fix-psbt-duplicate-global-xpubs changing 4 files +46 −18
  1. thomasbuilds commented at 8:43 AM on July 6, 2026: contributor

    Global xpubs are stored in a map of key origin to set of xpubs, while the serialization writes one record per xpub, keyed by the xpub. Merge unions the map origin-by-origin, so when the combined PSBTs provide different key origins for the same xpub, the result serializes the same PSBT_GLOBAL_XPUB key twice. BIP 174 declares PSBTs with duplicate keys invalid and the deserializer rejects them, so combinepsbt returns a PSBT that no RPC can parse again. This affects all releases since the merge loop was added in #17034 (v23.0).

    <details><summary>Reproduction on master</summary>

    The PSBTs share the unsigned transaction and xpub, and differ only in the master fingerprint of the global xpub record (00000000 vs 11111111):

    $ A=cHNidP8BADwCAAAAAaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqAAAAAAD/////AQAAAAAAAAAAAAAAAABPAQQ1h88AAAAAAAAAAACHPf+BwC9SViP9H+UWfqw6VaBJ3j0xS7Qu4if/7TfVCAM5o2ATMBWX2u9B++WToCzFE9C1VSfsLfEFDi6P9JyFwgQAAAAAAAAA
    $ B=cHNidP8BADwCAAAAAaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqAAAAAAD/////AQAAAAAAAAAAAAAAAABPAQQ1h88AAAAAAAAAAACHPf+BwC9SViP9H+UWfqw6VaBJ3j0xS7Qu4if/7TfVCAM5o2ATMBWX2u9B++WToCzFE9C1VSfsLfEFDi6P9JyFwgQRERERAAAA
    $ bitcoin-cli -regtest decodepsbt "$(bitcoin-cli -regtest combinepsbt "[\"$A\",\"$B\"]")"
    error code: -22
    error message:
    TX decode failed Duplicate Key, global key "01043587cf00...9c85c2" already provided: iostream error
    

    </details>

    Deduplicate by xpub when merging, keeping the origin that is already present: BIP 174 lets the Combiner "pick arbitrarily when conflicts occur", and conflicting unknown and proprietary records are already resolved the same way. The logic is shared between combinepsbt and joinpsbts through a new MergeGlobalXPubs helper. The second commit adds a test that fails on master with the error above, and the last commit removes the global_xpubs tracking set in Unserialize, write-only since the generic duplicate key check introduced in #21283 (1e2d146b47) replaced the explicit one.

    Note: the xpub loop in joinpsbts currently has no observable effect, since the collected xpubs never reach the returned PSBT. My #35516 fixes that, so this PR should land first: on its own, #35516 would make the same duplicate key issue reachable through joinpsbts, while with the shared helper in place it never becomes reachable. I will rebase #35516 on top afterwards.

  2. psbt: avoid duplicate global xpub keys when merging
    The global xpubs are stored in a map of key origin to set of xpubs,
    while the serialization writes one record per xpub, keyed by the xpub.
    Merging two PSBTs origin-by-origin can store the same xpub under two
    origins, which serializes as a PSBT with duplicate keys that the
    deserializer (and BIP 174) reject. Notably, combinepsbt returned a
    PSBT that no RPC could parse again when the combined PSBTs provide
    different key origins for the same xpub.
    
    Deduplicate by xpub when merging, keeping the origin that is already
    present, and share the logic between combinepsbt and joinpsbts.
    7c632c0e2a
  3. test: check combinepsbt with conflicting global xpub origins 3b7051c7e3
  4. psbt: remove write-only global xpub tracking set
    The explicit duplicate global xpub check was replaced by the generic
    duplicate key check in 1e2d146b47, leaving the set unused.
    6d387af562
  5. DrahtBot added the label PSBT on Jul 6, 2026
  6. DrahtBot commented at 8:43 AM on July 6, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35665.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->


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

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