wallet: bound pending MuSig2 sessions #36641

pull fametrano wants to merge 1 commits into bitcoin:master from fametrano:wallet-musig-session-bound changing 6 files +102 −7
  1. fametrano commented at 6:02 AM on October 24, 2026: none

    The wallet keeps the secret nonce of every unfinished MuSig2 session in locked memory for as long as the wallet is loaded. A nonce is removed only when its session makes a partial signature.

    I keep at most 2048 sessions per descriptor, about 288 KiB, and drop the oldest first. A dropped nonce is never reused. Its session restarts from a PSBT without our pubnonce. A standard transaction has room for about 1700 key-path inputs. Each MuSig2 leaf with our key adds one session per input, so a PSBT with many such leaves, or several concurrent PSBTs, can reach the limit. I tested this with a unit test that starts 4096 sessions. It fails without the change and passes with it.

    This is one of several PRs from a large audit of Bitcoin Core that I did with the help of LLM tools. The audit produced its evidence all at once, which is why the PRs arrive together. I understand each change fully and will answer review questions myself.

  2. DrahtBot added the label Wallet on Oct 24, 2026
  3. DrahtBot commented at 6:02 AM on October 24, 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 NACK vicjuma

    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:

    • #36451 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36451.svg"></sub> (refactor: Use NotNull for CreateNewBlock and pimpls by maflcko)
    • #36122 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36122.svg"></sub> (BIP460: CISA for Taproot key path spends by fjahr)

    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-->

  4. DrahtBot added the label CI failed on Oct 24, 2026
  5. wallet: bound pending MuSig2 sessions
    The wallet keeps the secret nonce of every unfinished MuSig2 session in
    locked memory for as long as the wallet is loaded. A nonce is removed
    only when its session makes a partial signature.
    
    I keep at most 2048 sessions per descriptor, about 288 KiB, and drop the
    oldest first. A dropped nonce is never reused. Its session restarts from
    a PSBT without our pubnonce. A standard transaction has room for about
    1700 key-path inputs. Each MuSig2 leaf with our key adds one session per
    input, so a PSBT with many such leaves, or several concurrent PSBTs, can
    reach the limit. I tested this with a unit test that starts 4096
    sessions. It fails without the change and passes with it.
    5c6a090b9d
  6. DrahtBot removed the label CI failed on Oct 24, 2026
  7. in src/musig.h:65 in 5c6a090b9d
      61 | @@ -57,6 +62,34 @@ class MuSig2SecNonce
      62 |      bool IsValid();
      63 |  };
      64 |  
      65 | +/**
    


    vicjuma commented at 11:52 PM on October 26, 2026:

    src/script/sign.cpp:192: provider.DeleteMuSig2Session(session_id); currently lgtm tbh. I mean, on top of the current secnonces being memory-based, it is also deleted after it's done. Unless there is a practical scenario warranting this, I do not see the need

  8. in src/musig.cpp:128 in 5c6a090b9d
     124 | @@ -122,6 +125,30 @@ bool MuSig2SecNonce::IsValid()
     125 |      return m_impl->IsValid();
     126 |  }
     127 |  
     128 | +bool MuSig2SecNonces::Add(const uint256& session_id, MuSig2SecNonce&& nonce)
    


    vicjuma commented at 11:56 PM on October 26, 2026:

    Any justifications for adding these?

  9. in src/wallet/test/scriptpubkeyman_tests.cpp:79 in 5c6a090b9d
      74 | +    BOOST_REQUIRE(other_provider != nullptr);
      75 | +    BOOST_CHECK(!other_provider->GetMuSig2SecNonce(session_ids.front()).has_value());
      76 | +    BOOST_CHECK(other_provider->GetMuSig2SecNonce(session_ids.back()).has_value());
      77 | +    size_t kept{0};
      78 | +    for (const uint256& id : session_ids) kept += other_provider->GetMuSig2SecNonce(id).has_value();
      79 | +    BOOST_CHECK_LT(kept, size_t{num_sessions});
    


    vicjuma commented at 12:03 AM on October 27, 2026:

    Even 1 will pass here, which is not the intention of your PR

  10. vicjuma commented at 12:10 AM on October 27, 2026: contributor

    Concept NACK I do not see the practical implications of what you are trying to solve. If there is any justification, point it out.

Labels

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-30 09:40 UTC