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.
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.
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
For detailed information about the code coverage, see the test coverage report.
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.
Reviewers, this pull request conflicts with the following ones:
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.
Here is a functional test which creates a transaction using an OP_CODESEPARATOR
in its scriptSig
(non-standard) but also uses an OP_RETURN
right 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.
0diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py
1index 33054fd517..6c259d59bb 100644
2--- a/test/functional/data/invalid_txs.py
3+++ b/test/functional/data/invalid_txs.py
4@@ -245,6 +245,19 @@ class TooManySigops(BadTxTemplate):
5 script_pub_key=lotsa_checksigs,
6 amount=1)
7
8+
9+class NonStandardAndInvalid(BadTxTemplate):
10+ """A non-standard transaction which is also consensus-invalid should return the consensus error."""
11+ reject_reason = "mandatory-script-verify-flag-failed (Using OP_CODESEPARATOR in non-witness script)"
12+ expect_disconnect = True
13+ valid_in_block = False
14+
15+ def get_tx(self):
16+ return create_tx_with_script(
17+ self.spend_tx, 0, script_sig=b'\x00' * 3 + b'\xab\x6a',
18+ amount=(self.spend_avail // 2))
19+
20+
21 def getDisabledOpcodeTemplate(opcode):
22 """ Creates disabled opcode tx template class"""
23 def get_tx(self):
24diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py
25index 0ae05d4b0b..7782217152 100755
26--- a/test/functional/p2p_invalid_tx.py
27+++ b/test/functional/p2p_invalid_tx.py
28@@ -165,7 +165,7 @@ class InvalidTxRequestTest(BitcoinTestFramework):
29 node.p2ps[0].send_txs_and_test([rejected_parent], node, success=False)
30
31 self.log.info('Test that a peer disconnection causes erase its transactions from the orphan pool')
32- with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=25']):
33+ with node.assert_debug_log(['Erased 100 orphan transaction(s) from peer=26']):
34 self.reconnect_p2p(num_connections=1)
35
36 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')
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.
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:
SCRIPT_VERIFY_DERSIG
), interpreter flag is set in GetBlockScriptFlags
https://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp#L2378SCRIPT_VERIFY_NULLDUMMY
), interpreter flag is set in GetBlockScriptFlags
https://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp#L2393Those 2 consensus changes have been buried, so I think the comment could reflet there are TX_NOT_STANDARD before the buried height (correspondingly 363725
and 481824
) and verification check error for DER encoding and NULLDUMMY
should be TX_CONSENSUS after.
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):
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.py
currently: https://github.com/bitcoin/bitcoin/blob/master/test/functional/p2p_invalid_tx.py#L28
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())));
0diff --git a/src/validation.cpp b/src/validation.cpp
1index fc61b14dc1..ecc1ab22dd 100644
2--- a/src/validation.cpp
3+++ b/src/validation.cpp
4@@ -1970,7 +1970,7 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
5 CScriptCheck check2(txdata.m_spent_outputs[i], tx, i,
6 flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata);
7 if (check2())
8- return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
9+ return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(error)));
10
11 // If the second check failed, it failed due to a mandatory script verification
12 // flag, but the first check might have failed on a non-mandatory script
CScriptCheck::GetScriptError
, so this modification isn’t really applicable anymore.
-par=1
(or whatever to make the thread inline) should work, no?
-par=1 (or whatever to make the thread inline) should work, no?
That worked, thanks!
Re-Code Review ACK 86e2a6b7
The code nit improvement, ready to be git cherry-picked:https://github.com/ariard/bitcoin/tree/2024-10-check2-impr
ACK 86e2a6b749c7fecbd086b361806ac9f6e9426d79
played with tests to ensure the test was failing how I’d expect it with modifications