Changeset View
Changeset View
Standalone View
Standalone View
test/functional/abc-replay-protection.py
Show First 20 Lines • Show All 168 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
bytes(bytearray([SIGHASH_ALL | SIGHASH_FORKID])) | bytes(bytearray([SIGHASH_ALL | SIGHASH_FORKID])) | ||||
txspend.vin[0].scriptSig = CScript([sig]) | txspend.vin[0].scriptSig = CScript([sig]) | ||||
txspend.rehash() | txspend.rehash() | ||||
return [txfund, txspend] | return [txfund, txspend] | ||||
def send_transaction_to_mempool(tx): | def send_transaction_to_mempool(tx): | ||||
tx_id = node.sendrawtransaction(ToHex(tx)) | tx_id = node.sendrawtransaction(ToHex(tx)) | ||||
assert(tx_id in set(node.getrawmempool())) | assert tx_id in set(node.getrawmempool()) | ||||
return tx_id | return tx_id | ||||
# Before the fork, no replay protection required to get in the mempool. | # Before the fork, no replay protection required to get in the mempool. | ||||
txns = create_fund_and_spend_tx(out[0]) | txns = create_fund_and_spend_tx(out[0]) | ||||
send_transaction_to_mempool(txns[0]) | send_transaction_to_mempool(txns[0]) | ||||
send_transaction_to_mempool(txns[1]) | send_transaction_to_mempool(txns[1]) | ||||
# And txns get mined in a block properly. | # And txns get mined in a block properly. | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
node.p2p.send_blocks_and_test([self.tip], node) | node.p2p.send_blocks_and_test([self.tip], node) | ||||
# Check we just activated the replay protection | # Check we just activated the replay protection | ||||
assert_equal(node.getblockheader(node.getbestblockhash())['mediantime'], | assert_equal(node.getblockheader(node.getbestblockhash())['mediantime'], | ||||
REPLAY_PROTECTION_START_TIME) | REPLAY_PROTECTION_START_TIME) | ||||
# Non replay protected transactions are not valid anymore, | # Non replay protected transactions are not valid anymore, | ||||
# so they should be removed from the mempool. | # so they should be removed from the mempool. | ||||
assert(tx_id not in set(node.getrawmempool())) | assert tx_id not in set(node.getrawmempool()) | ||||
# Good old transactions are now invalid. | # Good old transactions are now invalid. | ||||
send_transaction_to_mempool(txns[0]) | send_transaction_to_mempool(txns[0]) | ||||
assert_raises_rpc_error(-26, RPC_INVALID_SIGNATURE_ERROR, | assert_raises_rpc_error(-26, RPC_INVALID_SIGNATURE_ERROR, | ||||
node.sendrawtransaction, ToHex(txns[1])) | node.sendrawtransaction, ToHex(txns[1])) | ||||
# They also cannot be mined | # They also cannot be mined | ||||
block(4) | block(4) | ||||
Show All 16 Lines | def run_test(self): | ||||
for txn in tmpl['transactions']: | for txn in tmpl['transactions']: | ||||
txid = txn['txid'] | txid = txn['txid'] | ||||
if txid == replay_tx0_id: | if txid == replay_tx0_id: | ||||
found_id0 = True | found_id0 = True | ||||
elif txid == replay_tx1_id: | elif txid == replay_tx1_id: | ||||
found_id1 = True | found_id1 = True | ||||
assert(found_id0 and found_id1) | assert found_id0 and found_id1 | ||||
# And the mempool is still in good shape. | # And the mempool is still in good shape. | ||||
assert(replay_tx0_id in set(node.getrawmempool())) | assert replay_tx0_id in set(node.getrawmempool()) | ||||
assert(replay_tx1_id in set(node.getrawmempool())) | assert replay_tx1_id in set(node.getrawmempool()) | ||||
# They also can also be mined | # They also can also be mined | ||||
block(5) | block(5) | ||||
update_block(5, replay_txns) | update_block(5, replay_txns) | ||||
node.p2p.send_blocks_and_test([self.tip], node) | node.p2p.send_blocks_and_test([self.tip], node) | ||||
# Ok, now we check if a reorg work properly across the activation. | # Ok, now we check if a reorg work properly across the activation. | ||||
postforkblockid = node.getbestblockhash() | postforkblockid = node.getbestblockhash() | ||||
node.invalidateblock(postforkblockid) | node.invalidateblock(postforkblockid) | ||||
assert(replay_tx0_id in set(node.getrawmempool())) | assert replay_tx0_id in set(node.getrawmempool()) | ||||
assert(replay_tx1_id in set(node.getrawmempool())) | assert replay_tx1_id in set(node.getrawmempool()) | ||||
# Deactivating replay protection. | # Deactivating replay protection. | ||||
forkblockid = node.getbestblockhash() | forkblockid = node.getbestblockhash() | ||||
node.invalidateblock(forkblockid) | node.invalidateblock(forkblockid) | ||||
# The funding tx is not evicted from the mempool, since it's valid in | # The funding tx is not evicted from the mempool, since it's valid in | ||||
# both sides of the fork | # both sides of the fork | ||||
assert(replay_tx0_id in set(node.getrawmempool())) | assert replay_tx0_id in set(node.getrawmempool()) | ||||
assert(replay_tx1_id not in set(node.getrawmempool())) | assert replay_tx1_id not in set(node.getrawmempool()) | ||||
# Check that we also do it properly on deeper reorg. | # Check that we also do it properly on deeper reorg. | ||||
node.reconsiderblock(forkblockid) | node.reconsiderblock(forkblockid) | ||||
node.reconsiderblock(postforkblockid) | node.reconsiderblock(postforkblockid) | ||||
node.invalidateblock(forkblockid) | node.invalidateblock(forkblockid) | ||||
assert(replay_tx0_id in set(node.getrawmempool())) | assert replay_tx0_id in set(node.getrawmempool()) | ||||
assert(replay_tx1_id not in set(node.getrawmempool())) | assert replay_tx1_id not in set(node.getrawmempool()) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
ReplayProtectionTest().main() | ReplayProtectionTest().main() |