Changeset View
Changeset View
Standalone View
Standalone View
test/functional/p2p_unrequested_blocks.py
Show First 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
assert tip_entry_found | assert tip_entry_found | ||||
# But this block should be accepted by node since it has equal work. | # But this block should be accepted by node since it has equal work. | ||||
self.nodes[0].getblock(block_h2f.hash) | self.nodes[0].getblock(block_h2f.hash) | ||||
self.log.info("Second height 2 block accepted, but not reorg'ed to") | self.log.info("Second height 2 block accepted, but not reorg'ed to") | ||||
# 4b. Now send another block that builds on the forking chain. | # 4b. Now send another block that builds on the forking chain. | ||||
block_h3 = create_block( | block_h3 = create_block( | ||||
block_h2f.sha256, create_coinbase(3), block_h2f.nTime+1) | block_h2f.sha256, create_coinbase(3), block_h2f.nTime + 1) | ||||
block_h3.solve() | block_h3.solve() | ||||
test_node.send_message(msg_block(block_h3)) | test_node.send_message(msg_block(block_h3)) | ||||
test_node.sync_with_ping() | test_node.sync_with_ping() | ||||
# Since the earlier block was not processed by node, the new block | # Since the earlier block was not processed by node, the new block | ||||
# can't be fully validated. | # can't be fully validated. | ||||
tip_entry_found = False | tip_entry_found = False | ||||
for x in self.nodes[0].getchaintips(): | for x in self.nodes[0].getchaintips(): | ||||
if x['hash'] == block_h3.hash: | if x['hash'] == block_h3.hash: | ||||
assert_equal(x['status'], "headers-only") | assert_equal(x['status'], "headers-only") | ||||
tip_entry_found = True | tip_entry_found = True | ||||
assert tip_entry_found | assert tip_entry_found | ||||
self.nodes[0].getblock(block_h3.hash) | self.nodes[0].getblock(block_h3.hash) | ||||
# But this block should be accepted by node since it has more work. | # But this block should be accepted by node since it has more work. | ||||
self.nodes[0].getblock(block_h3.hash) | self.nodes[0].getblock(block_h3.hash) | ||||
self.log.info("Unrequested more-work block accepted") | self.log.info("Unrequested more-work block accepted") | ||||
# 4c. Now mine 288 more blocks and deliver; all should be processed but | # 4c. Now mine 288 more blocks and deliver; all should be processed but | ||||
# the last (height-too-high) on node (as long as it is not missing any headers) | # the last (height-too-high) on node (as long as it is not missing any headers) | ||||
tip = block_h3 | tip = block_h3 | ||||
all_blocks = [] | all_blocks = [] | ||||
for i in range(288): | for i in range(288): | ||||
next_block = create_block( | next_block = create_block( | ||||
tip.sha256, create_coinbase(i + 4), tip.nTime+1) | tip.sha256, create_coinbase(i + 4), tip.nTime + 1) | ||||
next_block.solve() | next_block.solve() | ||||
all_blocks.append(next_block) | all_blocks.append(next_block) | ||||
tip = next_block | tip = next_block | ||||
# Now send the block at height 5 and check that it wasn't accepted (missing header) | # Now send the block at height 5 and check that it wasn't accepted (missing header) | ||||
test_node.send_message(msg_block(all_blocks[1])) | test_node.send_message(msg_block(all_blocks[1])) | ||||
test_node.sync_with_ping() | test_node.sync_with_ping() | ||||
assert_raises_rpc_error(-5, "Block not found", | assert_raises_rpc_error(-5, "Block not found", | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
assert_raises_rpc_error(-1, "Block not found on disk", | assert_raises_rpc_error(-1, "Block not found on disk", | ||||
self.nodes[0].getblock, all_blocks[287].hash) | self.nodes[0].getblock, all_blocks[287].hash) | ||||
self.log.info( | self.log.info( | ||||
"Successfully reorged to longer chain from non-whitelisted peer") | "Successfully reorged to longer chain from non-whitelisted peer") | ||||
# 8. Create a chain which is invalid at a height longer than the | # 8. Create a chain which is invalid at a height longer than the | ||||
# current chain, but which has more blocks on top of that | # current chain, but which has more blocks on top of that | ||||
block_289f = create_block( | block_289f = create_block( | ||||
all_blocks[284].sha256, create_coinbase(289), all_blocks[284].nTime+1) | all_blocks[284].sha256, create_coinbase(289), all_blocks[284].nTime + 1) | ||||
block_289f.solve() | block_289f.solve() | ||||
block_290f = create_block( | block_290f = create_block( | ||||
block_289f.sha256, create_coinbase(290), block_289f.nTime+1) | block_289f.sha256, create_coinbase(290), block_289f.nTime + 1) | ||||
block_290f.solve() | block_290f.solve() | ||||
block_291 = create_block( | block_291 = create_block( | ||||
block_290f.sha256, create_coinbase(291), block_290f.nTime+1) | block_290f.sha256, create_coinbase(291), block_290f.nTime + 1) | ||||
# block_291 spends a coinbase below maturity! | # block_291 spends a coinbase below maturity! | ||||
block_291.vtx.append(create_transaction( | block_291.vtx.append(create_transaction( | ||||
block_290f.vtx[0], 0, b"42", 1)) | block_290f.vtx[0], 0, b"42", 1)) | ||||
block_291.hashMerkleRoot = block_291.calc_merkle_root() | block_291.hashMerkleRoot = block_291.calc_merkle_root() | ||||
block_291.solve() | block_291.solve() | ||||
block_292 = create_block( | block_292 = create_block( | ||||
block_291.sha256, create_coinbase(292), block_291.nTime+1) | block_291.sha256, create_coinbase(292), block_291.nTime + 1) | ||||
block_292.solve() | block_292.solve() | ||||
# Now send all the headers on the chain and enough blocks to trigger reorg | # Now send all the headers on the chain and enough blocks to trigger reorg | ||||
headers_message = msg_headers() | headers_message = msg_headers() | ||||
headers_message.headers.append(CBlockHeader(block_289f)) | headers_message.headers.append(CBlockHeader(block_289f)) | ||||
headers_message.headers.append(CBlockHeader(block_290f)) | headers_message.headers.append(CBlockHeader(block_290f)) | ||||
headers_message.headers.append(CBlockHeader(block_291)) | headers_message.headers.append(CBlockHeader(block_291)) | ||||
headers_message.headers.append(CBlockHeader(block_292)) | headers_message.headers.append(CBlockHeader(block_292)) | ||||
Show All 33 Lines | def run_test(self): | ||||
# We should have failed reorg and switched back to 290 (but have block 291) | # We should have failed reorg and switched back to 290 (but have block 291) | ||||
assert_equal(self.nodes[0].getblockcount(), 290) | assert_equal(self.nodes[0].getblockcount(), 290) | ||||
assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash) | assert_equal(self.nodes[0].getbestblockhash(), all_blocks[286].hash) | ||||
assert_equal(self.nodes[0].getblock( | assert_equal(self.nodes[0].getblock( | ||||
block_291.hash)["confirmations"], -1) | block_291.hash)["confirmations"], -1) | ||||
# Now send a new header on the invalid chain, indicating we're forked off, and expect to get disconnected | # Now send a new header on the invalid chain, indicating we're forked off, and expect to get disconnected | ||||
block_293 = create_block( | block_293 = create_block( | ||||
block_292.sha256, create_coinbase(293), block_292.nTime+1) | block_292.sha256, create_coinbase(293), block_292.nTime + 1) | ||||
block_293.solve() | block_293.solve() | ||||
headers_message = msg_headers() | headers_message = msg_headers() | ||||
headers_message.headers.append(CBlockHeader(block_293)) | headers_message.headers.append(CBlockHeader(block_293)) | ||||
test_node.send_message(headers_message) | test_node.send_message(headers_message) | ||||
test_node.wait_for_disconnect() | test_node.wait_for_disconnect() | ||||
# 9. Connect node1 to node0 and ensure it is able to sync | # 9. Connect node1 to node0 and ensure it is able to sync | ||||
connect_nodes(self.nodes[0], self.nodes[1]) | connect_nodes(self.nodes[0], self.nodes[1]) | ||||
sync_blocks([self.nodes[0], self.nodes[1]]) | sync_blocks([self.nodes[0], self.nodes[1]]) | ||||
self.log.info("Successfully synced nodes 1 and 0") | self.log.info("Successfully synced nodes 1 and 0") | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
AcceptBlockTest().main() | AcceptBlockTest().main() |