AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Moderate 50 Bitcoin

Stop enqueueing messages for disconnected peers

Public commit record

What the developer wrote

Authored by Matt Corallo

68/100 · Adequate
Stop enqueueing messages for disconnected peers

If a channel operation occurs while a peer is disconnected, we'll
still have a `PeerState` for that peer. Historically, we haven't
bothered to check if a peer is actually connected before we push
new messages onto the `PeerState::pending_msg_events` field,
leaving us sending messages into the void.

This is generally not an issue as
`ChannelManager::get_and_clear_pending_msg_events` should be called
very regularly, removing these messages and then dropping them as
`PeerManager` won't have anything to do with them.

Still, there is a race condition here - if a peer manages to
connect between the generation of one such message and when
`get_and_clear_pending_msg_events` is called, we may enqueue a
message to the peer which makes no sense and could lead to a
spurious channel closure (especially in the case of an async
`ChannelMonitorUpdate` completion or async signing operation, which
often lead to normal channel message generation).

Further, if a peer is slow to send their `channel_reestablish`
message after connection this race could be substantially more
likely, as such normal channel messages may be nonsense until we've
completed the reestablish dance (i.e. the later reestablish dance
may lead us to re-send the same messages again immediately).

Here we remove most of the cases where we enqueue messages for
disconnected peers.

Note that we differentiate between two different checks for
connected-ness - for cases where we're sending an `error` or gossip
messages, we allow the messages to be enqueued if the peer is
connected at all. For most other cases, we only allow messages to
be enqueued if the peer is connected *and* the channel has
completed its reestablish dance (if required, i.e. the channel is
"connected").
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context
The short version

What changed, and why it matters

This commit fixes a race condition in the Lightning Dev Kit where the software could queue up messages for a peer that was temporarily disconnected. If that peer reconnected at just the right moment, it could receive messages that don't make sense for the current channel state, potentially causing a channel to close unexpectedly. The fix adds checks to avoid enqueueing most channel messages unless the peer is connected and the channel re-establishment handshake is complete. Error and gossip messages are still allowed when the peer is simply connected.

Recommended action

Apply the patch. After applying, review any remaining sites that enqueue MessageSendEvent without an is_connected guard to ensure full coverage. Run the updated reorg tests and add targeted tests that simulate disconnect/reconnect during async monitor/signer completion to confirm the race is closed. Consider whether the remaining allowed error/gossip paths could still leak stale state.

Security signals we found

01

Race condition between message generation and peer reconnection

02

Out-of-order Lightning protocol messages before channel_reestablish completion

03

Spurious channel closure risk from stale pending_msg_events

04

Async ChannelMonitorUpdate / async signing operations increase race window

05

API misuse errors now returned for operations on disconnected peers

Risk score

Why this scored 50/100

Our methodology →
Potential impact 12/30
Exploitability 8/25
Stealth signal 10/15
Affected reach 9/15
Confidence 7/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.