fuzz: expand script verification flag testing to segwit v0 and tapscript #34593

pull b-l-u-e wants to merge 2 commits into bitcoin:master from b-l-u-e:fuzz-script-flags-segwit-tapscript changing 7 files +181 −22
  1. b-l-u-e commented at 8:34 pm on February 14, 2026: contributor

    This continues the work originally started by dergoegge in #31460.

    The script_flags fuzz harness tests that script verification flags are soft-forks applying flags can only tighten rules never widen them. Currently, the fuzzer can’t reach SigVersion::WITNESS_V0 or SigVersion::TAPSCRIPT code paths because it can’t construct inputs that pass the P2WSH script hash check or a valid taproot commitment.

    This PR makes those checks mockable by moving them into virtual methods on BaseSignatureChecker

    • CheckWitnessScriptHash(program, exec_script) for P2WSH script hash verification
    • CheckTaprootCommitment(control, program, tapleaf_hash) for taproot script-path commitment

    A new script_flags_mocked fuzz target uses FuzzedSignatureChecker which mocks out signature validation and these commitment checks, allowing the fuzzer to exercise the interpreter under witness v0 and tapscript contexts

    so the coverage report shows that script_flags_mocked reaches segwit v0 and tapscript paths

    Segwit v0 (P2WSH / P2WPKH)

    Line Hits Code path
    program.size() == WITNESS_V0_SCRIPTHASH_SIZE 10.0k P2WSH branch entered
    checker.CheckWitnessScriptHash(program, exec_script) 6.77k P2WSH script-hash check
    ExecuteWitnessScript(..., SigVersion::WITNESS_V0, ...) (P2WSH) 4.87k Witness v0 script execution (P2WSH)
    ExecuteWitnessScript(..., SigVersion::WITNESS_V0, ...) (P2WPKH) 2.11k Witness v0 script execution (P2WPKH)

    Taproot / tapscript

    Line Hits Code path
    checker.CheckSchnorrSignature(..., SigVersion::TAPROOT, ...) 88 Key-path spend
    checker.CheckTaprootCommitment(control, program, ...) 273 Script-path commitment
    (control[0] & TAPROOT_LEAF_MASK) == TAPROOT_LEAF_TAPSCRIPT 87 Tapscript leaf branch
    ExecuteWitnessScript(..., SigVersion::TAPSCRIPT, ...) 80 Tapscript execution
  2. DrahtBot added the label Fuzzing on Feb 14, 2026
  3. DrahtBot commented at 8:35 pm on February 14, 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.

  4. DrahtBot added the label CI failed on Feb 14, 2026
  5. DrahtBot commented at 9:51 pm on February 14, 2026: contributor

    🚧 At least one of the CI tasks failed. Task lint: https://github.com/bitcoin/bitcoin/actions/runs/22023859338/job/63637248135 LLM reason (✨ experimental): Lint check failed due to trailing whitespace and missing trailing newline in src/test/fuzz/script_flags.cpp.

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  6. b-l-u-e force-pushed on Feb 14, 2026
  7. fanquake commented at 2:58 pm on February 16, 2026: member

    https://github.com/bitcoin/bitcoin/actions/runs/22025166541/job/63640569730?pr=34593#step:11:3973:

    0fuzz: test/fuzz/miniscript.cpp:1149: void (anonymous namespace)::TestNode(const MsCtx, const std::optional<Node> &, FuzzedDataProvider &): Assertion `res || serror == ScriptError::SCRIPT_ERR_OP_COUNT || serror == ScriptError::SCRIPT_ERR_STACK_SIZE' failed.
    1==8513== ERROR: libFuzzer: deadly signal
    
  8. fanquake commented at 2:59 pm on February 16, 2026: member
  9. maflcko commented at 5:33 pm on February 17, 2026: member

    What is the point of opening a test-only pull request, where the added tests are failing??

    Please make sure to run the tests locally before opening a pull request.

  10. maflcko closed this on Feb 17, 2026

  11. b-l-u-e commented at 5:59 pm on February 17, 2026: contributor

    What is the point of opening a test-only pull request, where the added tests are failing??

    Please make sure to run the tests locally before opening a pull request.

    kindly reopen the pull request the test was working fine when i ran it locally… i will convert to draft, since im still working on how to resolve the error

  12. maflcko commented at 6:42 pm on February 17, 2026: member

    I don’t understand what the goal is to collect several draft pull requests. You have multiple open already.

    It is fine to have one or two drafts, but if you want to collect drafts, you can do so in your local fork. There is no need to use this repo for drafts. Especially if it is unclear what the status is and why they are in draft.

    Also, if you want to help with tests, you can help by reviewing and testing other pull requests.

  13. b-l-u-e commented at 7:19 pm on February 17, 2026: contributor

    I don’t understand what the goal is to collect several draft pull requests. You have multiple open already.

    It is fine to have one or two drafts, but if you want to collect drafts, you can do so in your local fork. There is no need to use this repo for drafts. Especially if it is unclear what the status is and why they are in draft.

    Also, if you want to help with tests, you can help by reviewing and testing other pull requests.

    I had 2 draft PRs open all of which, I’m actively trying to work on the two are in progress and being worked on this week… This one had passing tests locally and I planned to resolve the CI issue today.. but, I’ll be mindful of that going forward thanks..

  14. maflcko commented at 7:54 pm on February 17, 2026: member
    I’ll re-open this for now, but try to keep to at most one draft in the future
  15. maflcko reopened this on Feb 17, 2026

  16. script: move taproot commitment and witness script hash checks to BaseSignatureChecker
    Signed-off-by: b-l-u-e <winnie.gitau282@gmail.com>
    0efa79bb15
  17. fuzz: add script_flags_mocked target for segwit v0 and tapscript coverage
    Signed-off-by: b-l-u-e <winnie.gitau282@gmail.com>
    5163e40600
  18. b-l-u-e force-pushed on Feb 17, 2026
  19. b-l-u-e commented at 9:00 pm on February 17, 2026: contributor

    https://github.com/bitcoin/bitcoin/actions/runs/22025166541/job/63640569730?pr=34593#step:11:3973:

    0fuzz: test/fuzz/miniscript.cpp:1149: void (anonymous namespace)::TestNode(const MsCtx, const std::optional<Node> &, FuzzedDataProvider &): Assertion `res || serror == ScriptError::SCRIPT_ERR_OP_COUNT || serror == ScriptError::SCRIPT_ERR_STACK_SIZE' failed.
    1==8513== ERROR: libFuzzer: deadly signal
    

    Still getting a failure in the miniscript fuzzer…another ScriptError type being triggered by the mock checker

    0fuzz: test/fuzz/miniscript.cpp:1153: void (anonymous namespace)::TestNode(const MsCtx, const std::optional<Node> &, FuzzedDataProvider &): Assertion `res || serror == ScriptError::SCRIPT_ERR_OP_COUNT || serror == ScriptError::SCRIPT_ERR_STACK_SIZE || serror == ScriptError::SCRIPT_ERR_EVAL_FALSE || serror == ScriptError::SCRIPT_ERR_CLEANSTACK' failed.
    
  20. b-l-u-e commented at 9:17 pm on February 17, 2026: contributor
    Perhaps maybe i should close this for now until i investigate it further
  21. b-l-u-e closed this on Feb 17, 2026


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

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