@@ -2,17 +2,74 @@ mod common;
22use std:: collections:: HashMap ;
33
44use bitcoin:: Amount ;
5+ use electrsd:: corepc_node:: mtype:: ChainTipsStatus ;
56use ldk_node:: payment:: { PaymentDirection , PaymentKind } ;
67use ldk_node:: { Event , LightningBalance , PendingSweepBalance } ;
78use proptest:: prelude:: prop;
89use proptest:: proptest;
10+ use serde_json:: json;
911
1012use crate :: common:: {
1113 expect_event, exponential_backoff_poll, generate_blocks_and_wait, invalidate_blocks,
1214 open_channel, premine_and_distribute_funds, random_chain_source, random_config,
13- setup_bitcoind_and_electrsd, setup_node, wait_for_outpoint_spend, wait_for_tx,
15+ setup_bitcoind_and_electrsd, setup_node, wait_for_outpoint_spend, wait_for_tx, TestChainSource ,
1416} ;
1517
18+ #[ test]
19+ fn bitcoind_rest_follows_valid_reorg ( ) {
20+ let rt = tokio:: runtime:: Builder :: new_multi_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) ;
21+ rt. block_on ( async {
22+ let ( bitcoind, electrsd) = setup_bitcoind_and_electrsd ( ) ;
23+ let node = setup_node ( & TestChainSource :: BitcoindRestSync ( & bitcoind) , random_config ( ) ) ;
24+ let ( bitcoind, electrs) = ( & bitcoind. client , & electrsd. client ) ;
25+
26+ generate_blocks_and_wait ( bitcoind, electrs, 3 ) . await ;
27+ node. sync_wallets ( ) . unwrap ( ) ;
28+ let original_tip = node. status ( ) . current_best_block ;
29+ let fork_block_hash = bitcoind
30+ . get_block_hash ( ( original_tip. height - 1 ) as u64 )
31+ . expect ( "failed to get fork block hash" )
32+ . block_hash ( )
33+ . expect ( "fork block hash should be present" ) ;
34+
35+ invalidate_blocks ( bitcoind, 2 ) ;
36+ generate_blocks_and_wait ( bitcoind, electrs, 3 ) . await ;
37+ let replacement_tip_hash =
38+ bitcoind. best_block_hash ( ) . expect ( "failed to get replacement tip" ) ;
39+ let replacement_tip_height =
40+ bitcoind. get_blockchain_info ( ) . expect ( "failed to get replacement tip height" ) . blocks
41+ as u32 ;
42+
43+ let _: serde_json:: Value = bitcoind
44+ . call ( "reconsiderblock" , & [ json ! ( fork_block_hash) ] )
45+ . expect ( "failed to reconsider original branch" ) ;
46+ let chain_tips = bitcoind
47+ . get_chain_tips ( )
48+ . expect ( "failed to get chain tips" )
49+ . into_model ( )
50+ . expect ( "failed to parse chain tips" )
51+ . 0 ;
52+ assert ! ( chain_tips. iter( ) . any( |tip| {
53+ tip. hash == original_tip. block_hash && tip. status == ChainTipsStatus :: ValidFork
54+ } ) ) ;
55+ assert ! ( chain_tips. iter( ) . any( |tip| {
56+ tip. hash == replacement_tip_hash && tip. status == ChainTipsStatus :: Active
57+ } ) ) ;
58+
59+ node. sync_wallets ( )
60+ . expect ( "REST-backed node did not follow Bitcoin Core's replacement chain" ) ;
61+ let synced_tip = node. status ( ) . current_best_block ;
62+ assert_eq ! (
63+ synced_tip. block_hash, replacement_tip_hash,
64+ "REST-backed node did not follow Bitcoin Core's replacement chain"
65+ ) ;
66+ assert_eq ! (
67+ synced_tip. height, replacement_tip_height,
68+ "REST-backed node did not follow Bitcoin Core's replacement chain"
69+ ) ;
70+ } )
71+ }
72+
1673async fn wait_for_pending_sweep_balance < F > (
1774 node : & ldk_node:: Node , mut matches_balance : F ,
1875) -> PendingSweepBalance
0 commit comments