Changeset View
Changeset View
Standalone View
Standalone View
test/functional/p2p_invalid_block.py
Show All 28 Lines | class InvalidBlockRequestTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.num_nodes = 1 | self.num_nodes = 1 | ||||
self.setup_clean_chain = True | self.setup_clean_chain = True | ||||
self.extra_args = [["-whitelist=noban@127.0.0.1"]] | self.extra_args = [["-whitelist=noban@127.0.0.1"]] | ||||
def run_test(self): | def run_test(self): | ||||
# Add p2p connection to node0 | # Add p2p connection to node0 | ||||
node = self.nodes[0] # convenience reference to the node | node = self.nodes[0] # convenience reference to the node | ||||
node.add_p2p_connection(P2PDataStore()) | peer = node.add_p2p_connection(P2PDataStore()) | ||||
best_block = node.getblock(node.getbestblockhash()) | best_block = node.getblock(node.getbestblockhash()) | ||||
tip = int(node.getbestblockhash(), 16) | tip = int(node.getbestblockhash(), 16) | ||||
height = best_block["height"] + 1 | height = best_block["height"] + 1 | ||||
block_time = best_block["time"] + 1 | block_time = best_block["time"] + 1 | ||||
self.log.info("Create a new block with an anyone-can-spend coinbase") | self.log.info("Create a new block with an anyone-can-spend coinbase") | ||||
height = 1 | height = 1 | ||||
block = create_block(tip, create_coinbase(height), block_time) | block = create_block(tip, create_coinbase(height), block_time) | ||||
block.solve() | block.solve() | ||||
# Save the coinbase for later | # Save the coinbase for later | ||||
block1 = block | block1 = block | ||||
tip = block.sha256 | tip = block.sha256 | ||||
node.p2p.send_blocks_and_test([block1], node, success=True) | peer.send_blocks_and_test([block1], node, success=True) | ||||
self.log.info("Mature the block.") | self.log.info("Mature the block.") | ||||
node.generatetoaddress(100, node.get_deterministic_priv_key().address) | node.generatetoaddress(100, node.get_deterministic_priv_key().address) | ||||
best_block = node.getblock(node.getbestblockhash()) | best_block = node.getblock(node.getbestblockhash()) | ||||
tip = int(node.getbestblockhash(), 16) | tip = int(node.getbestblockhash(), 16) | ||||
height = best_block["height"] + 1 | height = best_block["height"] + 1 | ||||
block_time = best_block["time"] + 1 | block_time = best_block["time"] + 1 | ||||
Show All 26 Lines | def run_test(self): | ||||
block2_orig = copy.deepcopy(block2) | block2_orig = copy.deepcopy(block2) | ||||
# Mutate block 2 | # Mutate block 2 | ||||
block2.vtx.append(block2.vtx[2]) | block2.vtx.append(block2.vtx[2]) | ||||
assert_equal(block2.hashMerkleRoot, block2.calc_merkle_root()) | assert_equal(block2.hashMerkleRoot, block2.calc_merkle_root()) | ||||
assert_equal(orig_hash, block2.rehash()) | assert_equal(orig_hash, block2.rehash()) | ||||
assert block2_orig.vtx != block2.vtx | assert block2_orig.vtx != block2.vtx | ||||
node.p2p.send_blocks_and_test( | peer.send_blocks_and_test( | ||||
[block2], node, success=False, reject_reason='bad-txns-duplicate') | [block2], node, success=False, reject_reason='bad-txns-duplicate') | ||||
# Check transactions for duplicate inputs (CVE-2018-17144) | # Check transactions for duplicate inputs (CVE-2018-17144) | ||||
self.log.info("Test duplicate input block.") | self.log.info("Test duplicate input block.") | ||||
block2_dup = copy.deepcopy(block2_orig) | block2_dup = copy.deepcopy(block2_orig) | ||||
block2_dup.vtx[2].vin.append(block2_dup.vtx[2].vin[0]) | block2_dup.vtx[2].vin.append(block2_dup.vtx[2].vin[0]) | ||||
block2_dup.vtx[2].rehash() | block2_dup.vtx[2].rehash() | ||||
make_conform_to_ctor(block2_dup) | make_conform_to_ctor(block2_dup) | ||||
block2_dup.hashMerkleRoot = block2_dup.calc_merkle_root() | block2_dup.hashMerkleRoot = block2_dup.calc_merkle_root() | ||||
block2_dup.rehash() | block2_dup.rehash() | ||||
block2_dup.solve() | block2_dup.solve() | ||||
node.p2p.send_blocks_and_test( | peer.send_blocks_and_test( | ||||
[block2_dup], node, success=False, | [block2_dup], node, success=False, | ||||
reject_reason='bad-txns-inputs-duplicate') | reject_reason='bad-txns-inputs-duplicate') | ||||
self.log.info("Test very broken block.") | self.log.info("Test very broken block.") | ||||
block3 = create_block(tip, create_coinbase(height), block_time) | block3 = create_block(tip, create_coinbase(height), block_time) | ||||
block_time += 1 | block_time += 1 | ||||
block3.vtx[0].vout[0].nValue = 100 * COIN # Too high! | block3.vtx[0].vout[0].nValue = 100 * COIN # Too high! | ||||
block3.vtx[0].sha256 = None | block3.vtx[0].sha256 = None | ||||
block3.vtx[0].calc_sha256() | block3.vtx[0].calc_sha256() | ||||
block3.hashMerkleRoot = block3.calc_merkle_root() | block3.hashMerkleRoot = block3.calc_merkle_root() | ||||
block3.rehash() | block3.rehash() | ||||
block3.solve() | block3.solve() | ||||
node.p2p.send_blocks_and_test( | peer.send_blocks_and_test( | ||||
[block3], node, success=False, reject_reason='bad-cb-amount') | [block3], node, success=False, reject_reason='bad-cb-amount') | ||||
# Complete testing of CVE-2012-2459 by sending the original block. | # Complete testing of CVE-2012-2459 by sending the original block. | ||||
# It should be accepted even though it has the same hash as the mutated | # It should be accepted even though it has the same hash as the mutated | ||||
# one. | # one. | ||||
self.log.info("Test accepting original block after rejecting its" | self.log.info("Test accepting original block after rejecting its" | ||||
" mutated version.") | " mutated version.") | ||||
node.p2p.send_blocks_and_test([block2_orig], node, success=True, | peer.send_blocks_and_test([block2_orig], node, success=True, | ||||
timeout=5) | timeout=5) | ||||
# Update tip info | # Update tip info | ||||
height += 1 | height += 1 | ||||
block_time += 1 | block_time += 1 | ||||
tip = int(block2_orig.hash, 16) | tip = int(block2_orig.hash, 16) | ||||
# Complete testing of CVE-2018-17144, by checking for the inflation bug. | # Complete testing of CVE-2018-17144, by checking for the inflation bug. | ||||
# Create a block that spends the output of a tx in a previous block. | # Create a block that spends the output of a tx in a previous block. | ||||
block4 = create_block(tip, create_coinbase(height), block_time) | block4 = create_block(tip, create_coinbase(height), block_time) | ||||
tx3 = create_tx_with_script(tx2, 0, script_sig=b'\x51', | tx3 = create_tx_with_script(tx2, 0, script_sig=b'\x51', | ||||
amount=50 * COIN) | amount=50 * COIN) | ||||
# Duplicates input | # Duplicates input | ||||
tx3.vin.append(tx3.vin[0]) | tx3.vin.append(tx3.vin[0]) | ||||
tx3.rehash() | tx3.rehash() | ||||
block4.vtx.append(tx3) | block4.vtx.append(tx3) | ||||
make_conform_to_ctor(block4) | make_conform_to_ctor(block4) | ||||
block4.hashMerkleRoot = block4.calc_merkle_root() | block4.hashMerkleRoot = block4.calc_merkle_root() | ||||
block4.rehash() | block4.rehash() | ||||
block4.solve() | block4.solve() | ||||
self.log.info("Test inflation by duplicating input") | self.log.info("Test inflation by duplicating input") | ||||
node.p2p.send_blocks_and_test([block4], node, success=False, | peer.send_blocks_and_test([block4], node, success=False, | ||||
reject_reason='bad-txns-inputs-duplicate') | reject_reason='bad-txns-inputs-duplicate') | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
InvalidBlockRequestTest().main() | InvalidBlockRequestTest().main() |