Avoid initial commitment channel_ready retransmission while splicing
What changed, and why it matters
This commit fixes a protocol-level bug in the Lightning Dev Kit where a node could incorrectly re-send a 'channel_ready' message after reconnecting to a peer during a splice operation. Splicing only happens after both sides have already exchanged 'channel_ready', so retransmitting it again is unnecessary and could confuse the peer or violate protocol expectations. The fix adds checks to skip that retransmission when a splice is in progress or has been started.
Treat as a low-severity protocol correctness fix. Reviewers should verify that the two new conditions (pending_splice and splice_parent_funding_txid) fully cover all splice states where channel_ready retransmission should be suppressed, and that no other reconnection paths are affected.
Security signals we found
Protocol-state inconsistency: retransmitting channel_ready after both sides have already sent/received it during a splice could lead to peer confusion or state machine errors.
BOLT compliance: the change aligns behavior with the intended reading that retransmission is only required when no splice-related fields are present in channel_reestablish.
Test expectation change: splicing_tests.rs no longer forces send_channel_ready on reconnect, confirming the new behavior is intentional.
Evidence from the diff
In channel.rs, the logic that decides whether to retransmit channel_ready on reconnection previously only checked whether both sides were still at commitment number 1. The patch adds two extra conditions: self.pending_splice.is_none() and funding.channel_transaction_parameters.splice_parent_funding_txid.is_none(). This prevents retransmission while a splice is pending or when the channel parameters already reference a splice parent funding transaction. The corresponding splicing test is updated to stop expecting explicit channel_ready retransmission on reconnect.
Changed components
lightning/src/ln/channel.rslightning/src/ln/splicing_tests.rsInspect captured patch +8 / −3
diff --git a/lightning/src/ln/channel.rs b/lightning/src/ln/channel.rs
index 2a8fd8e..4eb5513 100644
--- a/lightning/src/ln/channel.rs
+++ b/lightning/src/ln/channel.rs
@@ -9693,12 +9693,18 @@ where
// A node:
// - if `next_commitment_number` is 1 in both the `channel_reestablish` it
- // sent and received:
+ // sent and received, and none of those `channel_reestablish` messages
+ // contain `my_current_funding_locked` or `next_funding` for a splice transaction:
// - MUST retransmit `channel_ready`.
// - otherwise:
// - MUST NOT retransmit `channel_ready`, but MAY send `channel_ready` with
// a different `short_channel_id` `alias` field.
- let channel_ready = if msg.next_local_commitment_number == 1 && INITIAL_COMMITMENT_NUMBER - self.holder_commitment_point.next_transaction_number() == 1 {
+ let both_sides_on_initial_commitment_number = msg.next_local_commitment_number == 1
+ && INITIAL_COMMITMENT_NUMBER - self.holder_commitment_point.next_transaction_number() == 1;
+ let channel_ready = if both_sides_on_initial_commitment_number
+ && self.pending_splice.is_none()
+ && self.funding.channel_transaction_parameters.splice_parent_funding_txid.is_none()
+ {
// We should never have to worry about MonitorUpdateInProgress resending ChannelReady
self.get_channel_ready(logger)
} else { None };
diff --git a/lightning/src/ln/splicing_tests.rs b/lightning/src/ln/splicing_tests.rs
index 88271d7..a7d5744 100644
--- a/lightning/src/ln/splicing_tests.rs
+++ b/lightning/src/ln/splicing_tests.rs
@@ -497,7 +497,6 @@ fn do_test_splice_state_reset_on_disconnect(reload: bool) {
}
let mut reconnect_args = ReconnectArgs::new(&nodes[0], &nodes[1]);
- reconnect_args.send_channel_ready = (true, true);
reconnect_nodes(reconnect_args);
mine_transaction(&nodes[0], &splice_tx);
Why this scored 28/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.