#36068 fuzz: reuse one fuzzed wallet across inputs
https://github.com/bitcoin/bitcoin/pull/36068 · · +146/-17 in 4 files, 2 commits · labels: Fuzzing
Goal
- Speed up wallet fuzz testing by reusing a single wallet instance across inputs
- Avoid repeated overhead from descriptor imports, BIP32 derivations, and database setups
This pull request optimizes fuzzing of wallet operations by reusing a single FuzzedWallet instance across fuzz inputs rather than reconstructing it each iteration. It introduces CWallet::ClearInMemoryTxStateForTest() to reset transaction and spend maps in memory, and caches derived destinations in FuzzedWallet.
Problem: Rebuilding FuzzedWallet for every fuzz input incurs heavy repeated overhead from importing eight descriptors, BIP32 derivations, and database transactions, slowing fuzz iterations down significantly.
Category: Test infrastructure (#10 of 45)
P3 · speedup
- P3 because a 4x to 6x speedup meaningfully increases fuzz testing throughput
- Accelerates test coverage rate for wallet transaction creation
A 4x to 6x speedup on fuzz execution meaningfully increases fuzz testing throughput and test coverage rate for wallet transaction creation. It is a solid optimization for test infrastructure, though deferrable.
Membership: Modifies shared fuzz utility src/test/fuzz/util/wallet.h and the spend fuzz target src/wallet/test/fuzz/spend.cpp.
Factors: security/stability 0, bug 0, performance 2, user value 0, leverage 1
Category: Wallet (#71 of 84)
P4 · cleanup
- P4 because it only adds an internal test-only helper to wipe in-memory state
- Has no impact on production wallet behavior or user-facing functionality
From a wallet maintenance perspective, this only introduces an internal test-only helper function to wipe in-memory maps, with no impact on real wallet operation or user-facing behavior.
Membership: Touches src/wallet/wallet.h and src/wallet/wallet.cpp by adding CWallet::ClearInMemoryTxStateForTest().
Factors: security/stability 0, bug 0, performance 0, user value 0, leverage 0
Reviewability: Ready
- Ready to review
- Clean patch, passing CI, and initial review questions answered
The patch is small, CI is passing, mergeable clean, and feedback from the initial review has been addressed.
Author status: active
Resolved concerns:
- jeanpablojp noted that DescriptorScriptPubKeyMan next_index drift across inputs causes successive iterations to derive different change addresses; author clarified the bound assertions and documentation.
- jeanpablojp questioned the order of clearing mapWallet relative to containers referencing it; author noted safe order in the test helper.
Agreement: Strong
- Approach approval confirming a roughly 4x fuzz execution speedup (jeanpablojp)
- Concerns about index drift and container clearing order were addressed (jeanpablojp)
Approach ACK from jeanpablojp confirming a 4x fuzz speedup.
jeanpablojp verified the performance improvement on local corpus runs and gave an Approach ACK with only minor questions that the author addressed.
- jeanpablojp: 'Approach ACK. Ran the qa-assets corpus on master and on this head, the speedup reproduces, around 4x here.'
Review verdicts (DrahtBot): 0
- Approach ACK: jeanpablojp
Files
144 lines under test/bench/ci.
- src/test/fuzz/util/wallet.h +118/-12
- src/wallet/test/fuzz/spend.cpp +9/-5
- src/wallet/wallet.cpp +11/-0
- src/wallet/wallet.h +8/-0
Card
This PR refactors FuzzedWallet to initialize once in fuzz target initialization and reset in-memory state per input rather than re-importing descriptors and re-deriving keys every time. It adds a test-only CWallet::ClearInMemoryTxStateForTest() method and precomputes destination pools. Reviewers confirmed a 4x to 6x speedup on the qa-assets corpus. It has an Approach ACK and is ready for merge review.