Skip to content

Commit 8ff90d9

Browse files
committed
Merge bitcoin/bitcoin#26291: Update MANDATORY_SCRIPT_VERIFY_FLAGS
1b09cc5 Make post-p2sh consensus rules mandatory for tx relay (Anthony Towns) 69c31bc doc, policy: Clarify comment on STANDARD_SCRIPT_VERIFY_FLAGS (Anthony Towns) Pull request description: The `MANDATORY_SCRIPT_VERIFY_FLAGS` constant was introduced in #3843 to distinguish between block consensus rules and relay standardness rules. However it was not actually used in the consensus code path: instead it only differentiates between the failure being reported as `TX_CONSENSUS` and `mandatory-script-verify-flag-failed` vs `TX_NOT_STANDARD` and `non-mandatory-script-verify-flag`. This updates the list of mandatory flags to include the post-p2sh soft forks that are enforced as consensus rules via `GetBlockScriptFlags()`. The effect of this change is that validation.cpp will report `TX_CONSENSUS` failures for txs that fail dersig/csv/cltv/nulldummy/witness/taproot checks, instead of `TX_NOT_STANDARD`, which in turn adds `Misbehaving(100)` via `MaybePunishNodeForTx` in `net_processing`. ACKs for top commit: Sjors: Code review ACK 1b09cc5 darosior: ACK 1b09cc5 achow101: ACK 1b09cc5 theStack: Concept and code-review ACK 1b09cc5 Tree-SHA512: d3e5868e8cece478f2e934956ba0c231d8bb9c2daefd0df1f817774e292049902cfc1d0cd76dbd2e7722627a93eab2d7046ff678199aac70a2b01642e69349f1
2 parents 33da5d0 + 1b09cc5 commit 8ff90d9

File tree

7 files changed

+45
-44
lines changed

7 files changed

+45
-44
lines changed

src/policy/policy.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,30 +86,31 @@ static constexpr unsigned int EXTRA_DESCENDANT_TX_SIZE_LIMIT{10000};
8686
* Note that this does not affect consensus validity; see GetBlockScriptFlags()
8787
* for that.
8888
*/
89-
static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH;
89+
static constexpr unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS{SCRIPT_VERIFY_P2SH |
90+
SCRIPT_VERIFY_DERSIG |
91+
SCRIPT_VERIFY_NULLDUMMY |
92+
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY |
93+
SCRIPT_VERIFY_CHECKSEQUENCEVERIFY |
94+
SCRIPT_VERIFY_WITNESS |
95+
SCRIPT_VERIFY_TAPROOT};
9096

9197
/**
9298
* Standard script verification flags that standard transactions will comply
9399
* with. However we do not ban/disconnect nodes that forward txs violating
94-
* these rules, for better forwards and backwards compatability.
100+
* the additional (non-mandatory) rules here, to improve forwards and
101+
* backwards compatability.
95102
*/
96103
static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS{MANDATORY_SCRIPT_VERIFY_FLAGS |
97-
SCRIPT_VERIFY_DERSIG |
98104
SCRIPT_VERIFY_STRICTENC |
99105
SCRIPT_VERIFY_MINIMALDATA |
100-
SCRIPT_VERIFY_NULLDUMMY |
101106
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS |
102107
SCRIPT_VERIFY_CLEANSTACK |
103108
SCRIPT_VERIFY_MINIMALIF |
104109
SCRIPT_VERIFY_NULLFAIL |
105-
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY |
106-
SCRIPT_VERIFY_CHECKSEQUENCEVERIFY |
107110
SCRIPT_VERIFY_LOW_S |
108-
SCRIPT_VERIFY_WITNESS |
109111
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM |
110112
SCRIPT_VERIFY_WITNESS_PUBKEYTYPE |
111113
SCRIPT_VERIFY_CONST_SCRIPTCODE |
112-
SCRIPT_VERIFY_TAPROOT |
113114
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION |
114115
SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS |
115116
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE};

test/functional/feature_cltv.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ def run_test(self):
151151
cltv_invalidate(spendtx, i)
152152

153153
expected_cltv_reject_reason = [
154-
"non-mandatory-script-verify-flag (Operation not valid with the current stack size)",
155-
"non-mandatory-script-verify-flag (Negative locktime)",
156-
"non-mandatory-script-verify-flag (Locktime requirement not satisfied)",
157-
"non-mandatory-script-verify-flag (Locktime requirement not satisfied)",
158-
"non-mandatory-script-verify-flag (Locktime requirement not satisfied)",
154+
"mandatory-script-verify-flag-failed (Operation not valid with the current stack size)",
155+
"mandatory-script-verify-flag-failed (Negative locktime)",
156+
"mandatory-script-verify-flag-failed (Locktime requirement not satisfied)",
157+
"mandatory-script-verify-flag-failed (Locktime requirement not satisfied)",
158+
"mandatory-script-verify-flag-failed (Locktime requirement not satisfied)",
159159
][i]
160160
# First we show that this tx is valid except for CLTV by getting it
161161
# rejected from the mempool for exactly that reason.

test/functional/feature_csv_activation.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,9 @@ def run_test(self):
407407

408408
# -1 OP_CSV tx and (empty stack) OP_CSV tx should fail
409409
self.send_blocks([self.create_test_block([bip112tx_special_v1])], success=False,
410-
reject_reason='non-mandatory-script-verify-flag (Negative locktime)')
410+
reject_reason='mandatory-script-verify-flag-failed (Negative locktime)')
411411
self.send_blocks([self.create_test_block([bip112tx_emptystack_v1])], success=False,
412-
reject_reason='non-mandatory-script-verify-flag (Operation not valid with the current stack size)')
412+
reject_reason='mandatory-script-verify-flag-failed (Operation not valid with the current stack size)')
413413
# If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 1 txs should still pass
414414

415415
success_txs = [tx['tx'] for tx in bip112txs_vary_OP_CSV_v1 if tx['sdf']]
@@ -424,15 +424,15 @@ def run_test(self):
424424
fail_txs += [tx['tx'] for tx in bip112txs_vary_OP_CSV_9_v1 if not tx['sdf']]
425425
for tx in fail_txs:
426426
self.send_blocks([self.create_test_block([tx])], success=False,
427-
reject_reason='non-mandatory-script-verify-flag (Locktime requirement not satisfied)')
427+
reject_reason='mandatory-script-verify-flag-failed (Locktime requirement not satisfied)')
428428

429429
self.log.info("Test version 2 txs")
430430

431431
# -1 OP_CSV tx and (empty stack) OP_CSV tx should fail
432432
self.send_blocks([self.create_test_block([bip112tx_special_v2])], success=False,
433-
reject_reason='non-mandatory-script-verify-flag (Negative locktime)')
433+
reject_reason='mandatory-script-verify-flag-failed (Negative locktime)')
434434
self.send_blocks([self.create_test_block([bip112tx_emptystack_v2])], success=False,
435-
reject_reason='non-mandatory-script-verify-flag (Operation not valid with the current stack size)')
435+
reject_reason='mandatory-script-verify-flag-failed (Operation not valid with the current stack size)')
436436

437437
# If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 2 txs should pass (all sequence locks are met)
438438
success_txs = [tx['tx'] for tx in bip112txs_vary_OP_CSV_v2 if tx['sdf']]
@@ -448,20 +448,20 @@ def run_test(self):
448448
fail_txs += [tx['tx'] for tx in bip112txs_vary_OP_CSV_9_v2 if not tx['sdf']]
449449
for tx in fail_txs:
450450
self.send_blocks([self.create_test_block([tx])], success=False,
451-
reject_reason='non-mandatory-script-verify-flag (Locktime requirement not satisfied)')
451+
reject_reason='mandatory-script-verify-flag-failed (Locktime requirement not satisfied)')
452452

453453
# If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in nSequence, tx should fail
454454
fail_txs = [tx['tx'] for tx in bip112txs_vary_nSequence_v2 if tx['sdf']]
455455
for tx in fail_txs:
456456
self.send_blocks([self.create_test_block([tx])], success=False,
457-
reject_reason='non-mandatory-script-verify-flag (Locktime requirement not satisfied)')
457+
reject_reason='mandatory-script-verify-flag-failed (Locktime requirement not satisfied)')
458458

459459
# If sequencelock types mismatch, tx should fail
460460
fail_txs = [tx['tx'] for tx in bip112txs_vary_nSequence_v2 if not tx['sdf'] and tx['stf']]
461461
fail_txs += [tx['tx'] for tx in bip112txs_vary_OP_CSV_v2 if not tx['sdf'] and tx['stf']]
462462
for tx in fail_txs:
463463
self.send_blocks([self.create_test_block([tx])], success=False,
464-
reject_reason='non-mandatory-script-verify-flag (Locktime requirement not satisfied)')
464+
reject_reason='mandatory-script-verify-flag-failed (Locktime requirement not satisfied)')
465465

466466
# Remaining txs should pass, just test masking works properly
467467
success_txs = [tx['tx'] for tx in bip112txs_vary_nSequence_v2 if not tx['sdf'] and not tx['stf']]

test/functional/feature_dersig.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def run_test(self):
120120
'txid': spendtx.hash,
121121
'wtxid': spendtx.getwtxid(),
122122
'allowed': False,
123-
'reject-reason': 'non-mandatory-script-verify-flag (Non-canonical DER signature)',
123+
'reject-reason': 'mandatory-script-verify-flag-failed (Non-canonical DER signature)',
124124
}],
125125
self.nodes[0].testmempoolaccept(rawtxs=[spendtx.serialize().hex()], maxfeerate=0),
126126
)
@@ -130,7 +130,7 @@ def run_test(self):
130130
block.hashMerkleRoot = block.calc_merkle_root()
131131
block.solve()
132132

133-
with self.nodes[0].assert_debug_log(expected_msgs=[f'CheckInputScripts on {block.vtx[-1].hash} failed with non-mandatory-script-verify-flag (Non-canonical DER signature)']):
133+
with self.nodes[0].assert_debug_log(expected_msgs=[f'CheckInputScripts on {block.vtx[-1].hash} failed with mandatory-script-verify-flag-failed (Non-canonical DER signature)']):
134134
peer.send_and_ping(msg_block(block))
135135
assert_equal(int(self.nodes[0].getbestblockhash(), 16), tip)
136136
peer.sync_with_ping()

test/functional/feature_nulldummy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from test_framework.wallet import getnewdestination
3838
from test_framework.wallet_util import generate_keypair
3939

40-
NULLDUMMY_ERROR = "non-mandatory-script-verify-flag (Dummy CHECKMULTISIG argument must be zero)"
40+
NULLDUMMY_ERROR = "mandatory-script-verify-flag-failed (Dummy CHECKMULTISIG argument must be zero)"
4141

4242

4343
def invalidate_nulldummy_tx(tx):

test/functional/feature_segwit.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,13 @@ def run_test(self):
215215

216216
self.log.info("Verify default node can't accept txs with missing witness")
217217
# unsigned, no scriptsig
218-
self.fail_accept(self.nodes[0], "non-mandatory-script-verify-flag (Witness program hash mismatch)", wit_ids[NODE_0][P2WPKH][0], sign=False)
219-
self.fail_accept(self.nodes[0], "non-mandatory-script-verify-flag (Witness program was passed an empty witness)", wit_ids[NODE_0][P2WSH][0], sign=False)
218+
self.fail_accept(self.nodes[0], "mandatory-script-verify-flag-failed (Witness program hash mismatch)", wit_ids[NODE_0][P2WPKH][0], sign=False)
219+
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)
220220
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)
221221
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)
222222
# unsigned with redeem script
223-
self.fail_accept(self.nodes[0], "non-mandatory-script-verify-flag (Witness program hash mismatch)", p2sh_ids[NODE_0][P2WPKH][0], sign=False, redeem_script=witness_script(False, self.pubkey[0]))
224-
self.fail_accept(self.nodes[0], "non-mandatory-script-verify-flag (Witness program was passed an empty witness)", p2sh_ids[NODE_0][P2WSH][0], sign=False, redeem_script=witness_script(True, self.pubkey[0]))
223+
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]))
224+
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]))
225225

226226
self.log.info("Verify block and transaction serialization rpcs return differing serializations depending on rpc serialization flag")
227227
assert self.nodes[2].getblock(blockhash, False) != self.nodes[0].getblock(blockhash, False)
@@ -244,10 +244,10 @@ def run_test(self):
244244
assert_equal(witnesses[0], '00' * 32)
245245

246246
self.log.info("Verify witness txs without witness data are invalid after the fork")
247-
self.fail_accept(self.nodes[2], 'non-mandatory-script-verify-flag (Witness program hash mismatch)', wit_ids[NODE_2][P2WPKH][2], sign=False)
248-
self.fail_accept(self.nodes[2], 'non-mandatory-script-verify-flag (Witness program was passed an empty witness)', wit_ids[NODE_2][P2WSH][2], sign=False)
249-
self.fail_accept(self.nodes[2], 'non-mandatory-script-verify-flag (Witness program hash mismatch)', p2sh_ids[NODE_2][P2WPKH][2], sign=False, redeem_script=witness_script(False, self.pubkey[2]))
250-
self.fail_accept(self.nodes[2], 'non-mandatory-script-verify-flag (Witness program was passed an empty witness)', p2sh_ids[NODE_2][P2WSH][2], sign=False, redeem_script=witness_script(True, self.pubkey[2]))
247+
self.fail_accept(self.nodes[2], 'mandatory-script-verify-flag-failed (Witness program hash mismatch)', wit_ids[NODE_2][P2WPKH][2], sign=False)
248+
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)
249+
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]))
250+
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]))
251251

252252
self.log.info("Verify default node can now use witness txs")
253253
self.success_mine(self.nodes[0], wit_ids[NODE_0][P2WPKH][0], True)

0 commit comments

Comments
 (0)