mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-11 21:20:39 +02:00
Merge bitcoin/bitcoin#35164: test: cover P2SH sigop counting in test_witness_sigops
d180b891a2test: add mixed P2SH/witness sigop accounting (Lőrinc)6e60c362bctest: add P2SH sigop counting coverage (Musa Haruna) Pull request description: Add test coverage for sigop counting in P2SH spends in `test_witness_sigops()`, addressing the existing TODO. The new cases mirror the existing P2WSH sigop tests by constructing transactions that: - remain below the block sigop limit (accepted), - exceed the limit (rejected with bad-blk-sigops) Since P2SH sigops are accounted as legacy sigops, the expected sigop cost accounts for the 4× legacy weighting applied during consensus validation. The added coverage verifies the enforcement of the block sigop limit for both witness and P2SH spends, including mixed P2SH/witness transactions. **Acknowledgement:** During review ([comment](https://github.com/bitcoin/bitcoin/pull/35164#pullrequestreview-4769420630)), **l0rinc** demonstrated, using mutation testing on his branch [here](https://github.com/l0rinc/bitcoin/pull/248), that the original test suite would not detect two consensus sigop undercounting bugs. Those experiments helped validate the coverage added by this PR and motivated the inclusion of the mixed P2SH/witness regression test. ACKs for top commit: l0rinc: reACKd180b891a2Bicaru20: ACKd180b891a2sedited: ACKd180b891a2Tree-SHA512: 795923f56316c3cad4d02a572ed6486a0f3f62bd524fb162d2bcd884108485974e96f38c08b5ff0a8659feecfc208c8d7e93dde2b9e0517c70f6343c2063d9b5
This commit is contained in:
@@ -29,6 +29,7 @@ from test_framework.messages import (
|
||||
MSG_WTX,
|
||||
NODE_NETWORK,
|
||||
NODE_WITNESS,
|
||||
WITNESS_SCALE_FACTOR,
|
||||
msg_no_witness_block,
|
||||
msg_getdata,
|
||||
msg_headers,
|
||||
@@ -1872,6 +1873,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||
# sig ops
|
||||
outputs = (MAX_SIGOP_COST // sigops_per_script) + 2
|
||||
extra_sigops_available = MAX_SIGOP_COST % sigops_per_script
|
||||
p2sh_outputs = MAX_SIGOP_COST // (sigops_per_script * WITNESS_SCALE_FACTOR) + 1
|
||||
|
||||
# We chose the number of checkmultisigs/checksigs to make this work:
|
||||
assert extra_sigops_available < 100 # steer clear of MAX_OPS_PER_SCRIPT
|
||||
@@ -1895,6 +1897,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||
tx.vout.append(CTxOut(split_value, script_pubkey))
|
||||
tx.vout[-2].scriptPubKey = script_pubkey_toomany
|
||||
tx.vout[-1].scriptPubKey = script_pubkey_justright
|
||||
tx.vout += [CTxOut(0, script_to_p2sh_script(witness_script)) for _ in range(p2sh_outputs)]
|
||||
|
||||
block_1 = self.build_next_block()
|
||||
self.update_witness_block_with_transactions(block_1, [tx])
|
||||
@@ -1923,7 +1926,7 @@ class SegWitTest(BitcoinTestFramework):
|
||||
tx2.vout.append(CTxOut(0, script_pubkey_checksigs))
|
||||
tx2.vin.pop()
|
||||
tx2.wit.vtxinwit.pop()
|
||||
tx2.vout[0].nValue -= tx.vout[-2].nValue
|
||||
tx2.vout[0].nValue -= tx.vout[outputs - 2].nValue
|
||||
block_3 = self.build_next_block()
|
||||
self.update_witness_block_with_transactions(block_3, [tx2])
|
||||
test_witness_block(self.nodes[0], self.test_node, block_3, accepted=False, reason='bad-blk-sigops')
|
||||
@@ -1949,7 +1952,20 @@ class SegWitTest(BitcoinTestFramework):
|
||||
self.update_witness_block_with_transactions(block_5, [tx2])
|
||||
test_witness_block(self.nodes[0], self.test_node, block_5, accepted=True)
|
||||
|
||||
# TODO: test p2sh sigop counting
|
||||
p2sh_tx = CTransaction()
|
||||
p2sh_tx.vin = [CTxIn(COutPoint(tx.txid_int, outputs + i), CScript([witness_script])) for i in range(p2sh_outputs)]
|
||||
p2sh_tx.vout.append(CTxOut(0, CScript([OP_TRUE])))
|
||||
block_6 = self.build_next_block()
|
||||
self.update_witness_block_with_transactions(block_6, [p2sh_tx])
|
||||
test_witness_block(self.nodes[0], self.test_node, block_6, accepted=False, reason='bad-blk-sigops')
|
||||
|
||||
# Add witness data to verify that the transaction's P2SH sigops are still counted.
|
||||
p2sh_tx.vin.append(CTxIn(COutPoint(tx.txid_int, outputs - 2), b""))
|
||||
p2sh_tx.wit.vtxinwit = [CTxInWitness() for _ in p2sh_tx.vin]
|
||||
p2sh_tx.wit.vtxinwit[-1].scriptWitness.stack = [witness_script_toomany]
|
||||
block_7 = self.build_next_block()
|
||||
self.update_witness_block_with_transactions(block_7, [p2sh_tx])
|
||||
test_witness_block(self.nodes[0], self.test_node, block_7, accepted=False, reason='bad-blk-sigops')
|
||||
|
||||
# Cleanup and prep for next test
|
||||
self.utxo.pop(0)
|
||||
|
||||
Reference in New Issue
Block a user