bench: improve stateful benchmark reproducibility #35124

pull l0rinc wants to merge 4 commits into bitcoin:master from l0rinc:l0rinc/reset-stateful-benchmarks changing 4 files +22 −13
  1. l0rinc commented at 2:48 PM on April 20, 2026: contributor

    Context

    Found while reviewing #35018, which led to a few additional benchmark fixes.

    Problem

    The CHACHA20 and FSCHACHA20POLY1305 benchmarks reused a single cipher object across timed calls. That advanced the stream state across samples, so later samples no longer measured work from the same starting point. A few other benchmarks could benefit from the same iteration-stability treatment, but that is outside the scope of this PR.

    While investigating this, it also became clear that MempoolCheckEphemeralSpends only populated vin[0] in its loop, and that WalletBalanceMine duplicated WalletBalanceClean. The same review also showed that nanobench setup() can be misused as though it runs once per timed call.

    Fix

    Rebuild the ChaCha ciphers in setup() and pair that setup with epochIterations(1) so each timed call starts from the same state. Add a nanobench assertion that setup() is only used with epochIterations(1). Also fix the ephemeral spend benchmark inputs and remove the duplicate wallet balance benchmark.

  2. bench: drop duplicate balance benchmark
    `WalletBalanceMine` duplicated `WalletBalanceClean` exactly.
    Remove the duplicate registration so the balance benchmark list stays distinct.
    95b1366d57
  3. bench: fix ephemeral spend inputs
    `MempoolCheckEphemeralSpends` wrote every prevout to `tx2.vin[0]` instead of `tx2.vin[i]`.
    That left only one child input pointing at the parent transaction, while the remaining inputs kept default prevouts.
    
    Write each prevout to `vin[i]` instead.
    Add an assertion that the last child input spends the last parent output.
    37296a3347
  4. bench: assert `setup()` is paired with `epochIterations(1)`
    `setup()` in nanobench runs once per epoch, not once per timed call.
    If an epoch executes the benchmark body multiple times, `setup()` can silently leave later iterations with different preconditions.
    
    Fail fast when `setup()` is combined with anything other than `epochIterations(1)`.
    d6f82e6968
  5. bench: reset ChaCha cipher state
    `CHACHA20` and `FSCHACHA20POLY1305` kept one cipher object alive across timed calls.
    That advanced the stream state across samples, and `FSChaCha20Poly1305` could cross a rekey boundary.
    
    Rebuild the cipher in `setup()` for each timed call so each sample starts from the same state.
    b333754597
  6. DrahtBot added the label Tests on Apr 20, 2026
  7. DrahtBot commented at 2:49 PM on April 20, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK achow101

    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.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  8. achow101 commented at 7:35 PM on April 20, 2026: member

    ACK b33375459764a3cc716723d596164299dd8c6e22


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-04-21 09:12 UTC

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