test: add CONST_SCRIPTCODE failure-path vectors to script_tests.json #35835

pull jeanpablojp wants to merge 1 commits into bitcoin:master from jeanpablojp:script-tests-const-scriptcode changing 1 files +11 −0
  1. jeanpablojp commented at 1:25 PM on July 29, 2026: contributor

    Follow-up to #35664.

    While going through which script error codes are covered by src/test/data/script_tests.json, I noticed that the two errors gated behind SCRIPT_VERIFY_CONST_SCRIPTCODE are never asserted anywhere in the test suite:

    • SCRIPT_ERR_OP_CODESEPARATOR shows up only once, as a mempool reject string in test/functional/data/invalid_txs.py. Nothing asserts it at the script level.
    • SCRIPT_ERR_SIG_FINDANDDELETE is not asserted by any test.

    tx_invalid.json does contain a SCRIPT_VERIFY_CONST_SCRIPTCODE section, but those tests can only state that a transaction is invalid, not which error made it fail. script_tests.json is the harness that verifies exact error codes, and today it has no vector that uses the CONST_SCRIPTCODE flag.

    This PR adds one section with six static vectors:

    • OP_CODESEPARATOR in an executed pre-segwit script fails with its own error code.
    • OP_CODESEPARATOR inside an unexecuted IF branch fails as well: the check in EvalScript happens before the fExec guard, so the opcode is rejected even though it never runs. This rule had no error-level coverage before.
    • A control vector: the same unexecuted-branch script passes when the flag is off.
    • A signature push that also appears in the scriptPubKey makes CHECKSIG fail with SIG_FINDANDDELETE, since FindAndDelete locates the signature inside the scriptCode.
    • The same case for CHECKMULTISIG, which calls FindAndDelete for each signature in its own loop.
    • A control vector: with the flag off, FindAndDelete silently removes the push and the script still evaluates.

    Both checks trigger before any signature verification happens, so the vectors can rely on a dummy signature — the same approach used in #35664.

    To confirm that the expected errors are the ones that really fire, I first added the vectors expecting OK, let the harness report the actual error for each one, and then set the expectations accordingly. Tested with:

    cmake --build build --target test_bitcoin
    build/bin/test_bitcoin --run_test=script_tests/script_json_test
    
  2. test: add CONST_SCRIPTCODE failure-path vectors to script_tests.json 829e44a115
  3. DrahtBot added the label Tests on Jul 29, 2026
  4. DrahtBot commented at 1:25 PM on July 29, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/35835.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    Concept ACK darosior

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  5. darosior commented at 7:05 PM on August 3, 2026: member

    Concept ACK.

    Speaking of const scriptcode quirks, do we have a test case for CVE-2024-38365?

  6. jeanpablojp commented at 8:37 PM on August 3, 2026: contributor

    Not for that exact shape, no. What we have today covers the rule from two sides: script_FindAndDelete has the case commented as "doesn't match 'inside' opcodes", and tx_invalid.json has the vectors with the duplicated signature under a non-standard pushdata prefix, with a comment saying FindAndDelete only removes the push if the prefix is the same. What's missing is a vector with the CVE shape, the signature as the suffix of a bigger push (<x||sig>), and the CVE isn't referenced anywhere.

    Note also that all the current "must not match" vectors live in tx_invalid.json, so they prove the failure side. There's no positive counterpart pinning down that Core accepts the transaction btcd used to reject. And one detail that fits the topic of this PR: since FindAndDelete finds nothing, CONST_SCRIPTCODE doesn't trigger, meaning that vector would pass with or without the flag. I'll write this up as a separate PR.

  7. DrahtBot added the label CI failed on Aug 4, 2026
  8. DrahtBot commented at 12:14 PM on August 4, 2026: contributor

    <!--85328a0da195eb286784d51f73fa0af9-->

    🚧 At least one of the CI tasks failed. <sub>Task riscv32 bare metal, static libbitcoin_consensus: https://github.com/bitcoin/bitcoin/actions/runs/30455919894/job/91974388578</sub> <sub>LLM reason (✨ experimental): CI failed because submodule fetching hit GitHub rate limiting (HTTP 429 “remote end hung up unexpectedly”), so required commit for newlib/gcc couldn’t be retrieved (exit code 2).</sub>

    <details><summary>Hints</summary>

    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.

    </details>

  9. maflcko closed this on Aug 4, 2026

  10. maflcko reopened this on Aug 4, 2026

  11. DrahtBot removed the label CI failed on Aug 4, 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-08-21 05:51 UTC

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