Skip to content

Commit

Permalink
test: Adds block tiebreak over restarts tests
Browse files Browse the repository at this point in the history
Adds tests to make sure we are consistent on activating the same chain over
a node restart if two or more candidates have the same work when the node is shutdown
  • Loading branch information
sr-gi committed Mar 25, 2024
1 parent c7e663d commit e4cf8d0
Showing 1 changed file with 49 additions and 1 deletion.
50 changes: 49 additions & 1 deletion test/functional/feature_chain_tiebreaks.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def send_headers(node, blocks):
# announcement.
node.submitheader(hexdata=CBlockHeader(block).serialize().hex())

def run_test(self):
def test_chain_split_in_memory(self):
node = self.nodes[0]
# Add P2P connection to bitcoind
peer = node.add_p2p_connection(P2PDataStore())
Expand Down Expand Up @@ -99,5 +99,53 @@ def run_test(self):
# B7 is now active.
assert_equal(node.getbestblockhash(), blocks[7].hash)

# Invalidate blocks to start fresh on the next test
node.invalidateblock(blocks[0].hash)

def test_chain_split_from_disk(self):
node = self.nodes[0]
peer = node.add_p2p_connection(P2PDataStore())

self.log.info('Precomputing blocks')
#
# A1
# /
# G
# \
# A2
#
blocks = []

# Construct two blocks building from genesis.
start_height = node.getblockcount()
genesis_block = node.getblock(node.getblockhash(start_height))
prev_time = genesis_block["time"]

for i in range(0, 2):
blocks.append(create_block(
hashprev=int(genesis_block["hash"], 16),
tmpl={"height": start_height + 1,
# Make sure each block has a different hash.
"curtime": prev_time + i + 1,
}
))
blocks[-1].solve()

# Send blocks and test the last one is not connected
self.log.info('Send A1 and A2. Make sure than only the former connects')
peer.send_blocks_and_test([blocks[0]], node, success=True)
peer.send_blocks_and_test([blocks[1]], node, success=False)

self.log.info('Restart the node and check that the best tip before restarting matched the ones afterwards')
# Restart and check enough times to this to eventually fail if the logic is broken
for _ in range(10):
self.restart_node(0)
assert_equal(blocks[0].hash, node.getbestblockhash())

def run_test(self):
self.test_chain_split_in_memory()
self.test_chain_split_from_disk()


if __name__ == '__main__':
ChainTiebreaksTest().main()

0 comments on commit e4cf8d0

Please sign in to comment.