lnpeer: channel_reestablish: further restrict states for msg handler
What changed, and why it matters
This commit tightens when Electrum's Lightning code accepts a 'channel_reestablish' message from a peer. Previously, the message was dropped only if the channel was already CLOSED or later; now it is also dropped while the channel is in the process of force-closing (FORCE_CLOSING, REQUESTED_FCLOSE, WE_ARE_TOXIC). The change is defensive: it reduces the chance a peer could probe or confuse Electrum during a force-close. The patch is a one-line threshold change and does not by itself fix a known exploit.
Treat as a defensive hardening patch. Review whether additional channel messages (not just channel_reestablish) should be similarly restricted during force-close states, and ensure the state machine cannot be coerced into unsafe transitions by a peer before reaching FORCE_CLOSING.
Security signals we found
state-machine hardening for Lightning channel reestablishment
peer message ignored during force-close transitions
defensive reduction of attack surface during close
no explicit vulnerability or CVE referenced in commit
Evidence from the diff
In electrum/lnpeer.py, on_channel_reestablish() now drops channel_reestablish messages when chan.get_state() >= ChannelState.FORCE_CLOSING instead of >= ChannelState.CLOSED. This expands the ignored states to include FORCE_CLOSING, REQUESTED_FCLOSE, and WE_ARE_TOXIC. The stated rationale is to avoid giving the peer a surface to probe whether state was lost after we sent a force-close request, and to avoid running the handler while we are already force-closing. It is a hardening change, not a complete vulnerability fix.
Changed components
electrum/lnpeer.pyLightning channel_reestablish message handlerChannelState state machine (FORCE_CLOSING, REQUESTED_FCLOSE, WE_ARE_TOXIC, CLOSED)Inspect captured patch +1 / −1
diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
index a5200c9..fabe139 100644
--- a/electrum/lnpeer.py
+++ b/electrum/lnpeer.py
@@ -1465,7 +1465,7 @@ class Peer(Logger, EventListener):
f'channel_reestablish ({chan.get_id_for_log()}): received channel_reestablish with '
f'(their_next_local_ctn={their_next_local_ctn}, '
f'their_oldest_unrevoked_remote_ctn={their_oldest_unrevoked_remote_ctn})')
- if chan.get_state() >= ChannelState.CLOSED:
+ if chan.get_state() >= ChannelState.FORCE_CLOSING:
self.logger.warning(
f"on_channel_reestablish. dropping message. illegal action. "
f"chan={chan.get_id_for_log()}. {chan.get_state()=!r}. {chan.peer_state=!r}")
Why this scored 46/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.