Changeset View
Changeset View
Standalone View
Standalone View
qa/rpc-tests/invalidateblock.py
Show All 15 Lines | class InvalidateTest(BitcoinTestFramework): | ||||
def __init__(self): | def __init__(self): | ||||
super().__init__() | super().__init__() | ||||
self.setup_clean_chain = True | self.setup_clean_chain = True | ||||
self.num_nodes = 3 | self.num_nodes = 3 | ||||
def setup_network(self): | def setup_network(self): | ||||
self.nodes = [] | self.nodes = [] | ||||
self.is_network_split = False | self.is_network_split = False | ||||
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"])) | self.nodes.append(start_node(0, self.options.tmpdir)) | ||||
self.nodes.append(start_node(1, self.options.tmpdir, ["-debug"])) | self.nodes.append(start_node(1, self.options.tmpdir)) | ||||
self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"])) | self.nodes.append(start_node(2, self.options.tmpdir)) | ||||
def run_test(self): | def run_test(self): | ||||
print( | self.log.info( | ||||
"Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:") | "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:") | ||||
print("Mine 4 blocks on Node 0") | self.log.info("Mine 4 blocks on Node 0") | ||||
self.nodes[0].generate(4) | self.nodes[0].generate(4) | ||||
assert(self.nodes[0].getblockcount() == 4) | assert(self.nodes[0].getblockcount() == 4) | ||||
besthash = self.nodes[0].getbestblockhash() | besthash = self.nodes[0].getbestblockhash() | ||||
print("Mine competing 6 blocks on Node 1") | self.log.info("Mine competing 6 blocks on Node 1") | ||||
self.nodes[1].generate(6) | self.nodes[1].generate(6) | ||||
assert(self.nodes[1].getblockcount() == 6) | assert(self.nodes[1].getblockcount() == 6) | ||||
print("Connect nodes to force a reorg") | self.log.info("Connect nodes to force a reorg") | ||||
connect_nodes_bi(self.nodes, 0, 1) | connect_nodes_bi(self.nodes, 0, 1) | ||||
sync_blocks(self.nodes[0:2]) | sync_blocks(self.nodes[0:2]) | ||||
assert(self.nodes[0].getblockcount() == 6) | assert(self.nodes[0].getblockcount() == 6) | ||||
badhash = self.nodes[1].getblockhash(2) | badhash = self.nodes[1].getblockhash(2) | ||||
print( | self.log.info( | ||||
"Invalidate block 2 on node 0 and verify we reorg to node 0's original chain") | "Invalidate block 2 on node 0 and verify we reorg to node 0's original chain") | ||||
self.nodes[0].invalidateblock(badhash) | self.nodes[0].invalidateblock(badhash) | ||||
newheight = self.nodes[0].getblockcount() | newheight = self.nodes[0].getblockcount() | ||||
newhash = self.nodes[0].getbestblockhash() | newhash = self.nodes[0].getbestblockhash() | ||||
if (newheight != 4 or newhash != besthash): | if (newheight != 4 or newhash != besthash): | ||||
raise AssertionError( | raise AssertionError( | ||||
"Wrong tip for node0, hash %s, height %d" % (newhash, newheight)) | "Wrong tip for node0, hash %s, height %d" % (newhash, newheight)) | ||||
print("\nMake sure we won't reorg to a lower work chain:") | self.log.info("\nMake sure we won't reorg to a lower work chain:") | ||||
connect_nodes_bi(self.nodes, 1, 2) | connect_nodes_bi(self.nodes, 1, 2) | ||||
print("Sync node 2 to node 1 so both have 6 blocks") | self.log.info("Sync node 2 to node 1 so both have 6 blocks") | ||||
sync_blocks(self.nodes[1:3]) | sync_blocks(self.nodes[1:3]) | ||||
assert(self.nodes[2].getblockcount() == 6) | assert(self.nodes[2].getblockcount() == 6) | ||||
print("Invalidate block 5 on node 1 so its tip is now at 4") | self.log.info("Invalidate block 5 on node 1 so its tip is now at 4") | ||||
self.nodes[1].invalidateblock(self.nodes[1].getblockhash(5)) | self.nodes[1].invalidateblock(self.nodes[1].getblockhash(5)) | ||||
assert(self.nodes[1].getblockcount() == 4) | assert(self.nodes[1].getblockcount() == 4) | ||||
print("Invalidate block 3 on node 2, so its tip is now 2") | self.log.info("Invalidate block 3 on node 2, so its tip is now 2") | ||||
self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3)) | self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3)) | ||||
assert(self.nodes[2].getblockcount() == 2) | assert(self.nodes[2].getblockcount() == 2) | ||||
print("..and then mine a block") | self.log.info("..and then mine a block") | ||||
self.nodes[2].generate(1) | self.nodes[2].generate(1) | ||||
print("Verify all nodes are at the right height") | self.log.info("Verify all nodes are at the right height") | ||||
time.sleep(5) | time.sleep(5) | ||||
for i in range(3): | assert_equal(self.nodes[2].getblockcount(), 3) | ||||
print(i, self.nodes[i].getblockcount()) | assert_equal(self.nodes[0].getblockcount(), 4) | ||||
assert(self.nodes[2].getblockcount() == 3) | |||||
assert(self.nodes[0].getblockcount() == 4) | |||||
node1height = self.nodes[1].getblockcount() | node1height = self.nodes[1].getblockcount() | ||||
if node1height < 4: | if node1height < 4: | ||||
raise AssertionError( | raise AssertionError( | ||||
"Node 1 reorged to a lower height: %d" % node1height) | "Node 1 reorged to a lower height: %d" % node1height) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
InvalidateTest().main() | InvalidateTest().main() |