lnpeer: only spawn htlc_switch for peers with LNWallet
What changed, and why it matters
This commit stops a background task called htlc_switch from running for simple Lightning Network gossip-only peers. Previously, this task was started for all peers, including ones that only exchange network routing information and never handle actual payments. The change moves the task start so it only runs for full wallet peers. The commit message frames this as a cleanup because gossip peers don't handle HTLCs (payment channels), not as a security fix. There is no direct evidence in the commit of an exploitable vulnerability.
Treat as a hardening/cleanup change rather than an urgent security patch. Review whether the unconditional htlc_switch could have caused any unintended side effects or exceptions in LNGossip peers, but no immediate exploit is evident from the diff.
Security signals we found
Behavioral correctness fix: removes unnecessary HTLC processing for non-wallet Lightning peers
Potential defense-in-depth: prevents htlc_switch from accessing wallet-only state on gossip peers
No explicit security claim in commit message or diff
Evidence from the diff
In electrum/lnpeer.py, the main_loop coroutine previously unconditionally spawned self.htlc_switch() in the task group for every Peer. The patch moves that spawn after the gossip-related tasks and guards it with if self.network.lngossip != self.lnworker. This ensures htlc_switch is only spawned when the peer’s lnworker is not the LNGossip instance. The change is a correctness/resource optimization: running an HTLC processing loop for a gossip-only peer is unnecessary and could lead to unexpected behavior if the loop tries to interact with wallet state that does not exist in LNGossip.
Changed components
electrum/lnpeer.pyLightning Network peer main_loophtlc_switch task spawningLNGossip peer handlingInspect captured patch +2 / −1
diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
index a4bddd1..01eeddd 100644
--- a/electrum/lnpeer.py
+++ b/electrum/lnpeer.py
@@ -523,12 +523,13 @@ class Peer(Logger, EventListener):
@handle_disconnect
async def main_loop(self):
async with self.taskgroup as group:
- await group.spawn(self.htlc_switch())
await group.spawn(self._message_loop())
await group.spawn(self._query_gossip())
await group.spawn(self._process_gossip())
await group.spawn(self._send_own_gossip())
await group.spawn(self._forward_gossip())
+ if self.network.lngossip != self.lnworker:
+ await group.spawn(self.htlc_switch())
async def _process_gossip(self):
while True:
Why this scored 33/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.