lnworker: fix _get_next_peers_to_try regression
What changed, and why it matters
This commit fixes a programming bug where the order of logical checks was wrong, causing Electrum to ignore all recently-used Lightning peers when no Tor proxy was configured. The fix makes the code correctly check whether the active proxy is a Tor proxy before deciding whether to skip onion-address peers. This is a connectivity bug rather than a direct theft or remote-code vulnerability, but it could make users' Lightning connections behave unexpectedly or prefer less optimal peers.
Treat as a routine bug fix. Users running Lightning on Electrum should update to a version containing this commit to restore correct peer selection, especially if they do not use a Tor proxy. No emergency response is warranted.
Security signals we found
Logic/precedence bug in peer-selection that could alter Lightning routing/connectivity behavior
Fix centralizes proxy/Tor checks on a single canonical property (is_proxy_tor), reducing future precedence mistakes
No direct cryptographic, authentication, or remote-code flaw visible in the diff
Evidence from the diff
The patch corrects operator-precedence/logic errors in LNPeerManager._get_next_peers_to_try and choose_preferred_address. The original expressions peer.is_onion() and not self.network.proxy or not self.network.proxy.enabled were parsed as (peer.is_onion() and not self.network.proxy) or not self.network.proxy.enabled, so whenever no proxy was enabled the whole condition became true and every recent peer was skipped. The fix replaces the ad-hoc proxy checks with self.network.is_proxy_tor, which is the canonical way to ask whether a Tor proxy is active. Tests are updated to use the new property.
Changed components
electrum/lnworker.py: LNPeerManager._get_next_peers_to_tryelectrum/lnworker.py: LNPeerManager.choose_preferred_addresstests/test_lnpeer.pytests/test_lnpeermgr.pyInspect captured patch +5 / −4
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
index 71ac86d..e71802f 100644
--- a/electrum/lnworker.py
+++ b/electrum/lnworker.py
@@ -486,7 +486,7 @@ class LNPeerManager(Logger, EventListener, NetworkRetryManager[LNPeerAddr]):
continue
if not self.is_good_peer(peer):
continue
- if peer.is_onion() and not self.network.proxy or not self.network.proxy.enabled:
+ if peer.is_onion() and not self.network.is_proxy_tor:
continue
return [peer]
# try random peer from graph
@@ -564,7 +564,7 @@ class LNPeerManager(Logger, EventListener, NetworkRetryManager[LNPeerAddr]):
for host, port, timestamp in sorted(addr_list, key=lambda a: -a[2]):
if is_ip_address(host):
return host, port, timestamp
- if not self.network.proxy or not self.network.proxy.enabled:
+ if not self.network.is_proxy_tor:
addr_list = [(h, p, ts) for h, p, ts in addr_list if not h.endswith('.onion')]
if not addr_list:
return None
diff --git a/tests/test_lnpeer.py b/tests/test_lnpeer.py
index e88a53b..b36f8b7 100644
--- a/tests/test_lnpeer.py
+++ b/tests/test_lnpeer.py
@@ -73,6 +73,7 @@ class MockNetwork:
self.lngossip = MockLNGossip()
self.tx_queue = asyncio.Queue()
self.proxy = ProxySettings()
+ self.is_proxy_tor = None
self._blockchain = MockBlockchain()
def get_local_height(self):
diff --git a/tests/test_lnpeermgr.py b/tests/test_lnpeermgr.py
index 7603346..eccbda8 100644
--- a/tests/test_lnpeermgr.py
+++ b/tests/test_lnpeermgr.py
@@ -73,7 +73,7 @@ class TestLNPeerManager(ElectrumTestCase):
self.assertEqual(result, ("10.0.0.1", 9735, 150)) # Most recent IP
# no IP, proxy disabled, filter .onion and choose random
- self.assertFalse(peermgr.network.proxy.enabled)
+ self.assertFalse(peermgr.network.is_proxy_tor)
addr_list = [("host.com", 9735, 100), ("host.onion", 9735, 200)]
result = peermgr.choose_preferred_address(addr_list)
self.assertEqual(result, ("host.com", 9735, 100))
@@ -84,7 +84,7 @@ class TestLNPeerManager(ElectrumTestCase):
self.assertIsNone(result)
# return onion if proxy enabled
- peermgr.network.proxy.enabled = True
+ peermgr.network.is_proxy_tor = True
addr_list = [("host.onion", 9735, 100)]
result = peermgr.choose_preferred_address(addr_list)
self.assertEqual(result, ("host.onion", 9735, 100))
Why this scored 25/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.