test: repeat block malleability test with relayable block over P2P
Adds a functional test that repeats the existing witness nonce size malleability check using a block under MAX_BLOCK_WEIGHT so it can be relayed over the P2P network, addressing the TODO in test_block_malleability. Includes rejection check for 'bad-witness-nonce-size' and confirmation that a corrected block is accepted.
This commit is contained in:
1 parent
41642d43b3
commit
d0e1bbad01
1 file changed
+31
-1
@@ -82,6 +82,7 @@ from test_framework.script_util import (
|
|||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import (
|
from test_framework.util import (
|
||||||
assert_not_equal,
|
assert_not_equal,
|
||||||
|
assert_greater_than_or_equal,
|
||||||
assert_equal,
|
assert_equal,
|
||||||
assert_raises_rpc_error,
|
assert_raises_rpc_error,
|
||||||
ensure_for,
|
ensure_for,
|
||||||
@@ -822,7 +823,6 @@ class SegWitTest(BitcoinTestFramework):
|
|||||||
assert block.get_weight() > MAX_BLOCK_WEIGHT
|
assert block.get_weight() > MAX_BLOCK_WEIGHT
|
||||||
|
|
||||||
# We can't send over the p2p network, because this is too big to relay
|
# We can't send over the p2p network, because this is too big to relay
|
||||||
# TODO: repeat this test with a block that can be relayed
|
|
||||||
assert_equal('bad-witness-nonce-size', self.nodes[0].submitblock(block.serialize().hex()))
|
assert_equal('bad-witness-nonce-size', self.nodes[0].submitblock(block.serialize().hex()))
|
||||||
|
|
||||||
assert_not_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
|
assert_not_equal(self.nodes[0].getbestblockhash(), block.hash_hex)
|
||||||
@@ -833,6 +833,36 @@ class SegWitTest(BitcoinTestFramework):
|
|||||||
|
|
||||||
assert self.nodes[0].getbestblockhash() == block.hash_hex
|
assert self.nodes[0].getbestblockhash() == block.hash_hex
|
||||||
|
|
||||||
|
# Build a relayable-but-invalid block
|
||||||
|
relayable_block = self.build_next_block()
|
||||||
|
add_witness_commitment(relayable_block)
|
||||||
|
relayable_block.solve()
|
||||||
|
|
||||||
|
# Append extra witness data to the coinbase input that triggers the
|
||||||
|
# same validation rejection but keeps the block under the weight limit
|
||||||
|
# so it can be sent via P2P.
|
||||||
|
relayable_block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.append(b'a' * 100_000)
|
||||||
|
|
||||||
|
# Ensure it's relayable by weight
|
||||||
|
assert_greater_than_or_equal(MAX_BLOCK_WEIGHT, relayable_block.get_weight())
|
||||||
|
|
||||||
|
# Send over P2P and expect rejection for the same reason
|
||||||
|
test_witness_block(self.nodes[0], self.test_node, relayable_block,
|
||||||
|
accepted=False, reason='bad-witness-nonce-size')
|
||||||
|
|
||||||
|
# Node should still be on the previous tip
|
||||||
|
assert_not_equal(self.nodes[0].getbestblockhash(), relayable_block.hash_hex)
|
||||||
|
|
||||||
|
# Now fix the block by removing the extra witness data
|
||||||
|
relayable_block.vtx[0].wit.vtxinwit[0].scriptWitness.stack.pop()
|
||||||
|
|
||||||
|
# Confirm the block is still relayable by weight
|
||||||
|
assert relayable_block.get_weight() <= MAX_BLOCK_WEIGHT
|
||||||
|
|
||||||
|
# Send the corrected block and expect acceptance
|
||||||
|
test_witness_block(self.nodes[0], self.test_node, relayable_block, accepted=True)
|
||||||
|
assert_equal(self.nodes[0].getbestblockhash(), relayable_block.hash_hex)
|
||||||
|
|
||||||
# Now make sure that malleating the witness reserved value doesn't
|
# Now make sure that malleating the witness reserved value doesn't
|
||||||
# result in a block permanently marked bad.
|
# result in a block permanently marked bad.
|
||||||
block = self.build_next_block()
|
block = self.build_next_block()
|
||||||
|
|||||||
Reference in new issue
Block a user