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

Function test_bwatch_reorg_long_chain

tests/test_plugin.py:5454–5515  ·  view source on GitHub ↗

Test bwatch handles a longer reorg (5+ blocks)

(node_factory, bitcoind)

Source from the content-addressed store, hash-verified

5452
5453
5454def test_bwatch_reorg_long_chain(node_factory, bitcoind):
5455 """Test bwatch handles a longer reorg (5+ blocks)"""
5456 l1 = node_factory.get_node(options=BWATCH_OPTS)
5457
5458 # Wait for bwatch to initialize and sync to initial tip
5459 wait_bwatch_caught_up(l1)
5460
5461 # Mine 10 blocks and wait for bwatch to fully catch up
5462 bitcoind.generate_block(10)
5463 expected_height = bitcoind.rpc.getblockcount()
5464 l1.daemon.wait_for_log(rf'Added block {expected_height} to history')
5465
5466 # Reorg 5 blocks - save hashes of blocks that will be reorged out
5467 height = bitcoind.rpc.getblockcount()
5468 common_ancestor_height = height - 5
5469 common_ancestor_hash = bitcoind.rpc.getblockhash(common_ancestor_height)
5470 old_hashes = [bitcoind.rpc.getblockhash(h)
5471 for h in range(common_ancestor_height + 1, height + 1)]
5472
5473 reorg_from_hash = bitcoind.rpc.getblockhash(
5474 common_ancestor_height + 1)
5475 bitcoind.rpc.invalidateblock(reorg_from_hash)
5476
5477 # Mine longer replacement chain
5478 bitcoind.generate_block(8)
5479 time.sleep(3)
5480
5481 # Should handle the deep reorg
5482 l1.daemon.wait_for_log(r'Reorg detected')
5483
5484 # Verify bwatch's block history matches bitcoind's new chain
5485 new_height = bitcoind.rpc.getblockcount()
5486
5487 # Wait for bwatch to fully sync to the new chain height
5488 # bwatch stores blocks from initial height (101), not genesis
5489 initial_height = 101 # regtest starts at this height
5490 expected_blocks = new_height - initial_height + 1
5491 wait_for(lambda: len(l1.rpc.listdatastore(['bwatch', 'block_history'])['datastore']) == expected_blocks)
5492
5493 ds = l1.rpc.listdatastore(['bwatch', 'block_history'])
5494
5495 # Check that bwatch has correct number of blocks
5496 assert len(ds['datastore']) == expected_blocks
5497
5498 # Verify the common ancestor is still present with correct hash
5499 ancestor_entry = next((e for e in ds['datastore']
5500 if e['key'][-1] == f"{common_ancestor_height:010d}"),
5501 None)
5502 assert ancestor_entry is not None
5503 assert reverse_bitcoin_hash(common_ancestor_hash) in str(ancestor_entry['hex'])
5504
5505 # Verify none of the old block hashes are in datastore
5506 for entry in ds['datastore']:
5507 for old_hash in old_hashes:
5508 assert reverse_bitcoin_hash(old_hash) not in str(entry['hex'])
5509
5510 # Verify the new tip matches bitcoind
5511 new_tip_hash = bitcoind.rpc.getblockhash(new_height)

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