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 +49 −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. bench: simplify script verification benchmark, generalize signing
    Simplify the benchmark with the following changes:
    - Generate an actual random key instead of hardcoding a fixed 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.
    a99f56715c
  3. bench: add script verification benchmark for P2TR key path spends 73f5a454b8
  4. DrahtBot added the label Tests on Feb 2, 2026
  5. 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. A summary of reviews will appear here.

    LLM Linter (✨ experimental)

    Possible places where named args for integral literals may be used (e.g. func(x, /*named_arg=*/0) in C++, and func(x, named_arg=0) in Python):

    • Coin(txCredit.vout[0], /nHeightIn=/100, /fCoinBaseIn=/false) in src/bench/verify_script.cpp

    2026-02-02 01:11:37

  6. 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.
  7. in src/bench/verify_script.cpp:50 in 73f5a454b8
    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.


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-02 06:13 UTC

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