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

Function test_bwatch_reorg_2_blocks

tests/test_plugin.py:5393–5451  ·  view source on GitHub ↗

Test bwatch handles a 2-block reorg correctly

(node_factory, bitcoind)

Source from the content-addressed store, hash-verified

5391
5392@pytest.mark.slow_test
5393def test_bwatch_reorg_2_blocks(node_factory, bitcoind):
5394 """Test bwatch handles a 2-block reorg correctly"""
5395 l1 = node_factory.get_node(options=BWATCH_OPTS)
5396
5397 # Wait for bwatch to initialize
5398 wait_bwatch_caught_up(l1)
5399
5400 # Mine some blocks
5401 bitcoind.generate_block(5)
5402 expected_height = bitcoind.rpc.getblockcount()
5403 l1.daemon.wait_for_log(rf'Added block {expected_height} to history')
5404
5405 # Get the hash of block to reorg from (2 blocks back)
5406 height = bitcoind.rpc.getblockcount()
5407 old_block1_hash = bitcoind.rpc.getblockhash(height - 1)
5408 old_block2_hash = bitcoind.rpc.getblockhash(height)
5409 common_ancestor_hash = bitcoind.rpc.getblockhash(height - 2)
5410
5411 # Invalidate to cause 2-block reorg
5412 bitcoind.rpc.invalidateblock(old_block1_hash)
5413
5414 # Mine longer chain
5415 bitcoind.generate_block(4)
5416 time.sleep(2)
5417
5418 # bwatch should detect and handle the reorg
5419 l1.daemon.wait_for_log(r'Reorg detected', timeout=60)
5420 # Wait for bwatch to finish processing the new chain
5421 l1.daemon.wait_for_log(r'No block change')
5422
5423 # Verify bwatch's block history matches bitcoind's new chain
5424 new_height = bitcoind.rpc.getblockcount()
5425
5426 # Check that bwatch has correct number of blocks (from its start height, not genesis)
5427 initial_height = 101 # regtest starts at this height
5428 expected_blocks = new_height - initial_height + 1
5429
5430 # Wait for datastore to be fully updated
5431 wait_for(lambda: len(l1.rpc.listdatastore(['bwatch', 'block_history'])['datastore']) == expected_blocks, timeout=60)
5432
5433 ds = l1.rpc.listdatastore(['bwatch', 'block_history'])
5434
5435 # Verify the common ancestor is still present with correct hash
5436 ancestor_entry = next((e for e in ds['datastore']
5437 if e['key'][-1] == f"{height - 2:010d}"), None)
5438 assert ancestor_entry is not None
5439 assert reverse_bitcoin_hash(common_ancestor_hash) in str(ancestor_entry['hex'])
5440
5441 # Verify the old block hashes are not in datastore
5442 for entry in ds['datastore']:
5443 assert reverse_bitcoin_hash(old_block1_hash) not in str(entry['hex'])
5444 assert reverse_bitcoin_hash(old_block2_hash) not in str(entry['hex'])
5445
5446 # Verify the new tip matches bitcoind
5447 new_tip_hash = bitcoind.rpc.getblockhash(new_height)
5448 tip_entry = next((e for e in ds['datastore']
5449 if e['key'][-1] == f"{new_height:010d}"), None)
5450 assert tip_entry is not None

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