fixup! splice: Handle CHANNEL_READY during splice resume
What changed, and why it matters
This is a small follow-up fix to a recent splice-resume feature in Core Lightning's channel daemon. It removes a hard abort when an unexpected ERROR message arrives during a splice, and instead lets the daemon handle certain allowed out-of-order messages (like CHANNEL_READY) while waiting for the expected splice messages. The change is defensive and appears aimed at preventing the node from crashing during legitimate splice resume flows.
Treat as a low-severity stability/defensive fix. Review the parent splice commit to ensure the abort removal does not mask fatal error conditions that should still terminate the channel. No immediate security response appears warranted unless the original abort was hiding a reachable crash/DoS.
Security signals we found
Removal of an abort-on-ERROR path that could crash the channel daemon
Addition of re-entrant message handling for allowed premature messages during splice resume
Fixup commit indicates this is a correction to an earlier, likely still-unmerged, splice change
Evidence from the diff
The patch modifies channeld/channeld.c. It removes the if (type == WIRE_ERROR) abort(); guard inside peer_expect_msg_four(), which previously killed the daemon if any ERROR message was received while expecting splice-related messages. It also adds a loop in interactive_send_commitments() so that a permitted premature message (e.g., CHANNEL_READY during splice resume) can be processed and then a new message can be awaited, rather than failing the expectation check. A comment typo is fixed (BOLT-??? -> BOLT-splice).
Changed components
channeld/channeld.cpeer_expect_msg_four()interactive_send_commitments()splice resume / reconnection logicInspect captured patch +6 / −3
diff --git a/channeld/channeld.c b/channeld/channeld.c
index 4e18a93f..af55a92b 100644
--- a/channeld/channeld.c
+++ b/channeld/channeld.c
@@ -3032,8 +3032,6 @@ static const u8 *peer_expect_msg_four(const tal_t *ctx,
msg = peer_read(ctx, peer->pps);
type = fromwire_peektype(msg);
- if (type == WIRE_ERROR)
- abort();
if (type != expect_type
&& type != second_allowed_type
&& type != third_allowed_type
@@ -3116,9 +3114,14 @@ static struct commitsig *interactive_send_commitments(struct peer *peer,
WIRE_TX_ABORT,
allowed_premature_msg);
+ /* If the message is a type that we allow to receive
+ * prematurely: process this, then come back and get another
+ * message */
if (allowed_premature_msg
&& fromwire_peektype(msg) == allowed_premature_msg) {
+ /* Process the pre-allowed message */
peer_in(peer, msg);
+ /* Now get a new message */
msg = peer_expect_msg_four(tmpctx, peer,
WIRE_COMMITMENT_SIGNED,
WIRE_TX_SIGNATURES,
@@ -6037,7 +6040,7 @@ static void peer_reconnect(struct peer *peer,
if (retransmit_revoke_and_ack && peer->last_was_revoke)
resend_revoke(peer);
- /* BOLT-??? #2
+ /* BOLT-splice #2
* 1. type: 5 (`my_current_funding_locked`)
* 2. data:
* * [`sha256`:`my_current_funding_locked_txid`]
Why this scored 34/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.