bench: add script verification benchmark for P2TR key path spends #34472

pull theStack wants to merge 2 commits into bitcoin:master from theStack:202602-bench_add_script_verify_p2tr_keyspend changing 1 files +45 −31
  1. theStack commented at 1:11 am on February 2, 2026: contributor

    We currently benchmark Schnorr signature verification only in the context of block validation (ConectBlock* benchmarks), but not individually for single inputs [1]. This PR adds a script verification benchmark for P2TR key path spends accordingly, by generalizing the already existing one for P2WPKH spends.

    This should make it easier to quantify potential performance improvements like e.g. https://github.com/bitcoin-core/secp256k1/pull/1777, which allows to plug in our HW-optimized SHA256 functions to be used in libsecp256k1 (see the linked example commit https://github.com/furszy/bitcoin-core/commit/f68bef06d95a589859f98fc898dd80ab2e35eb39). IIRC from last CoreDev, the main speedup from this is expected for ECDSA signing though (as this involves quite a lot of hashing), but it still makes sense to have verification benchmarks available for both signature types as well.

    (An alternative way could be to add benchmarks for the signing/verifying member functions CKey::Sign{,Schnorr}, CPubKey::Verify and XOnlyPubKey::VerifySchnorr directly, if we prefer that.)

    [1] this claim can be practically verified by putting an assert(false); into XOnlyPubKey::VerifySchnorr: the three benchmarks crashing are ConnectBlockAllSchnorr, ConnectBlockMixedEcdsaSchnorr and SignTransactionSchnorr (as signing includes verification)

  2. DrahtBot added the label Tests on Feb 2, 2026
  3. DrahtBot commented at 1:11 am on February 2, 2026: contributor

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

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK furszy, sedited
    Concept ACK l0rinc, w0xlt

    If your review is incorrectly listed, please copy-paste <!–meta-tag:bot-skip–> into the comment that the bot should ignore.

  4. in src/bench/verify_script.cpp:33 in a99f56715c
    42-    CHash160().Write(pubkey).Finalize(pubkeyHash);
    43+    // Create key material needed for output script creation / signing
    44+    FlatSigningProvider keystore;
    45+    CPubKey pubkey;
    46+    {
    47+        CKey privkey = GenerateRandomKey();
    


    furszy commented at 3:26 am on February 2, 2026:
    why random? the fixed deterministic sk for the benchmark seems more appropriate. And it is also faster to setup.

    theStack commented at 2:19 pm on February 3, 2026:
    Thanks, switched back to a deterministic key using Uint256::ONE.
  5. in src/bench/verify_script.cpp:49 in 73f5a454b8 outdated
    47+    CScript scriptPubKey;
    48+    switch (script_type) {
    49+    case ScriptType::P2WPKH: scriptPubKey = GetScriptForDestination(WitnessV0KeyHash(pubkey)); break;
    50+    case ScriptType::P2TR:   scriptPubKey = GetScriptForDestination(WitnessV1Taproot(XOnlyPubKey{pubkey})); break;
    51+    default: assert(false);
    52+    }
    


    furszy commented at 3:30 am on February 2, 2026:

    nit: To make it slightly more readable:

    0CTxDestination dest;
    1switch (script_type) {
    2    case ScriptType::P2WPKH: dest = WitnessV0KeyHash(pubkey); break;
    3    case ScriptType::P2TR:   dest = WitnessV1Taproot(XOnlyPubKey{pubkey}); break;
    4    default: assert(false);
    5}
    6scriptPubKey = GetScriptForDestination(dest);
    

    Also, I’m surprised we don’t have any visitor class or utility function that receives the script type + data and retrieves the destination or the script. It seems something we should be doing in several places.


    theStack commented at 2:25 pm on February 3, 2026:

    Applied your suggestion, I agree that this is more readable.

    Also, I’m surprised we don’t have any visitor class or utility function that receives the script type + data and retrieves the destination or the script. It seems something we should be doing in several places.

    Note that the ScriptType enum is only defined in this file, for the sake of differentiating between different scenarios to benchmark.

  6. l0rinc commented at 10:56 am on February 2, 2026: contributor
    Concept ACK, I will review this in more detail later, thanks for taking care of it
  7. w0xlt commented at 4:41 am on February 3, 2026: contributor
    Concept ACK
  8. bench: simplify script verification benchmark, generalize signing
    Simplify the benchmark with the following changes:
    - Set the deterministic private key using uint256::ONE,
      put it in a `FlatSigningProvider` instance for easier signing
    - Use `GetScriptForDestination` for creating the output script
    - Use `SignTransaction` to sign, instead of doing it manually
      (also removes the need to caclulate the public key hash manually)
    - Pass standard script verification flags instead of combining them manually
    
    These steps, in particular the generalized signing, prepare the
    benchmarking extension for a different script type (P2TR key-path) in
    the next commit.
    dd93362a1d
  9. theStack force-pushed on Feb 3, 2026
  10. theStack commented at 2:26 pm on February 3, 2026: contributor
    Force-pushed tackling @furszy’s suggestions (https://github.com/bitcoin/bitcoin/pull/34472#discussion_r2752385238, #34472 (review)), thanks for the review!
  11. in src/bench/verify_script.cpp:39 in dd93362a1d
    48+        privkey.Set(uint256::ONE.begin(), uint256::ONE.end(), /*fCompressedIn=*/true);
    49+        pubkey = privkey.GetPubKey();
    50+        CKeyID key_id = pubkey.GetID();
    51+        keystore.keys.emplace(key_id, privkey);
    52+        keystore.pubkeys.emplace(key_id, pubkey);
    53+    }
    


    furszy commented at 8:19 pm on February 5, 2026:

    nano nit:

    Could remove the brackets.

    0// Create deterministic key material needed for output script creation / signing
    1CKey privkey;
    2privkey.Set(uint256::ONE.begin(), uint256::ONE.end(), /*fCompressedIn=*/true);
    3CPubKey pubkey = privkey.GetPubKey();
    4CKeyID key_id = pubkey.GetID();
    5    
    6FlatSigningProvider keystore;
    7keystore.keys.emplace(key_id, privkey);
    8keystore.pubkeys.emplace(key_id, pubkey);
    
  12. in src/bench/verify_script.cpp:66 in f2ffd883f6
    65         bool complete = SignTransaction(txSpend, &keystore, coins, SIGHASH_ALL, input_errors);
    66         assert(complete);
    67+
    68+        std::vector<CTxOut> spent_outputs;
    69+        spent_outputs.emplace_back(txCredit.vout[0]);
    70+        txdata.Init(txSpend, std::move(spent_outputs));
    


    furszy commented at 8:22 pm on February 5, 2026:

    nit: Could write these three lines in one

    0txdata.Init(txSpend, /*spent_outputs=*/{txCredit.vout[0]});
    
  13. furszy commented at 8:22 pm on February 5, 2026: member
    utACK f2ffd883f6c6bf8fd64777a954918eeec971cb65
  14. DrahtBot requested review from l0rinc on Feb 5, 2026
  15. sedited approved
  16. sedited commented at 11:17 am on February 9, 2026: contributor

    ACK f2ffd883f6c6bf8fd64777a954918eeec971cb65

    I’d re-ACK quickly if you want to address the remaining nits.

  17. theStack force-pushed on Feb 9, 2026
  18. bench: add script verification benchmark for P2TR key path spends d339884f1d
  19. theStack force-pushed on Feb 9, 2026
  20. DrahtBot added the label CI failed on Feb 9, 2026
  21. theStack commented at 12:57 pm on February 9, 2026: contributor
  22. DrahtBot removed the label CI failed on Feb 9, 2026
  23. furszy commented at 3:14 pm on February 9, 2026: member
    ACK d339884f1dfac3749c6214ae896b4354cf9ee28e
  24. DrahtBot requested review from sedited on Feb 9, 2026
  25. sedited approved
  26. sedited commented at 3:52 pm on February 9, 2026: contributor
    Re-ACK d339884f1dfac3749c6214ae896b4354cf9ee28e

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-02-22 18:12 UTC

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