fuzz: several improvements to scriptpubkeyman harness #34969

pull brunoerg wants to merge 6 commits into bitcoin:master from brunoerg:2026-03-fuzz-spkm-improvements changing 3 files +71 −89
  1. brunoerg commented at 7:10 pm on March 31, 2026: contributor

    The scriptpubkeyman harness is slow - I’m getting under 40 exec/s on my personal server. This PR solves the following issues that may be affecting the performance:

    • There are redundant IsMine calls
    • ConsumeCoins always create up to 10'000 coins which may cause slowness.
    • There are some expensive ops in a loop - e.g. One of the slow units I got on my server is about a repeated sequence of GetNewDestination calls (see flamegraph below).
    • We’re always calling GetDescriptorString unconditionally. It looks like an inofensive function but this is extremely costly due to calls to ToNormalizedString/ToPrivateString functions that touch key operations.
    • Not related to slowness, but there is a bug on harness because we are aborting the execution when we cannot update the wallet descriptor, we can just skip and continue.

    spkm-updated

  2. fuzz: spkm: remove unnecessary IsMine call
    `MarkUnusedAddresses` covers it.
    1d826e5b8c
  3. fuzz: add a num_coins parameter to ConsumeCoins
    This new parameter is used to control the max number of coins
    this function might create. It allows us to create less than
    10'000 coins and then reduce the cost.
    8aa9fbe86d
  4. fuzz: spkm: reduce number of created coins 8f28f8a42d
  5. fuzz: spkm: move expensive ops out of the loop d19147b96f
  6. fuzz: spkm: do not call GetDescriptorString unconditionally
    GetDescriptorString calls ToNormalizedString or ToPrivateString,
    both of which rebuild the full descriptor string. This is expensive.
    da1ba538f6
  7. fuzz: spkm: fix early return on updating the wallet descriptor 883cf5ad79
  8. DrahtBot added the label Fuzzing on Mar 31, 2026
  9. DrahtBot commented at 7:11 pm on March 31, 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.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #34170 (fuzz: Extend scriptpubkeyman coverage by Chand-ra)
    • #32876 (refactor: use options struct for signing and PSBT operations by Sjors)
    • #32857 (wallet: allow skipping script paths by Sjors)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  10. andrewtoth commented at 9:04 pm on March 31, 2026: contributor

    Getting decent throughput when running on my laptop:

    0$ FUZZ=scriptpubkeyman ./build_fuzz_nosan/bin/fuzz ../qa-assets/fuzz_corpora/scriptpubkeyman/
    1...
    2[#3326974](/bitcoin-bitcoin/3326974/)	REDUCE cov: 14175 ft: 84867 corp: 5289/37Mb lim: 998620 exec/s: 1319 rss: 262Mb L: 15776/882699 MS: 1 EraseBytes-
    3[#3327186](/bitcoin-bitcoin/3327186/)	REDUCE cov: 14175 ft: 84867 corp: 5289/37Mb lim: 998620 exec/s: 1319 rss: 262Mb L: 961/882699 MS: 2 ChangeBit-EraseBytes-
    4[#3328687](/bitcoin-bitcoin/3328687/)	REDUCE cov: 14175 ft: 84867 corp: 5289/37Mb lim: 998620 exec/s: 1319 rss: 262Mb L: 1249/882699 MS: 1 EraseBytes-
    5...
    

    How is your server configured? Do you see a big speedup after applying this patch?

  11. brunoerg commented at 1:11 am on April 1, 2026: contributor

    Getting decent throughput when running on my laptop:

    What are the specs? How did you build it? Building with --preset=libfuzzer on my Ubuntu machine (AMD Ryzen 9 7900 / 32GB RAM), I get around 20 exec/s. With this PR, on same machine, I could reach similar coverage from master with an avg of 150 exec/s.

  12. andrewtoth commented at 3:07 am on April 1, 2026: contributor

    I’m on a i9-14900 with 96 GB RAM.

    I was running with only fuzzer sanitizer. When --preset=libfuzzer that uses undefined,address,fuzzer. With those I get a lot slower. It started at at 39 but after a few minutes was up to 128 exec/s. I checked out this PR and then it started at 128 and after a few minutes was up to 385 exec/s. Not bad!

    Running with only fuzzer sanitizer on this branch however didn’t seem to speed up it was around 1100 exec/s.

  13. brunoerg commented at 12:13 pm on April 1, 2026: contributor

    I’m on a i9-14900 with 96 GB RAM.

    I was running with only fuzzer sanitizer. When --preset=libfuzzer that uses undefined,address,fuzzer. With those I get a lot slower. It started at at 39 but after a few minutes was up to 128 exec/s. I checked out this PR and then it started at 128 and after a few minutes was up to 385 exec/s. Not bad!

    Running with only fuzzer sanitizer on this branch however didn’t seem to speed up it was around 1100 exec/s.

    Ah, got it. This is expected, because ASan instruments most memory accesses in instrumented code and tracks heap allocations, while UBSan adds runtime checks for selected undefined behaviors. So operations like GetScriptPubKeys(), ConsumeCoins(), and some string operations, such as GetDescriptorString() can become more expensive under these sanitizers.


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

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