2023-03-28 15:24:40 +00:00
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
|
|
2025-03-03 13:34:05 +01:00
|
|
|
from PyQt6.QtCore import pyqtProperty, pyqtSignal, QObject, pyqtSlot
|
2021-04-01 14:32:43 +02:00
|
|
|
|
|
|
|
|
from electrum.logging import get_logger
|
2021-04-07 16:48:40 +02:00
|
|
|
from electrum import constants
|
2025-03-03 13:34:05 +01:00
|
|
|
from electrum.network import ProxySettings
|
2021-12-01 01:02:52 +01:00
|
|
|
from electrum.interface import ServerAddr
|
2025-02-24 12:20:44 +01:00
|
|
|
from electrum.fee_policy import FEERATE_DEFAULT_RELAY
|
2021-04-01 14:32:43 +02:00
|
|
|
|
2022-07-21 13:24:32 +02:00
|
|
|
from .util import QtEventListener, event_listener
|
2025-04-09 13:44:26 +02:00
|
|
|
from .qeconfig import QEConfig
|
2022-12-30 16:22:22 +01:00
|
|
|
from .qeserverlistmodel import QEServerListModel
|
2022-07-07 19:10:20 +02:00
|
|
|
|
2023-03-28 15:24:40 +00:00
|
|
|
if TYPE_CHECKING:
|
|
|
|
|
from electrum.network import Network
|
|
|
|
|
|
|
|
|
|
|
2022-07-07 19:10:20 +02:00
|
|
|
class QENetwork(QObject, QtEventListener):
|
2021-04-01 14:32:43 +02:00
|
|
|
_logger = get_logger(__name__)
|
|
|
|
|
|
2021-04-07 16:48:40 +02:00
|
|
|
networkUpdated = pyqtSignal()
|
|
|
|
|
blockchainUpdated = pyqtSignal()
|
2023-04-05 11:21:31 +00:00
|
|
|
heightChanged = pyqtSignal([int], arguments=['height']) # local blockchain height
|
|
|
|
|
serverHeightChanged = pyqtSignal([int], arguments=['height'])
|
2021-04-07 16:48:40 +02:00
|
|
|
proxySet = pyqtSignal()
|
2021-12-01 01:02:52 +01:00
|
|
|
proxyChanged = pyqtSignal()
|
2025-03-03 13:34:05 +01:00
|
|
|
torProbeFinished = pyqtSignal([str, int], arguments=['host', 'port'])
|
2022-03-24 20:47:17 +01:00
|
|
|
statusChanged = pyqtSignal()
|
2022-03-23 13:48:30 +01:00
|
|
|
feeHistogramUpdated = pyqtSignal()
|
2022-07-21 19:41:26 +02:00
|
|
|
chaintipsChanged = pyqtSignal()
|
|
|
|
|
isLaggingChanged = pyqtSignal()
|
2022-07-22 12:49:09 +02:00
|
|
|
gossipUpdated = pyqtSignal()
|
2021-04-07 16:48:40 +02:00
|
|
|
|
2022-03-31 14:19:03 +02:00
|
|
|
# shared signal for static properties
|
|
|
|
|
dataChanged = pyqtSignal()
|
2021-04-01 14:32:43 +02:00
|
|
|
|
|
|
|
|
_height = 0
|
2023-03-30 00:40:55 +00:00
|
|
|
_server = ""
|
2023-04-14 15:55:03 +02:00
|
|
|
_is_connected = False
|
2023-03-17 10:15:07 +01:00
|
|
|
_server_status = ""
|
|
|
|
|
_network_status = ""
|
2022-07-21 19:41:26 +02:00
|
|
|
_chaintips = 1
|
|
|
|
|
_islagging = False
|
2022-07-21 13:24:32 +02:00
|
|
|
_fee_histogram = []
|
2022-07-22 12:49:09 +02:00
|
|
|
_gossipPeers = 0
|
|
|
|
|
_gossipUnknownChannels = 0
|
|
|
|
|
_gossipDbNodes = 0
|
|
|
|
|
_gossipDbChannels = 0
|
|
|
|
|
_gossipDbPolicies = 0
|
2021-04-01 14:32:43 +02:00
|
|
|
|
2025-04-09 13:44:26 +02:00
|
|
|
def __init__(self, network: 'Network', parent=None):
|
2023-01-12 13:09:21 +01:00
|
|
|
super().__init__(parent)
|
2023-03-29 22:32:44 +00:00
|
|
|
assert network, "--offline is not yet implemented for this GUI" # TODO
|
2023-01-12 13:09:21 +01:00
|
|
|
self.network = network
|
|
|
|
|
self._serverListModel = None
|
2023-04-05 11:21:31 +00:00
|
|
|
self._height = network.get_local_height() # init here, update event can take a while
|
|
|
|
|
self._server_height = network.get_server_height() # init here, update event can take a while
|
2023-01-12 13:09:21 +01:00
|
|
|
self.register_callbacks()
|
2023-04-12 12:14:11 +02:00
|
|
|
self.destroyed.connect(lambda: self.on_destroy())
|
2023-01-12 13:09:21 +01:00
|
|
|
|
2025-04-09 13:44:26 +02:00
|
|
|
QEConfig.instance.useGossipChanged.connect(self.on_gossip_setting_changed)
|
2023-01-12 13:09:21 +01:00
|
|
|
|
2023-04-12 12:14:11 +02:00
|
|
|
def on_destroy(self):
|
2023-04-12 12:31:16 +02:00
|
|
|
self.unregister_callbacks()
|
2023-04-12 12:14:11 +02:00
|
|
|
|
2022-07-21 13:24:32 +02:00
|
|
|
@event_listener
|
2022-07-07 19:10:20 +02:00
|
|
|
def on_event_network_updated(self, *args):
|
2021-04-07 16:48:40 +02:00
|
|
|
self.networkUpdated.emit()
|
2023-03-30 00:40:55 +00:00
|
|
|
self._update_status()
|
2021-04-01 14:32:43 +02:00
|
|
|
|
2022-07-21 13:24:32 +02:00
|
|
|
@event_listener
|
2022-07-21 19:41:26 +02:00
|
|
|
def on_event_blockchain_updated(self):
|
2022-03-31 14:19:03 +02:00
|
|
|
if self._height != self.network.get_local_height():
|
|
|
|
|
self._height = self.network.get_local_height()
|
|
|
|
|
self._logger.debug('new height: %d' % self._height)
|
|
|
|
|
self.heightChanged.emit(self._height)
|
2021-04-07 16:48:40 +02:00
|
|
|
self.blockchainUpdated.emit()
|
2021-04-01 14:32:43 +02:00
|
|
|
|
2022-07-21 13:24:32 +02:00
|
|
|
@event_listener
|
2022-07-07 19:10:20 +02:00
|
|
|
def on_event_default_server_changed(self, *args):
|
2023-03-30 00:40:55 +00:00
|
|
|
self._update_status()
|
2021-04-01 14:32:43 +02:00
|
|
|
|
2022-07-21 13:24:32 +02:00
|
|
|
@event_listener
|
2022-07-07 19:10:20 +02:00
|
|
|
def on_event_proxy_set(self, *args):
|
2022-03-31 14:19:03 +02:00
|
|
|
self._logger.debug('proxy set')
|
2021-04-07 16:48:40 +02:00
|
|
|
self.proxySet.emit()
|
2023-01-13 10:25:35 +01:00
|
|
|
self.proxyTorChanged.emit()
|
2021-04-01 14:32:43 +02:00
|
|
|
|
2023-11-30 12:12:45 +01:00
|
|
|
@event_listener
|
|
|
|
|
def on_event_tor_probed(self, *args):
|
|
|
|
|
self.proxyTorChanged.emit()
|
|
|
|
|
|
2023-03-30 00:40:55 +00:00
|
|
|
def _update_status(self):
|
|
|
|
|
server = str(self.network.get_parameters().server)
|
|
|
|
|
if self._server != server:
|
|
|
|
|
self._server = server
|
|
|
|
|
self.statusChanged.emit()
|
2023-03-17 10:15:07 +01:00
|
|
|
network_status = self.network.get_status()
|
|
|
|
|
if self._network_status != network_status:
|
2023-03-30 09:29:02 +02:00
|
|
|
self._logger.debug('network_status updated: %s' % network_status)
|
2023-03-17 10:15:07 +01:00
|
|
|
self._network_status = network_status
|
|
|
|
|
self.statusChanged.emit()
|
2023-04-14 15:55:03 +02:00
|
|
|
is_connected = self.network.is_connected()
|
|
|
|
|
if self._is_connected != is_connected:
|
|
|
|
|
self._is_connected = is_connected
|
|
|
|
|
self.statusChanged.emit()
|
|
|
|
|
server_status = self.network.get_connection_status_for_GUI()
|
2023-03-17 10:15:07 +01:00
|
|
|
if self._server_status != server_status:
|
2023-03-30 09:29:02 +02:00
|
|
|
self._logger.debug('server_status updated: %s' % server_status)
|
2023-03-17 10:15:07 +01:00
|
|
|
self._server_status = server_status
|
2022-03-31 14:19:03 +02:00
|
|
|
self.statusChanged.emit()
|
2023-04-05 11:21:31 +00:00
|
|
|
server_height = self.network.get_server_height()
|
|
|
|
|
if self._server_height != server_height:
|
|
|
|
|
self._logger.debug(f'server_height updated: {server_height}')
|
|
|
|
|
self._server_height = server_height
|
|
|
|
|
self.serverHeightChanged.emit(server_height)
|
2022-07-21 19:41:26 +02:00
|
|
|
chains = len(self.network.get_blockchains())
|
|
|
|
|
if chains != self._chaintips:
|
2022-07-26 18:08:32 +02:00
|
|
|
self._logger.debug('chain tips # changed: %d', chains)
|
2022-07-21 19:41:26 +02:00
|
|
|
self._chaintips = chains
|
|
|
|
|
self.chaintipsChanged.emit()
|
|
|
|
|
server_lag = self.network.get_local_height() - self.network.get_server_height()
|
|
|
|
|
if self._islagging ^ (server_lag > 1):
|
2022-07-26 18:08:32 +02:00
|
|
|
self._logger.debug('lagging changed: %s', str(server_lag > 1))
|
2022-07-21 19:41:26 +02:00
|
|
|
self._islagging = server_lag > 1
|
|
|
|
|
self.isLaggingChanged.emit()
|
2021-04-01 14:32:43 +02:00
|
|
|
|
2023-03-30 00:40:55 +00:00
|
|
|
@event_listener
|
|
|
|
|
def on_event_status(self, *args):
|
|
|
|
|
self._update_status()
|
|
|
|
|
|
2022-07-21 13:24:32 +02:00
|
|
|
@event_listener
|
|
|
|
|
def on_event_fee_histogram(self, histogram):
|
2023-04-05 14:32:11 +00:00
|
|
|
self._logger.debug(f'fee histogram updated')
|
2023-03-13 12:17:00 +01:00
|
|
|
self.update_histogram(histogram)
|
|
|
|
|
|
|
|
|
|
def update_histogram(self, histogram):
|
2025-02-24 12:20:44 +01:00
|
|
|
capped_histogram, bytes_current = histogram.get_capped_data()
|
2023-03-13 12:17:00 +01:00
|
|
|
# add clamping attributes for the GUI
|
|
|
|
|
self._fee_histogram = {
|
|
|
|
|
'histogram': capped_histogram,
|
|
|
|
|
'total': bytes_current,
|
2023-03-14 12:41:51 +01:00
|
|
|
'min_fee': capped_histogram[-1][0] if capped_histogram else FEERATE_DEFAULT_RELAY/1000,
|
|
|
|
|
'max_fee': capped_histogram[0][0] if capped_histogram else FEERATE_DEFAULT_RELAY/1000
|
2023-03-13 12:17:00 +01:00
|
|
|
}
|
2022-03-23 13:48:30 +01:00
|
|
|
self.feeHistogramUpdated.emit()
|
|
|
|
|
|
2022-07-22 12:49:09 +02:00
|
|
|
@event_listener
|
|
|
|
|
def on_event_channel_db(self, num_nodes, num_channels, num_policies):
|
2025-06-23 13:10:44 +00:00
|
|
|
changed = False
|
|
|
|
|
if self._gossipDbNodes != num_nodes:
|
|
|
|
|
self._gossipDbNodes = num_nodes
|
|
|
|
|
changed = True
|
|
|
|
|
if self._gossipDbChannels != num_channels:
|
|
|
|
|
self._gossipDbChannels = num_channels
|
|
|
|
|
changed = True
|
|
|
|
|
if self._gossipDbPolicies != num_policies:
|
|
|
|
|
self._gossipDbPolicies = num_policies
|
|
|
|
|
changed = True
|
|
|
|
|
if changed:
|
|
|
|
|
self._logger.debug(f'channel_db: {num_nodes} nodes, {num_channels} channels, {num_policies} policies')
|
2022-07-22 12:49:09 +02:00
|
|
|
self.gossipUpdated.emit()
|
|
|
|
|
|
|
|
|
|
@event_listener
|
|
|
|
|
def on_event_gossip_peers(self, num_peers):
|
|
|
|
|
self._logger.debug(f'gossip peers {num_peers}')
|
|
|
|
|
self._gossipPeers = num_peers
|
|
|
|
|
self.gossipUpdated.emit()
|
|
|
|
|
|
|
|
|
|
@event_listener
|
|
|
|
|
def on_event_unknown_channels(self, unknown):
|
2023-09-22 16:34:28 +02:00
|
|
|
if unknown == 0 and self._gossipUnknownChannels == 0: # TODO: backend sends a lot of unknown=0 events
|
2022-07-22 12:49:09 +02:00
|
|
|
return
|
|
|
|
|
self._logger.debug(f'unknown channels {unknown}')
|
|
|
|
|
self._gossipUnknownChannels = unknown
|
|
|
|
|
self.gossipUpdated.emit()
|
|
|
|
|
|
|
|
|
|
def on_gossip_setting_changed(self):
|
|
|
|
|
if not self.network:
|
|
|
|
|
return
|
2025-04-09 13:44:26 +02:00
|
|
|
if QEConfig.instance.useGossip:
|
2022-07-22 12:49:09 +02:00
|
|
|
self.network.start_gossip()
|
|
|
|
|
else:
|
|
|
|
|
self.network.run_from_another_thread(self.network.stop_gossip())
|
|
|
|
|
|
2022-06-15 11:39:46 +02:00
|
|
|
@pyqtProperty(int, notify=heightChanged)
|
2023-04-05 11:21:31 +00:00
|
|
|
def height(self): # local blockchain height
|
2021-04-01 14:32:43 +02:00
|
|
|
return self._height
|
|
|
|
|
|
2023-04-05 11:21:31 +00:00
|
|
|
@pyqtProperty(int, notify=serverHeightChanged)
|
2023-04-25 14:15:13 +02:00
|
|
|
def serverHeight(self):
|
2023-04-05 11:21:31 +00:00
|
|
|
return self._server_height
|
|
|
|
|
|
2025-06-03 13:22:45 +02:00
|
|
|
autoConnectChanged = pyqtSignal()
|
|
|
|
|
@pyqtProperty(bool, notify=autoConnectChanged)
|
|
|
|
|
def autoConnect(self):
|
|
|
|
|
return self.network.config.NETWORK_AUTO_CONNECT
|
|
|
|
|
|
|
|
|
|
# auto_connect is actually a tri-state, expose the undefined case
|
|
|
|
|
@pyqtProperty(bool, notify=autoConnectChanged)
|
|
|
|
|
def autoConnectDefined(self):
|
|
|
|
|
return self.network.config.cv.NETWORK_AUTO_CONNECT.is_set()
|
|
|
|
|
|
2023-03-30 00:40:55 +00:00
|
|
|
@pyqtProperty(str, notify=statusChanged)
|
2021-04-01 14:32:43 +02:00
|
|
|
def server(self):
|
2023-03-30 00:40:55 +00:00
|
|
|
return self._server
|
2021-04-01 14:32:43 +02:00
|
|
|
|
2025-06-03 13:22:45 +02:00
|
|
|
@pyqtSlot(str, bool, bool)
|
qml: qenetwork: fix type confusion for "server"
exc triggered when switching from same server to same server:
```
9.43 | D | gui.qml.qenetwork | server_status updated: Connecting
9.43 | E | network | Exception in _run_new_interface: Exception('diagnostic name not yet available?')
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/logging.py", line 241, in __get_logger_for_obj
diag_name = self.diagnostic_name()
File "/home/user/wspace/electrum/electrum/interface.py", line 555, in diagnostic_name
return self.server.net_addr_str()
AttributeError: 'str' object has no attribute 'net_addr_str'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/util.py", line 1218, in wrapper
return await func(*args, **kwargs)
File "/home/user/wspace/electrum/electrum/network.py", line 986, in _run_new_interface
interface = Interface(network=self, server=server)
File "/home/user/wspace/electrum/electrum/interface.py", line 502, in __init__
Logger.__init__(self)
File "/home/user/wspace/electrum/electrum/logging.py", line 232, in __init__
self.logger = self.__get_logger_for_obj()
File "/home/user/wspace/electrum/electrum/logging.py", line 243, in __get_logger_for_obj
raise Exception("diagnostic name not yet available?") from e
Exception: diagnostic name not yet available?
```
2025-07-18 14:16:30 +00:00
|
|
|
def setServerParameters(self, server_str: str, auto_connect: bool, one_server: bool):
|
2021-12-01 01:02:52 +01:00
|
|
|
net_params = self.network.get_parameters()
|
qml: qenetwork: fix type confusion for "server"
exc triggered when switching from same server to same server:
```
9.43 | D | gui.qml.qenetwork | server_status updated: Connecting
9.43 | E | network | Exception in _run_new_interface: Exception('diagnostic name not yet available?')
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/logging.py", line 241, in __get_logger_for_obj
diag_name = self.diagnostic_name()
File "/home/user/wspace/electrum/electrum/interface.py", line 555, in diagnostic_name
return self.server.net_addr_str()
AttributeError: 'str' object has no attribute 'net_addr_str'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/util.py", line 1218, in wrapper
return await func(*args, **kwargs)
File "/home/user/wspace/electrum/electrum/network.py", line 986, in _run_new_interface
interface = Interface(network=self, server=server)
File "/home/user/wspace/electrum/electrum/interface.py", line 502, in __init__
Logger.__init__(self)
File "/home/user/wspace/electrum/electrum/logging.py", line 232, in __init__
self.logger = self.__get_logger_for_obj()
File "/home/user/wspace/electrum/electrum/logging.py", line 243, in __get_logger_for_obj
raise Exception("diagnostic name not yet available?") from e
Exception: diagnostic name not yet available?
```
2025-07-18 14:16:30 +00:00
|
|
|
server = ServerAddr.from_str_with_inference(server_str)
|
2025-06-03 13:22:45 +02:00
|
|
|
if server == net_params.server and auto_connect == net_params.auto_connect and one_server == net_params.oneserver:
|
2021-12-01 01:02:52 +01:00
|
|
|
return
|
qml: qenetwork: fix type confusion for "server"
exc triggered when switching from same server to same server:
```
9.43 | D | gui.qml.qenetwork | server_status updated: Connecting
9.43 | E | network | Exception in _run_new_interface: Exception('diagnostic name not yet available?')
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/logging.py", line 241, in __get_logger_for_obj
diag_name = self.diagnostic_name()
File "/home/user/wspace/electrum/electrum/interface.py", line 555, in diagnostic_name
return self.server.net_addr_str()
AttributeError: 'str' object has no attribute 'net_addr_str'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/util.py", line 1218, in wrapper
return await func(*args, **kwargs)
File "/home/user/wspace/electrum/electrum/network.py", line 986, in _run_new_interface
interface = Interface(network=self, server=server)
File "/home/user/wspace/electrum/electrum/interface.py", line 502, in __init__
Logger.__init__(self)
File "/home/user/wspace/electrum/electrum/logging.py", line 232, in __init__
self.logger = self.__get_logger_for_obj()
File "/home/user/wspace/electrum/electrum/logging.py", line 243, in __get_logger_for_obj
raise Exception("diagnostic name not yet available?") from e
Exception: diagnostic name not yet available?
```
2025-07-18 14:16:30 +00:00
|
|
|
if server != net_params.server:
|
|
|
|
|
if server is None:
|
2025-06-03 13:22:45 +02:00
|
|
|
if not auto_connect:
|
|
|
|
|
return
|
|
|
|
|
server = net_params.server
|
|
|
|
|
self.statusChanged.emit()
|
|
|
|
|
if auto_connect != net_params.auto_connect:
|
|
|
|
|
self.network.config.NETWORK_AUTO_CONNECT = auto_connect
|
|
|
|
|
self.autoConnectChanged.emit()
|
|
|
|
|
net_params = net_params._replace(server=server, auto_connect=auto_connect, oneserver=one_server)
|
2021-12-01 01:02:52 +01:00
|
|
|
self.network.run_from_another_thread(self.network.set_parameters(net_params))
|
|
|
|
|
|
2023-03-30 00:40:55 +00:00
|
|
|
@pyqtProperty(str, notify=statusChanged)
|
|
|
|
|
def serverWithStatus(self):
|
|
|
|
|
server = self._server
|
2023-04-14 15:55:03 +02:00
|
|
|
if not self.network.is_connected(): # connecting or disconnected
|
2023-09-22 16:34:28 +02:00
|
|
|
return f'{server} (connecting...)'
|
2023-03-30 00:40:55 +00:00
|
|
|
return server
|
|
|
|
|
|
2022-07-21 19:41:26 +02:00
|
|
|
@pyqtProperty(str, notify=statusChanged)
|
2021-04-01 14:32:43 +02:00
|
|
|
def status(self):
|
2023-03-17 10:15:07 +01:00
|
|
|
return self._network_status
|
|
|
|
|
|
|
|
|
|
@pyqtProperty(str, notify=statusChanged)
|
2023-04-25 14:15:13 +02:00
|
|
|
def serverStatus(self):
|
2023-04-14 15:55:03 +02:00
|
|
|
return self.network.get_connection_status_for_GUI()
|
|
|
|
|
|
|
|
|
|
@pyqtProperty(bool, notify=statusChanged)
|
2023-04-25 14:15:13 +02:00
|
|
|
def isConnected(self):
|
2023-04-14 15:55:03 +02:00
|
|
|
return self._is_connected
|
2021-04-01 14:32:43 +02:00
|
|
|
|
2022-07-21 19:41:26 +02:00
|
|
|
@pyqtProperty(int, notify=chaintipsChanged)
|
|
|
|
|
def chaintips(self):
|
|
|
|
|
return self._chaintips
|
|
|
|
|
|
|
|
|
|
@pyqtProperty(bool, notify=isLaggingChanged)
|
|
|
|
|
def isLagging(self):
|
|
|
|
|
return self._islagging
|
|
|
|
|
|
2021-04-07 16:48:40 +02:00
|
|
|
@pyqtProperty(bool, notify=dataChanged)
|
|
|
|
|
def isTestNet(self):
|
|
|
|
|
return constants.net.TESTNET
|
|
|
|
|
|
2022-07-21 19:41:26 +02:00
|
|
|
@pyqtProperty(str, notify=dataChanged)
|
2021-04-07 16:48:40 +02:00
|
|
|
def networkName(self):
|
2025-11-23 22:09:21 +01:00
|
|
|
return constants.net.__name__.replace('Bitcoin', 'Palladium')
|
2021-04-07 16:48:40 +02:00
|
|
|
|
2021-12-01 01:02:52 +01:00
|
|
|
@pyqtProperty('QVariantMap', notify=proxyChanged)
|
|
|
|
|
def proxy(self):
|
|
|
|
|
net_params = self.network.get_parameters()
|
2025-03-03 13:34:05 +01:00
|
|
|
proxy = net_params.proxy
|
|
|
|
|
return proxy.to_dict()
|
2021-12-01 01:02:52 +01:00
|
|
|
|
|
|
|
|
@proxy.setter
|
2025-03-03 13:34:05 +01:00
|
|
|
def proxy(self, proxy_dict):
|
2021-12-01 01:02:52 +01:00
|
|
|
net_params = self.network.get_parameters()
|
2025-03-03 13:34:05 +01:00
|
|
|
proxy = ProxySettings.from_dict(proxy_dict)
|
|
|
|
|
net_params = net_params._replace(proxy=proxy)
|
2021-12-01 01:02:52 +01:00
|
|
|
self.network.run_from_another_thread(self.network.set_parameters(net_params))
|
|
|
|
|
self.proxyChanged.emit()
|
2022-03-23 13:48:30 +01:00
|
|
|
|
2023-01-13 10:25:35 +01:00
|
|
|
proxyTorChanged = pyqtSignal()
|
|
|
|
|
@pyqtProperty(bool, notify=proxyTorChanged)
|
|
|
|
|
def isProxyTor(self):
|
2023-12-04 10:42:32 +01:00
|
|
|
return bool(self.network.is_proxy_tor)
|
2023-01-13 10:25:35 +01:00
|
|
|
|
2024-10-10 10:05:38 +02:00
|
|
|
@pyqtProperty(bool, notify=statusChanged)
|
|
|
|
|
def oneServer(self):
|
|
|
|
|
return self.network.oneserver
|
|
|
|
|
|
2022-06-15 11:39:46 +02:00
|
|
|
@pyqtProperty('QVariant', notify=feeHistogramUpdated)
|
2022-03-23 13:48:30 +01:00
|
|
|
def feeHistogram(self):
|
2022-07-21 13:24:32 +02:00
|
|
|
return self._fee_histogram
|
2022-03-23 13:48:30 +01:00
|
|
|
|
2022-07-22 12:49:09 +02:00
|
|
|
@pyqtProperty('QVariantMap', notify=gossipUpdated)
|
|
|
|
|
def gossipInfo(self):
|
|
|
|
|
return {
|
|
|
|
|
'peers': self._gossipPeers,
|
|
|
|
|
'unknown_channels': self._gossipUnknownChannels,
|
|
|
|
|
'db_nodes': self._gossipDbNodes,
|
2023-09-22 16:34:28 +02:00
|
|
|
'db_channels': self._gossipDbChannels,
|
2022-07-22 12:49:09 +02:00
|
|
|
'db_policies': self._gossipDbPolicies
|
|
|
|
|
}
|
2022-12-30 16:22:22 +01:00
|
|
|
|
|
|
|
|
serverListModelChanged = pyqtSignal()
|
|
|
|
|
@pyqtProperty(QEServerListModel, notify=serverListModelChanged)
|
|
|
|
|
def serverListModel(self):
|
|
|
|
|
if self._serverListModel is None:
|
|
|
|
|
self._serverListModel = QEServerListModel(self.network)
|
|
|
|
|
return self._serverListModel
|
2025-03-03 13:34:05 +01:00
|
|
|
|
|
|
|
|
@pyqtSlot()
|
|
|
|
|
def probeTor(self):
|
|
|
|
|
ProxySettings.probe_tor(self.torProbeFinished.emit) # via signal
|
2026-02-16 15:58:52 +01:00
|
|
|
|
|
|
|
|
@pyqtSlot(result=int)
|
|
|
|
|
def clearPinnedServerCertificates(self):
|
|
|
|
|
try:
|
|
|
|
|
return self.network.run_from_another_thread(self.network.clear_pinned_server_certs())
|
|
|
|
|
except Exception:
|
|
|
|
|
self._logger.exception("failed to clear pinned server certificates")
|
|
|
|
|
return -1
|
|
|
|
|
|
|
|
|
|
@pyqtSlot(result=int)
|
|
|
|
|
def clearRecentServers(self):
|
|
|
|
|
try:
|
|
|
|
|
return self.network.clear_recent_servers()
|
|
|
|
|
except Exception:
|
|
|
|
|
self._logger.exception("failed to clear recent servers")
|
|
|
|
|
return -1
|