#34969 fuzz: several improvements to scriptpubkeyman harness

full analysis

https://github.com/bitcoin/bitcoin/pull/34969 · brunoerg · +71/-86 in 3 files, 7 commits · labels: Fuzzing

Goal

  • Speed up fuzz testing for scriptpubkeyman so automated testing can find bugs faster
  • Fix a harness bug that prematurely aborted test iterations when descriptor updates failed

This pull request optimizes the `scriptpubkeyman` fuzz harness and adds a `num_coins` limit parameter to the `ConsumeCoins` fuzz utility. It removes redundant `IsMine` calls, moves costly operations such as `GetNewDestination` and `GetDescriptorString` out of inner loops, reduces the coin generation ceiling from 10,000 to 5 for this harness, and fixes an early return that aborted execution when descriptor updates failed.

Problem: The `scriptpubkeyman` fuzz target ran very slowly under libfuzzer sanitizers (under 40 exec/s on standard development hardware) due to repetitive expensive descriptor string conversions and massive coin generations in loops. Additionally, an early return bug prematurely terminated executions when failing to update wallet descriptors, reducing fuzz exploration depth.

Category: Test infrastructure (#11 of 45)

P3 · speedup

  • P3 because it speeds up a single fuzz harness up to threefold under sanitizers
  • Deeper fuzz exploration benefits overall fuzzing coverage for wallet descriptors

Substantially improves fuzzing execution throughput for the scriptpubkeyman target from under 40 exec/s to between 150 and 385 exec/s under libfuzzer sanitizers. It also fixes a harness bug where descriptor update failures aborted fuzz iterations early instead of continuing.

Membership: Modifies the scriptpubkeyman fuzz target and fuzz test helper ConsumeCoins in src/test/fuzz/util.

Factors: security/stability 1, bug 1, performance 2, user value 0, leverage 1

Reviewability: Ready

  • Ready to review
  • CI is passing and the author addressed all inline reviewer comments

The PR has passing CI, is up to date, and the author addressed all inline reviewer feedback in the latest push.

Author status: active

Resolved concerns:

  • maflcko and pablomartin4btc noted that removing IsMine assertions weakened verification of the IsMine/GetScriptPubKeys bidirectional invariant; brunoerg restored the full bidirectional check efficiently outside the loop.

Agreement: Strong

  • Strong support for the performance gains and harness bug fix
  • Concept approval citing the bug fix and hot-path optimizations (pablomartin4btc)
  • Verified by benchmarking substantial fuzzing speedup under sanitizers (andrewtoth)
  • Verified test corpus behavior and execution counts (ekzyis)
  • Concerns about weakened verification assertions were resolved in updates (maflcko)

Strong support with Concept ACK from pablomartin4btc; prior invariant concerns resolved.

Reviewers verified that the performance gains are real under sanitizers, and pablomartin4btc provided a Concept ACK noting the bug fix and performance improvements. All assertion concerns were resolved.

  • pablomartin4btc gave Concept ACK: 'A real improvement — the early return bug fix and moving expensive ops out of the hot path are the right calls.'
  • andrewtoth benchmarked the branch with libfuzzer presets and confirmed speedup from ~39-128 exec/s to ~128-385 exec/s.
  • ekzyis verified corpus behavior and execution counts.
  • maflcko asked for clarification on IsMine assertion removal, which was addressed in a subsequent commit.

Review verdicts (DrahtBot): 0

Files

157 lines under test/bench/ci.

  • src/wallet/test/fuzz/scriptpubkeyman.cpp +68/-83
  • src/test/fuzz/util.cpp +2/-2
  • src/test/fuzz/util.h +1/-1

Card

This PR optimizes the scriptpubkeyman fuzz harness by removing redundant IsMine calls, limiting the number of generated coins, moving heavy descriptor operations out of the loop, and fixing an early harness exit on descriptor update failure. Fuzzing throughput improves by 3x to 10x under sanitizer builds (from ~40 exec/s up to 150-385 exec/s). The PR has a Concept ACK, verified benchmarks, and no open reviewer objections.

Data

dossier JSON · extract JSON · model openrouter/google/gemini-3.8-flash, generated 2026-09-17T15:52, confidence high, input hash 1e7fcb291334937b