diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 8814980711..fffdb4409a 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -538,9 +538,9 @@ fn has_onchain_tx_type bool>(node: &TestNode, predica fn assert_any_node_has_onchain_tx_type bool + Copy>( nodes: &[(&str, &TestNode)], tx_type_name: &str, predicate: F, -) { +) -> Result<(), String> { if nodes.iter().any(|(_, node)| has_onchain_tx_type(node, predicate)) { - return; + return Ok(()); } let observed: Vec = nodes @@ -552,14 +552,14 @@ fn assert_any_node_has_onchain_tx_type bool + Copy>( }) }) .collect(); - panic!("Expected on-chain payment with tx_type {}; observed {:?}", tx_type_name, observed); + Err(format!("Expected on-chain payment with tx_type {}; observed {:?}", tx_type_name, observed)) } fn assert_all_nodes_have_onchain_tx_type bool + Copy>( nodes: &[(&str, &TestNode)], panic_msg: &str, tx_type_name: &str, predicate: F, -) { +) -> Result<(), String> { if nodes.iter().all(|(_, node)| has_onchain_tx_type(node, predicate)) { - return; + return Ok(()); } let observed: Vec = nodes @@ -571,10 +571,10 @@ fn assert_all_nodes_have_onchain_tx_type bool + Copy> }) }) .collect(); - panic!( + return Err(format!( "Expected {}nodes to have on-chain payment with tx_type {}; observed {:?}", panic_msg, tx_type_name, observed - ); + )); } async fn settle_force_close_balance( @@ -592,7 +592,12 @@ async fn settle_force_close_balance( assert_eq!(actual_counterparty_node_id, counterparty_node_id); let cur_height = node.status().current_best_block.height; let blocks_to_go = confirmation_height - cur_height; - generate_blocks_and_wait(bitcoind, electrsd, blocks_to_go as usize).await; + let new_height = + generate_blocks_and_wait(bitcoind, electrsd, blocks_to_go as usize).await; + wait_for_node_tip(node, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(peer_node, new_height) + .await + .expect("node hasn't synced to the tip"); node.sync_wallets().unwrap(); peer_node.sync_wallets().unwrap(); }, @@ -607,7 +612,9 @@ async fn settle_force_close_balance( if node.list_balances().lightning_balances.is_empty() { break; } - generate_blocks_and_wait(bitcoind, electrsd, 1).await; + let new_height = generate_blocks_and_wait(bitcoind, electrsd, 1).await; + wait_for_node_tip(node, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(peer_node, new_height).await.expect("node hasn't synced to the tip"); node.sync_wallets().unwrap(); peer_node.sync_wallets().unwrap(); } @@ -616,8 +623,14 @@ async fn settle_force_close_balance( assert!(balances.lightning_balances.is_empty(), "Unexpected balance state: {:?}", balances); assert_eq!(balances.pending_balances_from_channel_closures.len(), 1); match balances.pending_balances_from_channel_closures[0] { - PendingSweepBalance::BroadcastAwaitingConfirmation { .. } => { - generate_blocks_and_wait(bitcoind, electrsd, 1).await; + PendingSweepBalance::BroadcastAwaitingConfirmation { latest_spending_txid, .. } => { + // The balance flips as soon as the sweeper generates the transaction, before it has + // been relayed to bitcoind. Make sure it is in the mempool so the next block + // includes it. + wait_for_tx(electrsd, latest_spending_txid).await; + let new_height = generate_blocks_and_wait(bitcoind, electrsd, 1).await; + wait_for_node_tip(node, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(peer_node, new_height).await.expect("node hasn't synced to the tip"); node.sync_wallets().unwrap(); peer_node.sync_wallets().unwrap(); @@ -632,7 +645,9 @@ async fn settle_force_close_balance( _ => panic!("Unexpected balance state!"), } - generate_blocks_and_wait(bitcoind, electrsd, 5).await; + let new_height = generate_blocks_and_wait(bitcoind, electrsd, 5).await; + wait_for_node_tip(node, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(peer_node, new_height).await.expect("node hasn't synced to the tip"); node.sync_wallets().unwrap(); peer_node.sync_wallets().unwrap(); } @@ -878,7 +893,7 @@ pub(crate) fn setup_node(chain_source: &TestChainSource, config: TestConfig) -> pub(crate) async fn generate_blocks_and_wait( bitcoind: &BitcoindClient, electrs: &E, num: usize, -) { +) -> usize { let _ = bitcoind.create_wallet("ldk_node_test"); let _ = bitcoind.load_wallet("ldk_node_test"); print!("Generating {} blocks...", num); @@ -887,9 +902,11 @@ pub(crate) async fn generate_blocks_and_wait( let address = bitcoind.new_address().expect("failed to get new address"); // TODO: expect this Result once the WouldBlock issue is resolved upstream. let _block_hashes_res = bitcoind.generate_to_address(num, &address); - wait_for_block(bitcoind, electrs, cur_height as usize + num).await; + let new_height = cur_height as usize + num; + wait_for_block(bitcoind, electrs, new_height).await; print!(" Done!"); println!("\n"); + return new_height; } pub(crate) fn invalidate_blocks(bitcoind: &BitcoindClient, num_blocks: usize) { @@ -918,14 +935,16 @@ pub(crate) async fn wait_for_block( } bitcoind.get_block_hash(min_height as u64).ok()?.block_hash().ok() }) - .await; + .await + .expect("reached max tries"); // A height-only wait can return the old header during a same-height reorg. Require the // replacement hash so callers cannot sync against the stale chain by mistake. exponential_backoff_poll(|| { let header = electrs.block_header(min_height).ok()?; (header.block_hash() == expected_block_hash).then_some(()) }) - .await; + .await + .expect("reached max tries"); } pub(crate) async fn wait_for_tx(electrs: &E, txid: Txid) { @@ -937,7 +956,8 @@ pub(crate) async fn wait_for_tx(electrs: &E, txid: Txid) { electrs.ping().unwrap(); electrs.transaction_get(&txid).ok() }) - .await; + .await + .expect("reached max tries"); } pub(crate) async fn wait_for_outpoint_spend(electrs: &E, outpoint: OutPoint) { @@ -954,7 +974,8 @@ pub(crate) async fn wait_for_outpoint_spend(electrs: &E, outpoin }); is_spent.then_some(()) }) - .await; + .await + .expect("reached max tries"); } /// Polls the channel from `source_node` to `counterparty_node` until it reports `is_usable` @@ -988,7 +1009,17 @@ pub(crate) async fn wait_for_channel_ready_to_send( ); } -pub(crate) async fn exponential_backoff_poll(mut poll: F) -> T +pub(crate) async fn wait_for_node_tip(node: &Node, height: usize) -> Option<()> { + // Pull-based chain sources (Esplora, Electrum) only advance the tip when a sync runs, so + // trigger one on every try instead of relying on the slow background interval. + exponential_backoff_poll(|| { + node.sync_wallets().unwrap(); + (node.status().current_best_block.height as usize >= height).then_some(()) + }) + .await +} + +pub(crate) async fn exponential_backoff_poll(mut poll: F) -> Option where F: FnMut() -> Option, { @@ -996,14 +1027,16 @@ where let mut tries = 0; loop { match poll() { - Some(data) => break data, + Some(data) => return Some(data), None if delay.as_millis() < 512 => { delay = delay.mul_f32(2.0); }, None => {}, } - assert!(tries < 20, "Reached max tries."); + if tries >= 20 { + return None; + } tries += 1; tokio::time::sleep(delay).await; } @@ -1011,11 +1044,11 @@ where pub(crate) async fn premine_and_distribute_funds( bitcoind: &BitcoindClient, electrs: &E, addrs: Vec
, amount: Amount, -) { +) -> usize { premine_blocks(bitcoind, electrs).await; distribute_funds_unconfirmed(bitcoind, electrs, addrs, amount).await; - generate_blocks_and_wait(bitcoind, electrs, 1).await; + generate_blocks_and_wait(bitcoind, electrs, 1).await } pub(crate) async fn premine_blocks(bitcoind: &BitcoindClient, electrs: &E) { @@ -1227,13 +1260,15 @@ pub(crate) async fn do_channel_full_cycle( let premine_amount_sat = if expect_anchor_channel { 2_125_000 } else { 2_100_000 }; - premine_and_distribute_funds( + let new_height = premine_and_distribute_funds( &bitcoind, electrsd, vec![addr_a, addr_b], Amount::from_sat(premine_amount_sat), ) .await; + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, premine_amount_sat); @@ -1307,7 +1342,9 @@ pub(crate) async fn do_channel_full_cycle( wait_for_tx(electrsd, funding_txo_a.txid).await; if !allow_0conf { - generate_blocks_and_wait(&bitcoind, electrsd, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind, electrsd, 6).await; + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); } node_a.sync_wallets().unwrap(); @@ -1648,7 +1685,9 @@ pub(crate) async fn do_channel_full_cycle( ); // Mine a block to give time for the HTLC to resolve - generate_blocks_and_wait(&bitcoind, electrsd, 1).await; + let new_height = generate_blocks_and_wait(&bitcoind, electrsd, 1).await; + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); println!("\nB splices out to pay A"); let addr_a = node_a.onchain_payment().new_address().unwrap(); @@ -1660,7 +1699,9 @@ pub(crate) async fn do_channel_full_cycle( let splice_out_txo = expect_splice_negotiated_event!(node_b, node_a.node_id()); wait_for_tx(electrsd, splice_out_txo.txid).await; - generate_blocks_and_wait(&bitcoind, electrsd, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind, electrsd, 6).await; + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); @@ -1682,7 +1723,9 @@ pub(crate) async fn do_channel_full_cycle( let splice_in_txo = expect_splice_negotiated_event!(node_a, node_b.node_id()); wait_for_tx(electrsd, splice_in_txo.txid).await; - generate_blocks_and_wait(&bitcoind, electrsd, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind, electrsd, 6).await; + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); @@ -1758,7 +1801,9 @@ pub(crate) async fn do_channel_full_cycle( wait_for_outpoint_spend(electrsd, splice_in_txo).await; - generate_blocks_and_wait(&bitcoind, electrsd, 1).await; + let new_height = generate_blocks_and_wait(&bitcoind, electrsd, 1).await; + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); @@ -1803,7 +1848,10 @@ pub(crate) async fn do_channel_full_cycle( assert_eq!(node_a_blocks_to_go, node_b_blocks_to_go); - generate_blocks_and_wait(&bitcoind, electrsd, node_a_blocks_to_go as usize).await; + let new_height = + generate_blocks_and_wait(&bitcoind, electrsd, node_a_blocks_to_go as usize).await; + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); @@ -1825,19 +1873,22 @@ pub(crate) async fn do_channel_full_cycle( "no ", "UnilateralClose", |tx_type| !matches!(tx_type, TransactionType::UnilateralClose { .. }), - ); + ) + .unwrap(); assert_any_node_has_onchain_tx_type( &[("node_a", &node_a), ("node_b", &node_b)], "Sweep", |tx_type| matches!(tx_type, TransactionType::Sweep { .. }), - ); + ) + .unwrap(); } else { assert_all_nodes_have_onchain_tx_type( &[("node_a", &node_a), ("node_b", &node_b)], "all ", "CooperativeClose", |tx_type| matches!(tx_type, TransactionType::CooperativeClose { .. }), - ); + ) + .unwrap(); // Peer removed after cooperative close — no further reason to reconnect. assert!( !node_a.list_peers().iter().any(|p| p.node_id == node_b.node_id() && p.is_persisted), diff --git a/tests/integration_tests_rust.rs b/tests/integration_tests_rust.rs index ea21221f68..ba19cbb07d 100644 --- a/tests/integration_tests_rust.rs +++ b/tests/integration_tests_rust.rs @@ -30,8 +30,8 @@ use common::{ open_channel_no_wait, open_channel_push_amt, open_channel_with_all, premine_and_distribute_funds, premine_blocks, prepare_rbf, random_chain_source, random_config, setup_bitcoind_and_electrsd, setup_builder, setup_node, setup_two_nodes, splice_in_with_all, - wait_for_block, wait_for_tx, InMemoryStore, NodePaymentExt, TestChainSource, TestConfig, - TestNode, TestStoreType, TestSyncStore, + wait_for_block, wait_for_node_tip, wait_for_tx, InMemoryStore, NodePaymentExt, TestChainSource, + TestConfig, TestNode, TestStoreType, TestSyncStore, }; use electrsd::corepc_node::{self, Node as BitcoinD}; use electrsd::ElectrsD; @@ -1277,10 +1277,11 @@ async fn onchain_send_receive() { let channel_amount_sat = 1_000_000; let reserve_amount_sat = 25_000; open_channel(&node_b, &node_a, channel_amount_sat, true, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; - + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); expect_channel_ready_event!(node_a, node_b.node_id()); expect_channel_ready_event!(node_b, node_a.node_id()); @@ -1348,9 +1349,11 @@ async fn onchain_send_receive() { assert_eq!(payment_a.amount_msat, payment_b.amount_msat); assert_eq!(payment_a.fee_paid_msat, payment_b.fee_paid_msat); - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); let expected_node_a_balance = expected_node_a_balance + amount_to_send_sats; let expected_node_b_balance_lower = expected_node_b_balance_lower - amount_to_send_sats; @@ -1388,12 +1391,12 @@ async fn onchain_send_receive() { let addr_b = node_b.onchain_payment().new_address().unwrap(); let txid = node_a.onchain_payment().send_all_to_address(&addr_b, true, None).unwrap(); - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; wait_for_tx(&electrsd.client, txid).await; - node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); - + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); let expected_node_b_balance_lower = expected_node_b_balance_lower + expected_node_a_balance; let expected_node_b_balance_upper = expected_node_b_balance_upper + expected_node_a_balance; let expected_node_a_balance = 0; @@ -1411,11 +1414,13 @@ async fn onchain_send_receive() { let addr_b = node_b.onchain_payment().new_address().unwrap(); let txid = node_a.onchain_payment().send_all_to_address(&addr_b, false, None).unwrap(); - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; wait_for_tx(&electrsd.client, txid).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); let expected_node_b_balance_lower = expected_node_b_balance_lower + reserve_amount_sat; let expected_node_b_balance_upper = expected_node_b_balance_upper + reserve_amount_sat; @@ -1532,10 +1537,11 @@ async fn onchain_send_all_retains_reserve() { let txid = node_a.onchain_payment().send_all_to_address(&addr_b, true, None).unwrap(); wait_for_tx(&electrsd.client, txid).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; - + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); // Check node a sent all and node b received it assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, 0); assert!(((premine_amount_sat * 2 - onchain_fee_buffer_sat)..=(premine_amount_sat * 2)) @@ -1550,16 +1556,20 @@ async fn onchain_send_all_retains_reserve() { .parse() .unwrap(); wait_for_tx(&electrsd.client, txid).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the node tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the node tip"); assert_eq!(node_a.list_balances().spendable_onchain_balance_sats, reserve_amount_sat); // Open a channel. open_channel(&node_b, &node_a, premine_amount_sat, false, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the node tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the node tip"); expect_channel_ready_event!(node_a, node_b.node_id()); expect_channel_ready_event!(node_b, node_a.node_id()); @@ -1573,10 +1583,12 @@ async fn onchain_send_all_retains_reserve() { let txid = node_b.onchain_payment().send_all_to_address(&addr_a, true, None).unwrap(); wait_for_tx(&electrsd.client, txid).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the node tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the node tip"); // Check node b sent all and node a received it assert_eq!(node_b.list_balances().total_onchain_balance_sats, reserve_amount_sat); @@ -1621,9 +1633,11 @@ async fn onchain_wallet_recovery() { .unwrap(); wait_for_tx(&electrsd.client, txid).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 1).await; - + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 1).await; original_node.sync_wallets().unwrap(); + wait_for_node_tip(&original_node, new_height) + .await + .expect("node hasn't synced to the node tip"); assert_eq!( original_node.list_balances().spendable_onchain_balance_sats, premine_amount_sat * 2 @@ -1659,9 +1673,11 @@ async fn onchain_wallet_recovery() { .unwrap(); wait_for_tx(&electrsd.client, txid).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 1).await; - + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 1).await; recovered_node.sync_wallets().unwrap(); + wait_for_node_tip(&recovered_node, new_height) + .await + .expect("node hasn't synced to the node tip"); assert_eq!( recovered_node.list_balances().spendable_onchain_balance_sats, premine_amount_sat * 3 @@ -2268,10 +2284,12 @@ async fn splice_channel() { open_channel(&node_a, &node_b, 4_000_000, false, &electrsd).await; // Open a channel with Node A contributing the funding - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the node tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the node tip"); let user_channel_id_a = expect_channel_ready_event!(node_a, node_b.node_id()); let user_channel_id_b = expect_channel_ready_event!(node_b, node_a.node_id()); @@ -2370,7 +2388,9 @@ async fn splice_channel() { expect_payment_received_event!(node_a, amount_msat); // Mine a block to give time for the HTLC to resolve - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 1).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 1).await; + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the node tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the node tip"); assert_eq!( node_a.list_balances().total_lightning_balance_sats, @@ -3045,10 +3065,12 @@ async fn simple_bolt12_send_receive() { node_a.sync_wallets().unwrap(); open_channel(&node_a, &node_b, 4_000_000, true, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the node tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); expect_channel_ready_event!(node_a, node_b.node_id()); expect_channel_ready_event!(node_b, node_a.node_id()); @@ -3356,12 +3378,22 @@ async fn async_payment() { ) .await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_sender.sync_wallets().unwrap(); node_sender_lsp.sync_wallets().unwrap(); node_receiver_lsp.sync_wallets().unwrap(); node_receiver.sync_wallets().unwrap(); + wait_for_node_tip(&node_sender, new_height).await.expect("node hasn't synced to the node tip"); + wait_for_node_tip(&node_sender_lsp, new_height) + .await + .expect("node hasn't synced to the node tip"); + wait_for_node_tip(&node_receiver_lsp, new_height) + .await + .expect("node hasn't synced to the node tip"); + wait_for_node_tip(&node_receiver, new_height) + .await + .expect("node hasn't synced to the node tip"); expect_channel_ready_event!(node_sender, node_sender_lsp.node_id()); expect_channel_ready_events!( @@ -3558,10 +3590,12 @@ async fn generate_bip21_uri() { node_a.sync_wallets().unwrap(); open_channel(&node_a, &node_b, 4_000_000, true, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the node tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); expect_channel_ready_event!(node_a, node_b.node_id()); expect_channel_ready_event!(node_b, node_a.node_id()); @@ -3697,10 +3731,12 @@ async fn unified_send_receive_bip21_uri() { node_a.sync_wallets().unwrap(); open_channel(&node_a, &node_b, 4_000_000, true, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); expect_channel_ready_event!(node_a, node_b.node_id()); expect_channel_ready_event!(node_b, node_a.node_id()); @@ -3795,11 +3831,14 @@ async fn unified_send_receive_bip21_uri() { }, }; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + // Make sure the transaction reached the mempool before mining, so the blocks include it. wait_for_tx(&electrsd.client, txid).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); assert_eq!(node_b.list_balances().total_onchain_balance_sats, 800_000); assert_eq!(node_b.list_balances().total_lightning_balance_sats, 200_000); @@ -3927,9 +3966,11 @@ async fn do_lsps2_client_service_integration(client_trusts_lsp: bool) { println!("Opening channel payer_node -> service_node!"); open_channel(&payer_node, &service_node, 5_000_000, false, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; service_node.sync_wallets().unwrap(); payer_node.sync_wallets().unwrap(); + wait_for_node_tip(&service_node, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&payer_node, new_height).await.expect("node hasn't synced to the tip"); expect_channel_ready_event!(payer_node, service_node.node_id()); expect_channel_ready_event!(service_node, payer_node.node_id()); @@ -4175,9 +4216,11 @@ async fn spontaneous_send_with_custom_preimage() { node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); open_channel(&node_a, &node_b, 500_000, true, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); expect_channel_ready_event!(node_a, node_b.node_id()); expect_channel_ready_event!(node_b, node_a.node_id()); @@ -4387,9 +4430,11 @@ async fn lsps2_client_trusts_lsp() { // Check the nodes pick up on the confirmed funding tx now. wait_for_tx(&electrsd.client, funding_txo.txid).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; service_node.sync_wallets().unwrap(); client_node.sync_wallets().unwrap(); + wait_for_node_tip(&service_node, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&client_node, new_height).await.expect("node hasn't synced to the tip"); assert_eq!( client_node .list_channels() @@ -4482,9 +4527,11 @@ async fn lsps2_lsp_trusts_client_but_client_does_not_claim() { // Open a channel payer -> service that will allow paying the JIT invoice open_channel(&payer_node, &service_node, 5_000_000, false, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; service_node.sync_wallets().unwrap(); payer_node.sync_wallets().unwrap(); + wait_for_node_tip(&service_node, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&payer_node, new_height).await.expect("node hasn't synced to the tip"); expect_channel_ready_event!(payer_node, service_node.node_id()); expect_channel_ready_event!(service_node, payer_node.node_id()); @@ -4517,9 +4564,11 @@ async fn lsps2_lsp_trusts_client_but_client_does_not_claim() { // Check the nodes pick up on the confirmed funding tx now. wait_for_tx(&electrsd.client, funding_txo.txid).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; service_node.sync_wallets().unwrap(); client_node.sync_wallets().unwrap(); + wait_for_node_tip(&service_node, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&client_node, new_height).await.expect("node hasn't synced to the tip"); assert_eq!( client_node .list_channels() @@ -4580,9 +4629,11 @@ async fn payment_persistence_after_restart() { // Open a large channel from node_a to node_b let channel_amount_sat = 5_000_000; open_channel(&node_a, &node_b, channel_amount_sat, true, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); expect_channel_ready_event!(node_a, node_b.node_id()); expect_channel_ready_event!(node_b, node_a.node_id()); @@ -4945,9 +4996,11 @@ async fn onchain_fee_bump_rbf() { } // Confirm the transaction and try to bump again (should fail) - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); assert_eq!( Err(NodeError::InvalidPaymentId), @@ -5056,10 +5109,12 @@ async fn open_channel_with_all_with_anchors() { let funding_txo = open_channel_with_all(&node_a, &node_b, false, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); let _user_channel_id_a = expect_channel_ready_event!(node_a, node_b.node_id()); let _user_channel_id_b = expect_channel_ready_event!(node_b, node_a.node_id()); @@ -5210,11 +5265,13 @@ async fn open_channel_variants_reserve_funds_for_anchor_peers() { opened_with_all_cases.push((variant, node_a, node_b, funding_txo_a)); } - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; for (variant, node_a, node_b, funding_txo) in opened_with_all_cases { node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); let _user_channel_id_a = expect_channel_ready_event!(node_a, node_b.node_id()); let _user_channel_id_b = expect_channel_ready_event!(node_b, node_a.node_id()); @@ -5266,10 +5323,12 @@ async fn splice_in_with_all_balance() { // Open a channel with a fixed amount first let funding_txo = open_channel(&node_a, &node_b, channel_amount_sat, false, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); let user_channel_id_a = expect_channel_ready_event!(node_a, node_b.node_id()); let _user_channel_id_b = expect_channel_ready_event!(node_b, node_a.node_id()); @@ -5285,10 +5344,12 @@ async fn splice_in_with_all_balance() { // Splice in with all remaining on-chain funds splice_in_with_all(&node_a, &node_b, &user_channel_id_a, &electrsd).await; - generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; + let new_height = generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; node_a.sync_wallets().unwrap(); node_b.sync_wallets().unwrap(); + wait_for_node_tip(&node_a, new_height).await.expect("node hasn't synced to the tip"); + wait_for_node_tip(&node_b, new_height).await.expect("node hasn't synced to the tip"); let _user_channel_id_a2 = expect_channel_ready_event!(node_a, node_b.node_id()); let _user_channel_id_b2 = expect_channel_ready_event!(node_b, node_a.node_id()); diff --git a/tests/reorg_test.rs b/tests/reorg_test.rs index aa17f072c3..b1e65abdb0 100644 --- a/tests/reorg_test.rs +++ b/tests/reorg_test.rs @@ -86,6 +86,7 @@ where .find(|balance| matches_balance(balance)) }) .await + .expect("reached max tries") } proptest! {