From 1a6bc726ce398e5e169bddde887d3db8a3dbd440 Mon Sep 17 00:00:00 2001 From: Elias Rohrer Date: Wed, 12 Aug 2026 16:00:37 +0200 Subject: [PATCH] Wait for splice broadcasts before mining SpliceNegotiated only marks negotiation's end. The asynchronous broadcast may still be queued, so immediate mining can leave the splice short of the confirmations required for ChannelReady. Wait until each negotiated transaction is observable before mining in the affected lifecycle, balance, and interop tests. Co-Authored-By: HAL 9000 --- tests/common/mod.rs | 6 ++++-- tests/common/scenarios/mod.rs | 5 +++-- tests/integration_tests_rust.rs | 2 ++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/common/mod.rs b/tests/common/mod.rs index b701f0488..9c1bb75c0 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1539,7 +1539,8 @@ pub(crate) async fn do_channel_full_cycle( assert!(splice_out_sat > 500_000); node_b.splice_out(&user_channel_id_b, node_a.node_id(), &addr_a, splice_out_sat).unwrap(); - expect_splice_negotiated_event!(node_b, node_a.node_id()); + 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; node_a.sync_wallets().unwrap(); @@ -1560,7 +1561,8 @@ pub(crate) async fn do_channel_full_cycle( let splice_in_sat = splice_out_sat; node_a.splice_in(&user_channel_id_a, node_b.node_id(), splice_in_sat).unwrap(); - expect_splice_negotiated_event!(node_a, node_b.node_id()); + 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; node_a.sync_wallets().unwrap(); diff --git a/tests/common/scenarios/mod.rs b/tests/common/scenarios/mod.rs index 5b73b6511..3a1066ca0 100644 --- a/tests/common/scenarios/mod.rs +++ b/tests/common/scenarios/mod.rs @@ -23,7 +23,7 @@ use electrsd::electrum_client::ElectrumApi; use ldk_node::{Event, Node}; use super::external_node::ExternalNode; -use super::{generate_blocks_and_wait, premine_and_distribute_funds}; +use super::{generate_blocks_and_wait, premine_and_distribute_funds, wait_for_tx}; #[derive(Debug, Clone, Copy)] pub(crate) enum Side { @@ -240,7 +240,8 @@ pub(crate) async fn splice_in_scenario( .await; let ext_node_id = peer.get_node_id().await.unwrap(); node.splice_in(&user_ch, ext_node_id, 500_000).unwrap(); - expect_splice_negotiated_event!(node, ext_node_id); + let splice_txo = expect_splice_negotiated_event!(node, ext_node_id); + wait_for_tx(electrs, splice_txo.txid).await; generate_blocks_and_wait(bitcoind, electrs, 6).await; sync_wallets_with_retry(node).await; expect_channel_ready_event!(node, ext_node_id); diff --git a/tests/integration_tests_rust.rs b/tests/integration_tests_rust.rs index 0333fe006..56e57d61a 100644 --- a/tests/integration_tests_rust.rs +++ b/tests/integration_tests_rust.rs @@ -2043,6 +2043,7 @@ async fn splice_channel() { // Node B contributed to this splice, so wait for its funding broadcast to be classified before // syncing — otherwise a sync racing the broadcaster's queue records a generic on-chain payment. wait_for_classified_funding_payment(&node_b, txo.txid).await; + wait_for_tx(&electrsd.client, txo.txid).await; generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await; @@ -2102,6 +2103,7 @@ async fn splice_channel() { // Node A contributed to this splice, so wait for its funding broadcast to be classified before // syncing — otherwise a sync racing the broadcaster's queue records a generic on-chain payment. wait_for_classified_funding_payment(&node_a, txo.txid).await; + wait_for_tx(&electrsd.client, txo.txid).await; generate_blocks_and_wait(&bitcoind.client, &electrsd.client, 6).await;