lightningd: allow another gossip state transition.
What changed, and why it matters
This is a small bug-fix patch for Core Lightning's internal channel gossip state machine. It adds one previously missing allowed transition between two internal states, preventing the daemon from logging a 'BROKEN' error and potentially misbehaving when a special type of channel (zeroconf, or soon a 'withheld' funding flow) is closed before the funding transaction is mined. There is no indication this allows an attacker to steal funds or take control; it is a robustness fix for an edge case in protocol handling.
Treat as a routine bug-fix/robustness improvement. Reviewers may want to confirm no other missing transitions exist for the new withheld=True flow, but no urgent security response is indicated by this commit alone.
Security signals we found
Fixes an internal state-machine error path (BROKEN log) for zeroconf/withheld channels
No memory safety, cryptographic, or authorization boundary change visible in diff
No input validation, parsing, or network message handling change visible in diff
Commit message describes the issue as a state transition that 'can definitely happen', not as a vulnerability
Evidence from the diff
The change adds a single entry to the allowed_transitions table in lightningd/channel_gossip.c: CGOSSIP_WAITING_FOR_SCID -> CGOSSIP_CHANNEL_UNANNOUNCED_DYING, with the rationale ‘Zeroconf channel closing mutually before funding tx’. The commit message shows this transition currently triggers an ‘Illegal gossip state transition’ BROKEN log. The fix simply recognizes this legitimate transition so the state machine does not treat it as an error. It is defensive and partial in the sense that it addresses one observed transition rather than redesigning the state machine.
Changed components
lightningd/channel_gossip.cCore Lightning channel gossip state machineZeroconf channel lifecycle handlingUpcoming 'withheld=True' funding flowInspect captured patch +2 / −0
diff --git a/lightningd/channel_gossip.c b/lightningd/channel_gossip.c
index 6cc92520..d7d53747 100644
--- a/lightningd/channel_gossip.c
+++ b/lightningd/channel_gossip.c
@@ -94,6 +94,8 @@ static struct state_transition allowed_transitions[] = {
"Channel usable (zeroconf) but no scid yet" },
{ CGOSSIP_WAITING_FOR_SCID, CGOSSIP_CHANNEL_DEAD,
"Zeroconf channel closed before funding tx mined" },
+ { CGOSSIP_WAITING_FOR_SCID, CGOSSIP_CHANNEL_UNANNOUNCED_DYING,
+ "Zeroconf channel closing mutually before funding tx" },
{ CGOSSIP_WAITING_FOR_USABLE, CGOSSIP_WAITING_FOR_MATCHING_PEER_SIGS,
"Channel mined, but we haven't got matching announcment sigs from peer" },
{ CGOSSIP_WAITING_FOR_USABLE, CGOSSIP_WAITING_FOR_ANNOUNCE_DEPTH,
Why this scored 23/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.