network: disconnected servers: do not filter out bookmarked raw ":t"
What changed, and why it matters
This is a small user-interface fix in the Electrum Bitcoin wallet. Previously, the list of 'disconnected servers' shown in the network settings only displayed secure ':s' servers and hid plain-text ':t' servers and .onion servers, even if the user had bookmarked them. The change makes bookmarked plain-text and .onion servers visible again so users can see and manage servers they deliberately saved. It does not change how the wallet actually connects to servers or any security-critical networking logic.
No security action required. Treat as a normal bug fix / UX improvement. Reviewers may optionally verify that to_friendly_name() does not expose sensitive internal addresses and that the renamed constant is imported correctly everywhere.
Security signals we found
UI-only change; no modification of connection, certificate, or authentication logic
No change to default server selection or preferred protocol ('s' remains preferred)
No input parsing changes beyond renaming an existing protocol set constant
No privilege escalation, code execution, or data-exfiltration path introduced
Evidence from the diff
The patch refactors Network.get_disconnected_server_addrs() to build ServerAddr objects for both ‘t’ and ‘s’ protocol transports, then only filters out non-preferred-protocol and non-Tor .onion servers when they are not bookmarked. It also renames _KNOWN_NETWORK_PROTOCOLS to KNOWN_ELEC_PROTOCOL_TRANSPORTS and exports it, and changes GUI display calls from net_addr_str() to to_friendly_name() so the protocol suffix is shown. The fix is purely presentational: bookmarked servers are now surfaced in the disconnected-servers UI regardless of transport or .onion status.
Changed components
electrum/network.pyelectrum/interface.pyelectrum/gui/qt/network_dialog.pyelectrum/gui/qml/qeserverlistmodel.pyInspect captured patch +20 / −14
diff --git a/electrum/gui/qml/qeserverlistmodel.py b/electrum/gui/qml/qeserverlistmodel.py
index b2e2222..b93a078 100644
--- a/electrum/gui/qml/qeserverlistmodel.py
+++ b/electrum/gui/qml/qeserverlistmodel.py
@@ -118,7 +118,7 @@ class QEServerListModel(QAbstractListModel, QtEventListener):
'height': 0,
'is_primary': False,
'is_connected': False,
- 'name': s.net_addr_str()
+ 'name': s.to_friendly_name()
}
server['address'] = server['name']
diff --git a/electrum/gui/qt/network_dialog.py b/electrum/gui/qt/network_dialog.py
index 2b97064..ad4ff48 100644
--- a/electrum/gui/qt/network_dialog.py
+++ b/electrum/gui/qt/network_dialog.py
@@ -183,7 +183,7 @@ class NodesListWidget(QTreeWidget):
disconnected_servers_item = QTreeWidgetItem([_("Other known servers"), ""])
disconnected_servers_item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.TOPLEVEL)
for server in network.get_disconnected_server_addrs():
- item = QTreeWidgetItem([server.net_addr_str(), ""])
+ item = QTreeWidgetItem([server.to_friendly_name(), ""])
item.setData(0, self.ITEMTYPE_ROLE, self.ItemType.DISCONNECTED_SERVER)
item.setData(0, self.SERVER_ADDR_ROLE, server)
if network.is_server_bookmarked(server):
diff --git a/electrum/interface.py b/electrum/interface.py
index b9827cf..2dead63 100644
--- a/electrum/interface.py
+++ b/electrum/interface.py
@@ -75,9 +75,9 @@ ca_path = certifi.where()
BUCKET_NAME_OF_ONION_SERVERS = 'onion'
-_KNOWN_NETWORK_PROTOCOLS = {'t', 's'}
+KNOWN_ELEC_PROTOCOL_TRANSPORTS = {'t', 's'}
PREFERRED_NETWORK_PROTOCOL = 's'
-assert PREFERRED_NETWORK_PROTOCOL in _KNOWN_NETWORK_PROTOCOLS
+assert PREFERRED_NETWORK_PROTOCOL in KNOWN_ELEC_PROTOCOL_TRANSPORTS
MAX_NUM_HEADERS_PER_REQUEST = 2016
assert MAX_NUM_HEADERS_PER_REQUEST >= CHUNK_SIZE
@@ -462,7 +462,7 @@ class ServerAddr:
net_addr = NetAddress(host, port) # this validates host and port
except Exception as e:
raise ValueError(f"cannot construct ServerAddr: invalid host or port (host={host}, port={port})") from e
- if protocol not in _KNOWN_NETWORK_PROTOCOLS:
+ if protocol not in KNOWN_ELEC_PROTOCOL_TRANSPORTS:
raise ValueError(f"invalid network protocol: {protocol}")
self.host = str(net_addr.host) # canonical form (if e.g. IPv6 address)
self.port = int(net_addr.port)
diff --git a/electrum/network.py b/electrum/network.py
index 2bff22e..c74a0af 100644
--- a/electrum/network.py
+++ b/electrum/network.py
@@ -53,7 +53,7 @@ from .transaction import Transaction
from .blockchain import Blockchain
from .interface import (
Interface, PREFERRED_NETWORK_PROTOCOL, RequestTimedOut, NetworkTimeout, BUCKET_NAME_OF_ONION_SERVERS,
- NetworkException, RequestCorrupted, ServerAddr, TxBroadcastError,
+ NetworkException, RequestCorrupted, ServerAddr, TxBroadcastError, KNOWN_ELEC_PROTOCOL_TRANSPORTS,
)
from .version import PROTOCOL_VERSION_MIN
from .i18n import _
@@ -660,21 +660,27 @@ class Network(Logger, NetworkRetryManager[ServerAddr]):
return out
def get_disconnected_server_addrs(self) -> Sequence[ServerAddr]:
- servers = self.get_servers()
+ hostmap = self.get_servers()
disconnected_server_addrs = [] # type: List[ServerAddr]
chains = self.get_blockchains()
connected_hosts = set([iface.host for ifaces in chains.values() for iface in ifaces])
- protocol = PREFERRED_NETWORK_PROTOCOL
- server_addrs = [
- ServerAddr(_host, port, protocol=protocol)
- for _host, d in servers.items()
- if (port := d.get(protocol))] # FIXME this filters out even bookmarked servers from other protocols
+ # convert hostmap to list of ServerAddrs (one-to-many mapping)
+ server_addrs = []
+ for host, portmap in hostmap.items():
+ for protocol in KNOWN_ELEC_PROTOCOL_TRANSPORTS:
+ if port := portmap.get(protocol):
+ server_addrs.append(ServerAddr(host, port, protocol=protocol))
+ # sort bookmarked servers to appear first
server_addrs.sort(key=lambda x: (-self.is_server_bookmarked(x), str(x)))
+ # filter out stuff
for server in server_addrs:
if server.host in connected_hosts:
continue
- if server.host.endswith('.onion') and not self.is_proxy_tor:
- continue
+ if not self.is_server_bookmarked(server):
+ if server.protocol != PREFERRED_NETWORK_PROTOCOL:
+ continue
+ if server.host.endswith('.onion') and not self.is_proxy_tor:
+ continue
disconnected_server_addrs.append(server)
return disconnected_server_addrs
Why this scored 19/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.