An input script might be invalid for multiple reasons. For example, it might fail both a standardness check and a consensus check, which can lead to a mandatory-script-verify-flag-failed error being reported that includes the script error string from the standardness failure (e.g. mandatory-script-verify-flag-failed (Using OP_CODESEPARATOR in non-witness script)), which is confusing.
validation: Improve input script check error reporting #31097
pull dergoegge wants to merge 2 commits into bitcoin:master from dergoegge:2024-10-check2 changing 4 files +24 −2-
dergoegge commented at 9:47 AM on October 16, 2024: member
-
[validation] Improve script check error reporting f859ff8a4e
-
DrahtBot commented at 9:47 AM on October 16, 2024: contributor
<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--006a51241073e994b41acfe9ec718e94-->
Code Coverage
For detailed information about the code coverage, see the test coverage report.
<!--021abf342d371248e50ceaed478a90ca-->
Reviews
See the guideline for information on the review process.
Type Reviewers ACK darosior, ariard, instagibbs If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.
<!--174a7506f384e20aa4161008e828411d-->
Conflicts
Reviewers, this pull request conflicts with the following ones:
- #31112 (Improve parallel script validation error debug logging by sipa)
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.
- DrahtBot added the label Validation on Oct 16, 2024
-
darosior commented at 10:16 AM on October 16, 2024: member
utACK f859ff8a4e9c3aa23bf5be6eceb7099ca72b2290
-
maflcko commented at 11:12 AM on October 16, 2024: member
A bit surprising that all tests passed. Maybe a test-case can be modified, or a new test can be added, so that the test changes fail on master and pass on this pull request? Otherwise, this may be broken again in the future. Also, it is harder to review, because each reviewer will have to write the test themselves.
-
darosior commented at 12:24 PM on October 16, 2024: member
Here is a functional test which creates a transaction using an
OP_CODESEPARATORin itsscriptSig(non-standard) but also uses anOP_RETURNright after, which makes it invalid by consensus. It returns the invalid combination of error strings fixed in this PR ("mandatory-script-verify-flag-failed" because it's a consensus failure, but "Using OP_CODESEPARATOR in non-witness script" because it returns the error string for the first check).You should be able to trivially adapt it to the fix in this PR by updating the error message.
diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py index 33054fd517..6c259d59bb 100644 --- a/test/functional/data/invalid_txs.py +++ b/test/functional/data/invalid_txs.py @@ -245,6 +245,19 @@ class TooManySigops(BadTxTemplate): script_pub_key=lotsa_checksigs, amount=1) + +class NonStandardAndInvalid(BadTxTemplate): + """A non-standard transaction which is also consensus-invalid should return the consensus error.""" + reject_reason = "mandatory-script-verify-flag-failed (Using OP_CODESEPARATOR in non-witness script)" + expect_disconnect = True + valid_in_block = False + + def get_tx(self): + return create_tx_with_script( + self.spend_tx, 0, script_sig=b'\x00' * 3 + b'\xab\x6a', + amount=(self.spend_avail // 2)) + + def getDisabledOpcodeTemplate(opcode): """ Creates disabled opcode tx template class""" def get_tx(self): diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py index 0ae05d4b0b..7782217152 100755 --- a/test/functional/p2p_invalid_tx.py +++ b/test/functional/p2p_invalid_tx.py @@ -165,7 +165,7 @@ class InvalidTxRequestTest(BitcoinTestFramework): node.p2ps[0].send_txs_and_test([rejected_parent], node, success=False) self.log.info('Test that a peer disconnection causes erase its transactions from the orphan pool') - with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=25']): + with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=26']): self.reconnect_p2p(num_connections=1) self.log.info('Test that a transaction in the orphan pool is included in a new tip block causes erase this transaction from the orphan pool') - DrahtBot added the label CI failed on Oct 16, 2024
-
maflcko commented at 3:23 PM on October 16, 2024: member
The test fails due to https://github.com/bitcoin/bitcoin/issues/30960
-
in src/validation.cpp:2200 in ad517754c6 outdated
2193 | @@ -2192,6 +2194,14 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state, 2194 | flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata); 2195 | if (check2()) 2196 | return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); 2197 | + 2198 | + // If the second check failed, it failed due to a mandatory script verification 2199 | + // flag, but the first check might have failed on a non-mandatory script 2200 | + // verification flag.
ariard commented at 8:22 PM on October 16, 2024:I was reading the comment just above this one i.e “Check whether the failure was caused by a non-mandatory script verification check, such as non-standard DER encodings or non-null dummy arguments”.
I think the 2 examples given in this comment are actually “mandatory-script-verify-flag”, i.e CONSENSUS and not NOT_STANDARD:
- DER encodings (BIP66 and
SCRIPT_VERIFY_DERSIG), interpreter flag is set inGetBlockScriptFlagshttps://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp#L2378 - NULLDUMMY for CHECKMULTISIG (BIP147 and
SCRIPT_VERIFY_NULLDUMMY), interpreter flag is set inGetBlockScriptFlagshttps://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp#L2393
Those 2 consensus changes have been buried, so I think the comment could reflet there are TX_NOT_STANDARD before the buried height (correspondingly
363725and481824) and verification check error for DER encoding andNULLDUMMYshould be TX_CONSENSUS after.in test/functional/data/invalid_txs.py:272 in ad517754c6 outdated
267 | + """A non-standard transaction which is also consensus-invalid should return the consensus error.""" 268 | + reject_reason = "mandatory-script-verify-flag-failed (OP_RETURN was encountered)" 269 | + expect_disconnect = True 270 | + valid_in_block = False 271 | + 272 | + def get_tx(self):
ariard commented at 8:43 PM on October 16, 2024:I think we should have further tests that a non-standard transaction which is consensus valid before an activation height, is considered as consensus invalid after the activation height.
E.g on regtest, the deployment heights are always active unless overridden. I don’t think we do that in
invalid_txs.pycurrently: https://github.com/bitcoin/bitcoin/blob/master/test/functional/p2p_invalid_tx.py#L28ariard commented at 8:45 PM on October 16, 2024: noneutACK ad51775
DrahtBot requested review from darosior on Oct 16, 2024in src/validation.cpp:2196 in ad517754c6 outdated
2193 | @@ -2192,6 +2194,14 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state, 2194 | flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata); 2195 | if (check2()) 2196 | return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
ariard commented at 2:37 AM on October 17, 2024:diff --git a/src/validation.cpp b/src/validation.cpp index fc61b14dc1..ecc1ab22dd 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1970,7 +1970,7 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state, CScriptCheck check2(txdata.m_spent_outputs[i], tx, i, flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata); if (check2()) - return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); + return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(error))); // If the second check failed, it failed due to a mandatory script verification // flag, but the first check might have failed on a non-mandatory script
dergoegge commented at 11:58 AM on October 17, 2024:Will do if i push again
instagibbs commented at 1:15 PM on October 21, 2024:nit: Agreed, this would help readability.
sipa commented at 1:54 PM on October 21, 2024:My follow-up PR removes
CScriptCheck::GetScriptError, so this modification isn't really applicable anymore.ariard commented at 2:37 AM on October 17, 2024: noneRe-tested, getting the correct RPC string.
maflcko commented at 9:43 AM on October 17, 2024: member-par=1(or whatever to make the thread inline) should work, no?[test] A non-standard transaction which is also consensus-invalid should return the consensus error 86e2a6b749dergoegge force-pushed on Oct 17, 2024DrahtBot removed the label CI failed on Oct 17, 2024dergoegge commented at 11:58 AM on October 17, 2024: member-par=1 (or whatever to make the thread inline) should work, no?
That worked, thanks!
darosior commented at 2:06 PM on October 17, 2024: memberre-ACK 86e2a6b749c7fecbd086b361806ac9f6e9426d79
DrahtBot requested review from ariard on Oct 17, 2024ariard commented at 9:47 PM on October 17, 2024: noneRe-Code Review ACK 86e2a6b7
The code nit improvement, ready to be git cherry-picked:https://github.com/ariard/bitcoin/tree/2024-10-check2-impr
fanquake requested review from instagibbs on Oct 21, 2024instagibbs approvedinstagibbs commented at 1:45 PM on October 21, 2024: memberACK 86e2a6b749c7fecbd086b361806ac9f6e9426d79
played with tests to ensure the test was failing how I'd expect it with modifications
fanquake merged this on Oct 21, 2024fanquake closed this on Oct 21, 2024danielabrozzoni commented at 2:10 PM on October 21, 2024: contributorpost merge tACK 86e2a6b749c7fecbd086b361806ac9f6e9426d79
TheCharlatan referenced this in commit 8bb47d4c2c on Nov 2, 2024achow101 referenced this in commit 3867d2421a on Dec 3, 2024luke-jr referenced this in commit 2d69e4c454 on Feb 26, 2025luke-jr referenced this in commit 6c24ce7025 on Feb 26, 2025bug-castercv502 referenced this in commit 403bebd591 on Sep 28, 2025bitcoin locked this on Oct 21, 2025 - DER encodings (BIP66 and
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-28 21:13 UTC
More mirrored repositories can be found on mirror.b10c.me