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_CODESEPARATORshows up only once, as a mempool reject string intest/functional/data/invalid_txs.py. Nothing asserts it at the script level.SCRIPT_ERR_SIG_FINDANDDELETEis 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_CODESEPARATORin an executed pre-segwit script fails with its own error code.OP_CODESEPARATORinside an unexecutedIFbranch fails as well: the check inEvalScripthappens before thefExecguard, 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
CHECKSIGfail withSIG_FINDANDDELETE, sinceFindAndDeletelocates the signature inside the scriptCode. - The same case for
CHECKMULTISIG, which callsFindAndDeletefor each signature in its own loop. - A control vector: with the flag off,
FindAndDeletesilently 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