diff --git a/test/functional/p2p_invalid_block.py b/test/functional/p2p_invalid_block.py --- a/test/functional/p2p_invalid_block.py +++ b/test/functional/p2p_invalid_block.py @@ -12,84 +12,64 @@ """ import copy -import time from test_framework.blocktools import ( create_block, create_coinbase, create_transaction, ) -from test_framework.comptool import RejectResult, TestInstance, TestManager from test_framework.messages import COIN -from test_framework.mininode import network_thread_start -from test_framework.test_framework import ComparisonTestFramework +from test_framework.mininode import network_thread_start, P2PDataStore +from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal -# Use the ComparisonTestFramework with 1 node: only use --testbinary. -class InvalidBlockRequestTest(ComparisonTestFramework): - - ''' Can either run this test as 1 node with expected answers, or two and compare them. - Change the "outcome" variable from each TestInstance object to only do the comparison. ''' - +class InvalidBlockRequestTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 1 self.setup_clean_chain = True + self.extra_args = [["-whitelist=127.0.0.1"]] def run_test(self): - test = TestManager(self, self.options.tmpdir) - test.add_all_connections(self.nodes) - self.tip = None - self.block_time = None - self.extra_args = [["-whitelist=127.0.0.1"]] + # Add p2p connection to node0 + node = self.nodes[0] # convenience reference to the node + node.add_p2p_connection(P2PDataStore()) network_thread_start() - test.run() + node.p2p.wait_for_verack() - def get_tests(self): - if self.tip is None: - self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) - self.block_time = int(time.time()) + 1 + best_block = node.getblock(node.getbestblockhash()) + tip = int(node.getbestblockhash(), 16) + height = best_block["height"] + 1 + block_time = best_block["time"] + 1 + + self.log.info("Create a new block with an anyone-can-spend coinbase") - ''' - Create a new block with an anyone-can-spend coinbase - ''' height = 1 - block = create_block( - self.tip, create_coinbase(height), self.block_time) - self.block_time += 1 + block = create_block(tip, create_coinbase(height), block_time) block.solve() - self.tip = block.sha256 - height += 1 - yield TestInstance([[block, True]]) + # Save the coinbase for later block1 = block + tip = block.sha256 + node.p2p.send_blocks_and_test([block1], node, True) + + self.log.info("Mature the block.") + node.generate(100) + + best_block = node.getblock(node.getbestblockhash()) + tip = int(node.getbestblockhash(), 16) + height = best_block["height"] + 1 + block_time = best_block["time"] + 1 - ''' - Now we need that block to mature so we can spend the coinbase. - ''' - test = TestInstance(sync_every_block=False) - for i in range(100): - block = create_block( - self.tip, create_coinbase(height), self.block_time) - block.solve() - self.tip = block.sha256 - self.block_time += 1 - test.blocks_and_transactions.append([block, True]) - height += 1 - yield test - - assert(block.sha256 == int(self.nodes[0].getbestblockhash(), 16)) - - ''' - Now we use merkle-root malleability to generate an invalid block with - same blockheader. - Manufacture a block with 3 transactions (coinbase, spend of prior - coinbase, spend of that spend). Duplicate the 3rd transaction to - leave merkle root and blockheader unchanged but invalidate the block. - ''' - block2 = create_block( - self.tip, create_coinbase(height), self.block_time) - self.block_time += 1 + # Use merkle-root malleability to generate an invalid block with + # same blockheader. + # Manufacture a block with 3 transactions (coinbase, spend of prior + # coinbase, spend of that spend). Duplicate the 3rd transaction to + # leave merkle root and blockheader unchanged but invalidate the block. + self.log.info("Test merkle root malleability.") + + block2 = create_block(tip, create_coinbase(height), block_time) + block_time += 1 # b'0x51' is OP_TRUE tx1 = create_transaction(block1.vtx[0], 0, b'', 50 * COIN) @@ -110,12 +90,8 @@ assert_equal(orig_hash, block2.rehash()) assert(block2_orig.vtx != block2.vtx) - self.tip = block2.sha256 - - yield TestInstance([[block2, RejectResult(16, b'bad-txns-duplicate')]]) - yield TestInstance([[block2_orig, True]]) - - height += 1 + node.p2p.send_blocks_and_test( + [block2], node, False, False, 16, b'bad-txns-duplicate') # Check transactions for duplicate inputs self.log.info("Test duplicate input block.") @@ -127,21 +103,22 @@ block2_orig.hashMerkleRoot = block2_orig.calc_merkle_root() block2_orig.rehash() block2_orig.solve() - yield TestInstance([[block2_orig, RejectResult(16, b'bad-txns-inputs-duplicate')]]) - - ''' - Make sure that a totally screwed up block is not valid. - ''' - block3 = create_block( - self.tip, create_coinbase(height), self.block_time) - self.block_time += 1 - block3.vtx[0].vout[0].nValue = 51 * COIN # Too high! + node.p2p.send_blocks_and_test( + [block2_orig], node, False, False, 16, b'bad-txns-inputs-duplicate') + + self.log.info("Test very broken block.") + + block3 = create_block(tip, create_coinbase(height), block_time) + block_time += 1 + block3.vtx[0].vout[0].nValue = 100 * COIN # Too high! block3.vtx[0].sha256 = None block3.vtx[0].calc_sha256() block3.hashMerkleRoot = block3.calc_merkle_root() block3.rehash() block3.solve() - yield TestInstance([[block3, RejectResult(16, b'bad-cb-amount')]]) + + node.p2p.send_blocks_and_test( + [block3], node, False, False, 16, b'bad-cb-amount') if __name__ == '__main__': diff --git a/test/functional/p2p_invalid_tx.py b/test/functional/p2p_invalid_tx.py --- a/test/functional/p2p_invalid_tx.py +++ b/test/functional/p2p_invalid_tx.py @@ -65,12 +65,10 @@ self.log.info("Create a new block with an anyone-can-spend coinbase.") height = 1 block = create_block(tip, create_coinbase(height), block_time) - block_time += 1 block.solve() # Save the coinbase for later block1 = block tip = block.sha256 - height += 1 node.p2p.send_blocks_and_test([block], node, success=True) self.log.info("Mature the block.")