validation: only check input scripts once
What changed, and why it matters
This Bitcoin Core change removes a second, redundant check of transaction scripts when a transaction is rejected from the mempool. Previously, the software ran the expensive script check twice to decide whether a failure was a policy issue (like a non-standard signature) or a consensus issue (a rule everyone must agree on). Now it only checks once and reports a single mempool error. This is mainly a performance and code-simplification improvement; it does not change which transactions are accepted or rejected, only the exact error message returned and the internal work done.
No immediate security action required. Operators and integrators relying on exact mempool reject-reason strings should update their parsing to recognize the new 'mempool-script-verify-flag-failed' prefix. Reviewers should confirm that the single-pass logic does not accidentally treat a pure consensus failure as policy-only in block validation paths, which the diff indicates is preserved by using different flag sets for mempool vs. block checks.
Security signals we found
Behavior change in error reporting for mempool script failures
Removal of redundant script execution path
Performance optimization in transaction validation
No change to consensus acceptance rules
No change to peer banning/disconnection logic for transactions
Evidence from the diff
In src/validation.cpp, CheckInputScripts no longer re-runs script verification with STANDARD_NOT_MANDATORY_VERIFY_FLAGS masked off when a mempool check fails. Instead, if the standard flags include non-mandatory policy flags, it immediately returns TX_NOT_STANDARD with the new string ‘mempool-script-verify-flag-failed’. If only consensus/mandatory flags are in use, it returns TX_CONSENSUS with ‘mandatory-script-verify-flag-failed’. The commit message explicitly states the motivation: peer discouragement for consensus failures during transaction relay has already been removed, and script checks are expensive, so the second pass is unnecessary. Test files are updated to expect the new error string and, where relevant, to expect the consensus error only when the same transaction is evaluated in a block context.
Changed components
src/validation.cpp CheckInputScriptsmempool acceptance RPC and P2P pathsfunctional tests for CLTV, DERSIG, NULLDUMMY, SegWit, mempool accept, packagesInspect captured patch +57 / −68
diff --git a/src/validation.cpp b/src/validation.cpp
index cf5f5469..b013d3b0 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -2191,34 +2191,17 @@ bool CheckInputScripts(const CTransaction& tx, TxValidationState& state,
if (pvChecks) {
pvChecks->emplace_back(std::move(check));
} else if (auto result = check(); result.has_value()) {
+ // Tx failures never trigger disconnections/bans.
+ // This is so that network splits aren't triggered
+ // either due to non-consensus relay policies (such as
+ // non-standard DER encodings or non-null dummy
+ // arguments) or due to new consensus rules introduced in
+ // soft forks.
if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) {
- // Check whether the failure was caused by a
- // non-mandatory script verification check, such as
- // non-standard DER encodings or non-null dummy
- // arguments; if so, ensure we return NOT_STANDARD
- // instead of CONSENSUS to avoid downstream users
- // splitting the network between upgraded and
- // non-upgraded nodes by banning CONSENSUS-failing
- // data providers.
- CScriptCheck check2(txdata.m_spent_outputs[i], tx, validation_cache.m_signature_cache, i,
- flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata);
- auto mandatory_result = check2();
- if (!mandatory_result.has_value()) {
- return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(result->first)), result->second);
- } else {
- // 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
- // verification flag.
- //
- // Avoid reporting a mandatory script check failure with a non-mandatory error
- // string by reporting the error from the second check.
- result = mandatory_result;
- }
+ return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("mempool-script-verify-flag-failed (%s)", ScriptErrorString(result->first)), result->second);
+ } else {
+ return state.Invalid(TxValidationResult::TX_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(result->first)), result->second);
}
-
- // MANDATORY flag failures correspond to
- // TxValidationResult::TX_CONSENSUS.
- return state.Invalid(TxValidationResult::TX_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(result->first)), result->second);
}
}
diff --git a/test/functional/data/invalid_txs.py b/test/functional/data/invalid_txs.py
index 32a188d1..3c249b2f 100644
--- a/test/functional/data/invalid_txs.py
+++ b/test/functional/data/invalid_txs.py
@@ -223,7 +223,7 @@ class CreateSumTooLarge(BadTxTemplate):
class InvalidOPIFConstruction(BadTxTemplate):
- reject_reason = "mandatory-script-verify-flag-failed (Invalid OP_IF construction)"
+ reject_reason = "mempool-script-verify-flag-failed (Invalid OP_IF construction)"
expect_disconnect = False
def get_tx(self):
@@ -276,8 +276,9 @@ def getDisabledOpcodeTemplate(opcode):
})
class NonStandardAndInvalid(BadTxTemplate):
- """A non-standard transaction which is also consensus-invalid should return the consensus error."""
- reject_reason = "mandatory-script-verify-flag-failed (OP_RETURN was encountered)"
+ """A non-standard transaction which is also consensus-invalid should return the first error."""
+ reject_reason = "mempool-script-verify-flag-failed (Using OP_CODESEPARATOR in non-witness script)"
+ block_reject_reason = "mandatory-script-verify-flag-failed (OP_RETURN was encountered)"
expect_disconnect = False
valid_in_block = False
diff --git a/test/functional/feature_block.py b/test/functional/feature_block.py
index 63592122..bc0364a8 100755
--- a/test/functional/feature_block.py
+++ b/test/functional/feature_block.py
@@ -194,9 +194,12 @@ class FullBlockTest(BitcoinTestFramework):
if TxTemplate != invalid_txs.InputMissing:
self.sign_tx(badtx, attempt_spend_tx)
badblock = self.update_block(blockname, [badtx])
+ reject_reason = (template.block_reject_reason or template.reject_reason)
+ if reject_reason.startswith("mempool-script-verify-flag-failed"):
+ reject_reason = "mandatory-script-verify-flag-failed" + reject_reason[33:]
self.send_blocks(
[badblock], success=False,
- reject_reason=(template.block_reject_reason or template.reject_reason),
+ reject_reason=reject_reason,
reconnect=True, timeout=2)
self.move_tip(2)
diff --git a/test/functional/feature_cltv.py b/test/functional/feature_cltv.py
index 2f34f557..75cd38a9 100755
--- a/test/functional/feature_cltv.py
+++ b/test/functional/feature_cltv.py
@@ -153,12 +153,14 @@ class BIP65Test(BitcoinTestFramework):
coin_vout = coin.prevout.n
cltv_invalidate(spendtx, i)
+ blk_rej = "mandatory-script-verify-flag-failed"
+ tx_rej = "mempool-script-verify-flag-failed"
expected_cltv_reject_reason = [
- "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)",
- "mandatory-script-verify-flag-failed (Negative locktime)",
- "mandatory-script-verify-flag-failed (Locktime requirement not satisfied)",
- "mandatory-script-verify-flag-failed (Locktime requirement not satisfied)",
- "mandatory-script-verify-flag-failed (Locktime requirement not satisfied)",
+ " (Operation not valid with the current stack size)",
+ " (Negative locktime)",
+ " (Locktime requirement not satisfied)",
+ " (Locktime requirement not satisfied)",
+ " (Locktime requirement not satisfied)",
][i]
# First we show that this tx is valid except for CLTV by getting it
# rejected from the mempool for exactly that reason.
@@ -169,8 +171,8 @@ class BIP65Test(BitcoinTestFramework):
'txid': spendtx_txid,
'wtxid': spendtx_wtxid,
'allowed': False,
- 'reject-reason': expected_cltv_reject_reason,
- 'reject-details': expected_cltv_reject_reason + f", input 0 of {spendtx_txid} (wtxid {spendtx_wtxid}), spending {coin_txid}:{coin_vout}"
+ 'reject-reason': tx_rej + expected_cltv_reject_reason,
+ 'reject-details': tx_rej + expected_cltv_reject_reason + f", input 0 of {spendtx_txid} (wtxid {spendtx_wtxid}), spending {coin_txid}:{coin_vout}"
}],
self.nodes[0].testmempoolaccept(rawtxs=[spendtx.serialize().hex()], maxfeerate=0),
)
@@ -180,7 +182,7 @@ class BIP65Test(BitcoinTestFramework):
block.hashMerkleRoot = block.calc_merkle_root()
block.solve()
- with self.nodes[0].assert_debug_log(expected_msgs=[f'Block validation error: {expected_cltv_reject_reason}']):
+ with self.nodes[0].assert_debug_log(expected_msgs=[f'Block validation error: {blk_rej + expected_cltv_reject_reason}']):
peer.send_and_ping(msg_block(block))
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
peer.sync_with_ping()
diff --git a/test/functional/feature_dersig.py b/test/functional/feature_dersig.py
index e0e00467..eec1559a 100755
--- a/test/functional/feature_dersig.py
+++ b/test/functional/feature_dersig.py
@@ -121,8 +121,8 @@ class BIP66Test(BitcoinTestFramework):
'txid': spendtx_txid,
'wtxid': spendtx_wtxid,
'allowed': False,
- 'reject-reason': 'mandatory-script-verify-flag-failed (Non-canonical DER signature)',
- 'reject-details': 'mandatory-script-verify-flag-failed (Non-canonical DER signature), ' +
+ 'reject-reason': 'mempool-script-verify-flag-failed (Non-canonical DER signature)',
+ 'reject-details': 'mempool-script-verify-flag-failed (Non-canonical DER signature), ' +
f"input 0 of {spendtx_txid} (wtxid {spendtx_wtxid}), spending {coin_txid}:0"
}],
self.nodes[0].testmempoolaccept(rawtxs=[spendtx.serialize().hex()], maxfeerate=0),
diff --git a/test/functional/feature_nulldummy.py b/test/functional/feature_nulldummy.py
index f301d65a..cd7c4491 100755
--- a/test/functional/feature_nulldummy.py
+++ b/test/functional/feature_nulldummy.py
@@ -37,8 +37,8 @@ from test_framework.util import (
from test_framework.wallet import getnewdestination
from test_framework.wallet_util import generate_keypair
-NULLDUMMY_ERROR = "mandatory-script-verify-flag-failed (Dummy CHECKMULTISIG argument must be zero)"
-
+NULLDUMMY_TX_ERROR = "mempool-script-verify-flag-failed (Dummy CHECKMULTISIG argument must be zero)"
+NULLDUMMY_BLK_ERROR = "mandatory-script-verify-flag-failed (Dummy CHECKMULTISIG argument must be zero)"
def invalidate_nulldummy_tx(tx):
"""Transform a NULLDUMMY compliant tx (i.e. scriptSig starts with OP_0)
@@ -104,7 +104,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
addr=self.ms_address, amount=47,
privkey=self.privkey)
invalidate_nulldummy_tx(test2tx)
- assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test2tx.serialize_with_witness().hex(), 0)
+ assert_raises_rpc_error(-26, NULLDUMMY_TX_ERROR, self.nodes[0].sendrawtransaction, test2tx.serialize_with_witness().hex(), 0)
self.log.info(f"Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [{COINBASE_MATURITY + 4}]")
self.block_submit(self.nodes[0], [test2tx], accept=True)
@@ -115,7 +115,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
privkey=self.privkey)
test6txs = [CTransaction(test4tx)]
invalidate_nulldummy_tx(test4tx)
- assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test4tx.serialize_with_witness().hex(), 0)
+ assert_raises_rpc_error(-26, NULLDUMMY_TX_ERROR, self.nodes[0].sendrawtransaction, test4tx.serialize_with_witness().hex(), 0)
self.block_submit(self.nodes[0], [test4tx], accept=False)
self.log.info("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation")
@@ -125,7 +125,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
privkey=self.privkey)
test6txs.append(CTransaction(test5tx))
test5tx.wit.vtxinwit[0].scriptWitness.stack[0] = b'\x01'
- assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, test5tx.serialize_with_witness().hex(), 0)
+ assert_raises_rpc_error(-26, NULLDUMMY_TX_ERROR, self.nodes[0].sendrawtransaction, test5tx.serialize_with_witness().hex(), 0)
self.block_submit(self.nodes[0], [test5tx], with_witness=True, accept=False)
self.log.info(f"Test 6: NULLDUMMY compliant base/witness transactions should be accepted to mempool and in block after activation [{COINBASE_MATURITY + 5}]")
@@ -141,7 +141,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
if with_witness:
add_witness_commitment(block)
block.solve()
- assert_equal(None if accept else NULLDUMMY_ERROR, node.submitblock(block.serialize().hex()))
+ assert_equal(None if accept else NULLDUMMY_BLK_ERROR, node.submitblock(block.serialize().hex()))
if accept:
assert_equal(node.getbestblockhash(), block.hash_hex)
self.lastblockhash = block.hash_hex
diff --git a/test/functional/feature_segwit.py b/test/functional/feature_segwit.py
index 967b9e1e..80266aa2 100755
--- a/test/functional/feature_segwit.py
+++ b/test/functional/feature_segwit.py
@@ -177,8 +177,8 @@ class SegWitTest(BitcoinTestFramework):
assert_equal(self.nodes[2].getbalance(), 20 * Decimal("49.999"))
self.log.info("Verify unsigned p2sh witness txs without a redeem script are invalid")
- self.fail_accept(self.nodes[2], "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_2][P2WPKH][1], sign=False)
- self.fail_accept(self.nodes[2], "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_2][P2WSH][1], sign=False)
+ self.fail_accept(self.nodes[2], "mempool-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_2][P2WPKH][1], sign=False)
+ self.fail_accept(self.nodes[2], "mempool-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_2][P2WSH][1], sign=False)
self.generate(self.nodes[0], 1) # block 164
@@ -197,13 +197,13 @@ class SegWitTest(BitcoinTestFramework):
self.log.info("Verify default node can't accept txs with missing witness")
# unsigned, no scriptsig
- self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Witness program hash mismatch)", wit_ids[NODE_0][P2WPKH][0], sign=False)
- self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Witness program was passed an empty witness)", wit_ids[NODE_0][P2WSH][0], sign=False)
- self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_0][P2WPKH][0], sign=False)
- self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_0][P2WSH][0], sign=False)
+ self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Witness program hash mismatch)", wit_ids[NODE_0][P2WPKH][0], sign=False)
+ self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Witness program was passed an empty witness)", wit_ids[NODE_0][P2WSH][0], sign=False)
+ self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_0][P2WPKH][0], sign=False)
+ self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Operation not valid with the current stack size)", p2sh_ids[NODE_0][P2WSH][0], sign=False)
# unsigned with redeem script
- self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Witness program hash mismatch)", p2sh_ids[NODE_0][P2WPKH][0], sign=False, redeem_script=witness_script(False, self.pubkey[0]))
- self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Witness program was passed an empty witness)", p2sh_ids[NODE_0][P2WSH][0], sign=False, redeem_script=witness_script(True, self.pubkey[0]))
+ self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Witness program hash mismatch)", p2sh_ids[NODE_0][P2WPKH][0], sign=False, redeem_script=witness_script(False, self.pubkey[0]))
+ self.fail_accept(self.nodes[0], "mempool-script-verify-flag-failed (Witness program was passed an empty witness)", p2sh_ids[NODE_0][P2WSH][0], sign=False, redeem_script=witness_script(True, self.pubkey[0]))
# Coinbase contains the witness commitment nonce, check that RPC shows us
coinbase_txid = self.nodes[2].getblock(blockhash)['tx'][0]
@@ -214,10 +214,10 @@ class SegWitTest(BitcoinTestFramework):
assert_equal(witnesses[0], '00' * 32)
self.log.info("Verify witness txs without witness data are invalid after the fork")
- self.fail_accept(self.nodes[2], 'mandatory-script-verify-flag-failed (Witness program hash mismatch)', wit_ids[NODE_2][P2WPKH][2], sign=False)
- self.fail_accept(self.nodes[2], 'mandatory-script-verify-flag-failed (Witness program was passed an empty witness)', wit_ids[NODE_2][P2WSH][2], sign=False)
- self.fail_accept(self.nodes[2], 'mandatory-script-verify-flag-failed (Witness program hash mismatch)', p2sh_ids[NODE_2][P2WPKH][2], sign=False, redeem_script=witness_script(False, self.pubkey[2]))
- self.fail_accept(self.nodes[2], 'mandatory-script-verify-flag-failed (Witness program was passed an empty witness)', p2sh_ids[NODE_2][P2WSH][2], sign=False, redeem_script=witness_script(True, self.pubkey[2]))
+ self.fail_accept(self.nodes[2], 'mempool-script-verify-flag-failed (Witness program hash mismatch)', wit_ids[NODE_2][P2WPKH][2], sign=False)
+ self.fail_accept(self.nodes[2], 'mempool-script-verify-flag-failed (Witness program was passed an empty witness)', wit_ids[NODE_2][P2WSH][2], sign=False)
+ self.fail_accept(self.nodes[2], 'mempool-script-verify-flag-failed (Witness program hash mismatch)', p2sh_ids[NODE_2][P2WPKH][2], sign=False, redeem_script=witness_script(False, self.pubkey[2]))
+ self.fail_accept(self.nodes[2], 'mempool-script-verify-flag-failed (Witness program was passed an empty witness)', p2sh_ids[NODE_2][P2WSH][2], sign=False, redeem_script=witness_script(True, self.pubkey[2]))
self.log.info("Verify default node can now use witness txs")
self.success_mine(self.nodes[0], wit_ids[NODE_0][P2WPKH][0], True)
diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py
index e225b68c..867c9312 100755
--- a/test/functional/mempool_accept.py
+++ b/test/functional/mempool_accept.py
@@ -475,7 +475,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
nested_anchor_spend.vout.append(CTxOut(nested_anchor_tx.vout[0].nValue - int(fee*COIN), script_to_p2wsh_script(CScript([OP_TRUE]))))
self.check_mempool_result(
- result_expected=[{'txid': nested_anchor_spend.txid_hex, 'allowed': False, 'reject-reason': 'non-mandatory-script-verify-flag (Witness version reserved for soft-fork upgrades)'}],
+ result_expected=[{'txid': nested_anchor_spend.txid_hex, 'allowed': False, 'reject-reason': 'mempool-script-verify-flag-failed (Witness version reserved for soft-fork upgrades)'}],
rawtxs=[nested_anchor_spend.serialize().hex()],
maxfeerate=0,
)
diff --git a/test/functional/p2p_segwit.py b/test/functional/p2p_segwit.py
index 8193ff7c..810b6a47 100755
--- a/test/functional/p2p_segwit.py
+++ b/test/functional/p2p_segwit.py
@@ -690,19 +690,19 @@ class SegWitTest(BitcoinTestFramework):
# segwit activation. Note that older bitcoind's that are not
# segwit-aware would also reject this for failing CLEANSTACK.
with self.nodes[0].assert_debug_log(
- expected_msgs=[spend_tx.txid_hex, 'was not accepted: mandatory-script-verify-flag-failed (Witness program was passed an empty witness)']):
+ expected_msgs=[spend_tx.txid_hex, 'was not accepted: mempool-script-verify-flag-failed (Witness program was passed an empty witness)']):
test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False)
# The transaction was detected as witness stripped above and not added to the reject
# filter. Trying again will check it again and result in the same error.
with self.nodes[0].assert_debug_log(
- expected_msgs=[spend_tx.txid_hex, 'was not accepted: mandatory-script-verify-flag-failed (Witness program was passed an empty witness)']):
+ expected_msgs=[spend_tx.txid_hex, 'was not accepted: mempool-script-verify-flag-failed (Witness program was passed an empty witness)']):
test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False)
# Try to put the witness script in the scriptSig, should also fail.
spend_tx.vin[0].scriptSig = CScript([p2wsh_pubkey, b'a'])
with self.nodes[0].assert_debug_log(
- expected_msgs=[spend_tx.txid_hex, 'was not accepted: mandatory-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)']):
+ expected_msgs=[spend_tx.txid_hex, 'was not accepted: mempool-script-verify-flag-failed (Script evaluated without error but finished with a false/empty top stack element)']):
test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False)
# Now put the witness script in the witness, should succeed after
@@ -1254,7 +1254,7 @@ class SegWitTest(BitcoinTestFramework):
# Now do the opposite: strip the witness entirely. This will be detected as witness stripping and
# the (w)txid won't be added to the reject filter: we can try again and get the same error.
tx3.wit.vtxinwit[0].scriptWitness.stack = []
- reason = "was not accepted: mandatory-script-verify-flag-failed (Witness program was passed an empty witness)"
+ reason = "was not accepted: mempool-script-verify-flag-failed (Witness program was passed an empty witness)"
test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=False, accepted=False, reason=reason)
test_transaction_acceptance(self.nodes[0], self.test_node, tx3, with_witness=False, accepted=False, reason=reason)
@@ -1447,7 +1447,7 @@ class SegWitTest(BitcoinTestFramework):
sign_input_segwitv0(tx2, 0, script, tx.vout[0].nValue, key)
# Should fail policy test.
- test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx2, True, False, 'mempool-script-verify-flag-failed (Using non-compressed keys in segwit)')
# But passes consensus.
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx2])
@@ -1466,7 +1466,7 @@ class SegWitTest(BitcoinTestFramework):
sign_p2pk_witness_input(witness_script, tx3, 0, SIGHASH_ALL, tx2.vout[0].nValue, key)
# Should fail policy test.
- test_transaction_acceptance(self.nodes[0], self.test_node, tx3, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx3, True, False, 'mempool-script-verify-flag-failed (Using non-compressed keys in segwit)')
# But passes consensus.
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx3])
@@ -1483,7 +1483,7 @@ class SegWitTest(BitcoinTestFramework):
sign_p2pk_witness_input(witness_script, tx4, 0, SIGHASH_ALL, tx3.vout[0].nValue, key)
# Should fail policy test.
- test_transaction_acceptance(self.nodes[0], self.test_node, tx4, True, False, 'non-mandatory-script-verify-flag (Using non-compressed keys in segwit)')
+ test_transaction_acceptance(self.nodes[0], self.test_node, tx4, True, False, 'mempool-script-verify-flag-failed (Using non-compressed keys in segwit)')
block = self.build_next_block()
self.update_witness_block_with_transactions(block, [tx4])
test_witness_block(self.nodes[0], self.test_node, block, accepted=True)
diff --git a/test/functional/rpc_packages.py b/test/functional/rpc_packages.py
index 3c467394..325a29c4 100755
--- a/test/functional/rpc_packages.py
+++ b/test/functional/rpc_packages.py
@@ -123,8 +123,8 @@ class RPCPackagesTest(BitcoinTestFramework):
assert_equal(testres_bad_sig, self.independent_txns_testres + [{
"txid": tx_bad_sig_txid,
"wtxid": tx_bad_sig_wtxid, "allowed": False,
- "reject-reason": "mandatory-script-verify-flag-failed (Operation not valid with the current stack size)",
- "reject-details": "mandatory-script-verify-flag-failed (Operation not valid with the current stack size), " +
+ "reject-reason": "mempool-script-verify-flag-failed (Operation not valid with the current stack size)",
+ "reject-details": "mempool-script-verify-flag-failed (Operation not valid with the current stack size), " +
f"input 0 of {tx_bad_sig_txid} (wtxid {tx_bad_sig_wtxid}), spending {coin['txid']}:{coin['vout']}"
}])
Why this scored 24/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.