Skip to content

bench: fix stateful benchmark setup and inputs#130

Closed
l0rinc wants to merge 4 commits into
masterfrom
l0rinc/reset-stateful-benchmarks
Closed

bench: fix stateful benchmark setup and inputs#130
l0rinc wants to merge 4 commits into
masterfrom
l0rinc/reset-stateful-benchmarks

Conversation

@l0rinc

@l0rinc l0rinc commented Apr 12, 2026

Copy link
Copy Markdown
Owner

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.

Context

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

@l0rinc l0rinc force-pushed the l0rinc/reset-stateful-benchmarks branch 6 times, most recently from 4d97ae8 to e5befb4 Compare April 19, 2026 16:25
@l0rinc l0rinc changed the title bench: reset stateful benchmarks between timed calls bench: fix stateful benchmark setup and inputs Apr 20, 2026
@l0rinc l0rinc force-pushed the l0rinc/reset-stateful-benchmarks branch from e5befb4 to 228ab96 Compare April 20, 2026 14:14
l0rinc added 3 commits April 20, 2026 16:15
`WalletBalanceMine` duplicated `WalletBalanceClean` exactly.
Remove the duplicate registration so the balance benchmark list stays distinct.
`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.
`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)`.
@l0rinc l0rinc force-pushed the l0rinc/reset-stateful-benchmarks branch 2 times, most recently from 3ae3920 to e82db0b Compare April 20, 2026 14:36
`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.
@l0rinc l0rinc force-pushed the l0rinc/reset-stateful-benchmarks branch from e82db0b to b333754 Compare April 20, 2026 14:41
@l0rinc l0rinc closed this Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant