lnpeer: send channel_update on channel_reestablish
What changed, and why it matters
This change makes Electrum's Lightning peer re-send its channel fee and routing rules to a peer whenever the connection is re-established, not just when the channel first opens. This helps peers know the current rules so payments can be received reliably. It is a protocol robustness improvement, not a fix for an active exploit.
No urgent action. Treat as a normal reliability improvement. Review whether sending channel_update on every reestablish could leak or spam channel state, but the conditions (OPEN, forwarding enabled, short_channel_id present, not just became ready) appear reasonable.
Security signals we found
Lightning protocol reliability improvement
Re-transmission of channel_update after reconnection
Prevents stale routing constraints for forwarding peers
No cryptographic bypass or memory safety issue visible
Evidence from the diff
In electrum/lnpeer.py, after a channel_reestablish, the code now sends a channel_update when the channel is OPEN, forwarding is enabled, the channel has a short_channel_id, and the channel did not just become ready. Previously, channel_update was effectively sent only around channel open. The change ensures peers have up-to-date channel constraints (fees, CLTV delta, etc.) needed for routing tags or blinded paths.
Changed components
electrum/lnpeer.pyLightning channel reestablishment flowchannel_update message handlingInspect captured patch +7 / −2
diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
index 4202f05..8acabb8 100644
--- a/electrum/lnpeer.py
+++ b/electrum/lnpeer.py
@@ -1705,8 +1705,8 @@ class Peer(Logger, EventListener):
chan.peer_state = PeerState.GOOD
self._chan_reest_finished[chan.channel_id].set()
+ chan_just_became_ready = (their_next_local_ctn == next_local_ctn == 1)
if chan.is_funded():
- chan_just_became_ready = (their_next_local_ctn == next_local_ctn == 1)
if chan_just_became_ready or self.features.supports(LnFeatures.OPTION_SCID_ALIAS_OPT):
self.send_channel_ready(chan)
@@ -1714,9 +1714,14 @@ class Peer(Logger, EventListener):
self.maybe_update_fee(chan) # if needed, update fee ASAP, to avoid force-closures from this
# checks done
util.trigger_callback('channel', self.lnworker.wallet, chan)
- # if we have sent a previous shutdown, it must be retransmitted (Bolt2)
if chan.get_state() == ChannelState.SHUTDOWN:
+ # if we have sent a previous shutdown, it must be retransmitted (Bolt2)
await self.taskgroup.spawn(self.send_shutdown(chan))
+ elif chan.get_state() == ChannelState.OPEN:
+ forwarding_enabled = self.config.EXPERIMENTAL_LN_FORWARD_PAYMENTS
+ if forwarding_enabled and chan.short_channel_id and not chan_just_became_ready:
+ # send channel update so peer knows our constraints for forwarding to them
+ self.send_channel_update(chan)
def send_channel_ready(self, chan: Channel):
assert chan.is_funded()
Why this scored 30/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.