Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc-replay-protection.py
Show First 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | def next_block(self, number): | ||||
# Do PoW, which is cheap on regnet | # Do PoW, which is cheap on regnet | ||||
block.solve() | block.solve() | ||||
self.tip = block | self.tip = block | ||||
self.block_heights[block.sha256] = height | self.block_heights[block.sha256] = height | ||||
assert number not in self.blocks | assert number not in self.blocks | ||||
self.blocks[number] = block | self.blocks[number] = block | ||||
return block | return block | ||||
def set_tip(self, number: int): | |||||
""" | |||||
Move the tip back to a previous block. | |||||
""" | |||||
self.tip = self.blocks[number] | |||||
def run_test(self): | def run_test(self): | ||||
node = self.nodes[0] | node = self.nodes[0] | ||||
node.add_p2p_connection(P2PDataStore()) | node.add_p2p_connection(P2PDataStore()) | ||||
node.setmocktime(REPLAY_PROTECTION_START_TIME) | node.setmocktime(REPLAY_PROTECTION_START_TIME) | ||||
self.genesis_hash = int(node.getbestblockhash(), 16) | self.genesis_hash = int(node.getbestblockhash(), 16) | ||||
self.block_heights[self.genesis_hash] = 0 | self.block_heights[self.genesis_hash] = 0 | ||||
spendable_outputs = [] | spendable_outputs = [] | ||||
# save the current tip so it can be spent by a later block | # save the current tip so it can be spent by a later block | ||||
def save_spendable_output(): | def save_spendable_output(): | ||||
spendable_outputs.append(self.tip) | spendable_outputs.append(self.tip) | ||||
# get an output that we previously marked as spendable | # get an output that we previously marked as spendable | ||||
def get_spendable_output(): | def get_spendable_output(): | ||||
return PreviousSpendableOutput(spendable_outputs.pop(0).vtx[0], 0) | return PreviousSpendableOutput(spendable_outputs.pop(0).vtx[0], 0) | ||||
# move the tip back to a previous block | |||||
def tip(number): | |||||
self.tip = self.blocks[number] | |||||
# adds transactions to the block and updates state | # adds transactions to the block and updates state | ||||
def update_block(block_number, new_transactions): | def update_block(block_number, new_transactions): | ||||
block = self.blocks[block_number] | block = self.blocks[block_number] | ||||
block.vtx.extend(new_transactions) | block.vtx.extend(new_transactions) | ||||
old_sha256 = block.sha256 | old_sha256 = block.sha256 | ||||
make_conform_to_ctor(block) | make_conform_to_ctor(block) | ||||
block.hashMerkleRoot = block.calc_merkle_root() | block.hashMerkleRoot = block.calc_merkle_root() | ||||
block.solve() | block.solve() | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
# And block containing them are rejected as well. | # And block containing them are rejected as well. | ||||
block(2) | block(2) | ||||
update_block(2, replay_txns) | update_block(2, replay_txns) | ||||
node.p2p.send_blocks_and_test( | node.p2p.send_blocks_and_test( | ||||
[self.tip], node, success=False, reject_reason='blk-bad-inputs') | [self.tip], node, success=False, reject_reason='blk-bad-inputs') | ||||
# Rewind bad block | # Rewind bad block | ||||
tip(1) | self.set_tip(1) | ||||
# Create a block that would activate the replay protection. | # Create a block that would activate the replay protection. | ||||
bfork = block(5555) | bfork = block(5555) | ||||
bfork.nTime = REPLAY_PROTECTION_START_TIME - 1 | bfork.nTime = REPLAY_PROTECTION_START_TIME - 1 | ||||
update_block(5555, []) | update_block(5555, []) | ||||
node.p2p.send_blocks_and_test([self.tip], node) | node.p2p.send_blocks_and_test([self.tip], node) | ||||
activation_blocks = [] | activation_blocks = [] | ||||
Show All 12 Lines | def run_test(self): | ||||
node.sendrawtransaction, ToHex(replay_txns[1])) | node.sendrawtransaction, ToHex(replay_txns[1])) | ||||
block(3) | block(3) | ||||
update_block(3, replay_txns) | update_block(3, replay_txns) | ||||
node.p2p.send_blocks_and_test( | node.p2p.send_blocks_and_test( | ||||
[self.tip], node, success=False, reject_reason='blk-bad-inputs') | [self.tip], node, success=False, reject_reason='blk-bad-inputs') | ||||
# Rewind bad block | # Rewind bad block | ||||
tip(5104) | self.set_tip(5104) | ||||
# Send some non replay protected txns in the mempool to check | # Send some non replay protected txns in the mempool to check | ||||
# they get cleaned at activation. | # they get cleaned at activation. | ||||
txns = create_fund_and_spend_tx(out[2]) | txns = create_fund_and_spend_tx(out[2]) | ||||
send_transaction_to_mempool(txns[0]) | send_transaction_to_mempool(txns[0]) | ||||
tx_id = send_transaction_to_mempool(txns[1]) | tx_id = send_transaction_to_mempool(txns[1]) | ||||
# Activate the replay protection | # Activate the replay protection | ||||
Show All 16 Lines | def run_test(self): | ||||
# They also cannot be mined | # They also cannot be mined | ||||
block(4) | block(4) | ||||
update_block(4, txns) | update_block(4, txns) | ||||
node.p2p.send_blocks_and_test( | node.p2p.send_blocks_and_test( | ||||
[self.tip], node, success=False, reject_reason='blk-bad-inputs') | [self.tip], node, success=False, reject_reason='blk-bad-inputs') | ||||
# Rewind bad block | # Rewind bad block | ||||
tip(5556) | self.set_tip(5556) | ||||
# The replay protected transaction is now valid | # The replay protected transaction is now valid | ||||
replay_tx0_id = send_transaction_to_mempool(replay_txns[0]) | replay_tx0_id = send_transaction_to_mempool(replay_txns[0]) | ||||
replay_tx1_id = send_transaction_to_mempool(replay_txns[1]) | replay_tx1_id = send_transaction_to_mempool(replay_txns[1]) | ||||
# Make sure the transaction are ready to be mined. | # Make sure the transaction are ready to be mined. | ||||
tmpl = node.getblocktemplate() | tmpl = node.getblocktemplate() | ||||
▲ Show 20 Lines • Show All 45 Lines • Show Last 20 Lines |