@@ -608,6 +608,37 @@ pub(crate) async fn wait_for_tx<E: ElectrumApi>(electrs: &E, txid: Txid) {
608608 . await ;
609609}
610610
611+ /// Keep calling `sync_wallets()` until the node's chain tip catches up to
612+ /// bitcoind's current tip, or panic if it doesn't converge within the timeout.
613+ ///
614+ /// `generate_blocks_and_wait` only waits for electrsd to observe the new
615+ /// blocks, which races with CBF's Kyoto peer receiving them via P2P. Tests
616+ /// that assert on post-mining state right after mining can see CBF still
617+ /// stuck on the previous tip; polling here lets Kyoto catch up naturally.
618+ /// For non-CBF chain sources the condition is typically satisfied by the
619+ /// very first sync, so the overhead is negligible.
620+ pub ( crate ) async fn sync_node_to_bitcoind_tip ( node : & TestNode , bitcoind : & BitcoindClient ) {
621+ let target_height =
622+ bitcoind. get_blockchain_info ( ) . expect ( "failed to query bitcoind blockchain info" ) . blocks
623+ as u32 ;
624+ let mut delay = Duration :: from_millis ( 100 ) ;
625+ for _ in 0 ..30 {
626+ let _ = node. sync_wallets ( ) ;
627+ if node. status ( ) . current_best_block . height >= target_height {
628+ return ;
629+ }
630+ tokio:: time:: sleep ( delay) . await ;
631+ if delay < Duration :: from_secs ( 2 ) {
632+ delay = delay. mul_f32 ( 1.5 ) ;
633+ }
634+ }
635+ panic ! (
636+ "sync_node_to_bitcoind_tip: node did not reach height {} within timeout (stuck at {})" ,
637+ target_height,
638+ node. status( ) . current_best_block. height
639+ ) ;
640+ }
641+
611642pub ( crate ) async fn wait_for_outpoint_spend < E : ElectrumApi > ( electrs : & E , outpoint : OutPoint ) {
612643 let tx = electrs. transaction_get ( & outpoint. txid ) . unwrap ( ) ;
613644 let txout_script = tx. output . get ( outpoint. vout as usize ) . unwrap ( ) . clone ( ) . script_pubkey ;
@@ -1357,15 +1388,8 @@ pub(crate) async fn do_channel_full_cycle<E: ElectrumApi>(
13571388 wait_for_outpoint_spend ( electrsd, splice_in_txo) . await ;
13581389
13591390 generate_blocks_and_wait ( & bitcoind, electrsd, 1 ) . await ;
1360- node_a. sync_wallets ( ) . unwrap ( ) ;
1361- node_b. sync_wallets ( ) . unwrap ( ) ;
1362-
1363- // CBF needs a second sync: the first sync confirms the close tx in the
1364- // Lightning wallet, which may trigger new script registrations. The
1365- // second sync picks up blocks matching those new scripts for the
1366- // on-chain wallet.
1367- node_a. sync_wallets ( ) . unwrap ( ) ;
1368- node_b. sync_wallets ( ) . unwrap ( ) ;
1391+ sync_node_to_bitcoind_tip ( & node_a, bitcoind) . await ;
1392+ sync_node_to_bitcoind_tip ( & node_b, bitcoind) . await ;
13691393
13701394 if force_close {
13711395 // Check node_b properly sees all balances and sweeps them.
0 commit comments