MCPcopy Create free account
hub / github.com/ElementsProject/lightning / test_bwatch_block_history_rollback

Function test_bwatch_block_history_rollback

tests/test_plugin.py:5558–5626  ·  view source on GitHub ↗

Test that block history is correctly rolled back during reorg

(node_factory, bitcoind)

Source from the content-addressed store, hash-verified

5556
5557@pytest.mark.slow_test
5558def test_bwatch_block_history_rollback(node_factory, bitcoind):
5559 """Test that block history is correctly rolled back during reorg"""
5560 l1 = node_factory.get_node(options=BWATCH_OPTS)
5561
5562 # Wait for bwatch to fully sync
5563 wait_bwatch_caught_up(l1)
5564
5565 # Mine blocks
5566 bitcoind.generate_block(5)
5567 expected_height = bitcoind.rpc.getblockcount()
5568
5569 # Wait for bwatch to process the new blocks
5570 l1.daemon.wait_for_log(rf'Added block {expected_height} to history', timeout=60)
5571
5572 # Check block history exists in datastore
5573 initial_height = 101 # regtest starts at this height
5574 expected_initial_blocks = expected_height - initial_height + 1
5575 wait_for(lambda: len(l1.rpc.listdatastore(['bwatch', 'block_history'])['datastore']) == expected_initial_blocks, timeout=60)
5576
5577 ds = l1.rpc.listdatastore(['bwatch', 'block_history'])
5578 initial_count = len(ds['datastore'])
5579 # bwatch stores blocks from its start height (101), so we should have at least 5 new blocks
5580 assert initial_count >= 5
5581
5582 # Cause a 3-block reorg - save hashes of blocks that will be reorged
5583 height = bitcoind.rpc.getblockcount()
5584 common_ancestor_height = height - 3
5585 common_ancestor_hash = bitcoind.rpc.getblockhash(common_ancestor_height)
5586 old_hashes = [bitcoind.rpc.getblockhash(h)
5587 for h in range(common_ancestor_height + 1, height + 1)]
5588
5589 reorg_from_hash = bitcoind.rpc.getblockhash(
5590 common_ancestor_height + 1)
5591 bitcoind.rpc.invalidateblock(reorg_from_hash)
5592 bitcoind.generate_block(5)
5593
5594 # Verify reorg was handled
5595 l1.daemon.wait_for_log(r'Reorg detected', timeout=60)
5596 # Wait for bwatch to finish syncing to the new chain
5597 l1.daemon.wait_for_log(r'No block change')
5598
5599 # Verify block history after reorg
5600 ds = l1.rpc.listdatastore(['bwatch', 'block_history'])
5601 new_height = bitcoind.rpc.getblockcount()
5602
5603 # Should have correct number of blocks (from its start height, not genesis)
5604 initial_height = 101 # regtest starts at this height
5605 expected_blocks = new_height - initial_height + 1
5606 assert len(ds['datastore']) == expected_blocks
5607
5608 # Verify the common ancestor is still present with correct hash
5609 ancestor_entry = next((e for e in ds['datastore']
5610 if e['key'][-1] == f"{common_ancestor_height:010d}"),
5611 None)
5612 assert ancestor_entry is not None
5613 assert reverse_bitcoin_hash(common_ancestor_hash) in str(ancestor_entry['hex'])
5614
5615 # Verify old block hashes are not present

Callers

nothing calls this directly

Calls 8

wait_forFunction · 0.90
wait_bwatch_caught_upFunction · 0.85
nextFunction · 0.85
reverse_bitcoin_hashFunction · 0.85
generate_blockMethod · 0.80
wait_for_logMethod · 0.80
listdatastoreMethod · 0.80
get_nodeMethod · 0.45

Tested by

no test coverage detected