similar to 05fd424548
from logs when running tests:
--- Logging error ---
Traceback (most recent call last):
File "...\Python39\lib\logging\__init__.py", line 1082, in emit
stream.write(msg + self.terminator)
ValueError: I/O operation on closed file.
Call stack:
File "...\Python39\lib\threading.py", line 912, in _bootstrap
self._bootstrap_inner()
File "...\Python39\lib\threading.py", line 954, in _bootstrap_inner
self.run()
File "...\Python39\lib\threading.py", line 892, in run
self._target(*self._args, **self._kwargs)
File "...\electrum\electrum\sql_db.py", line 71, in run_sql
self.logger.info("SQL thread terminated")
Message: 'SQL thread terminated'
Arguments: ()
- trampoline is enabled by default in config, to prevent download of `gossip_db`.
(if disabled, `gossip_db` will be downloaded, regardless of the existence of channels)
- if trampoline is enabled:
- the wallet can only open channels with trampoline nodes
- already-existing channels with non-trampoline nodes are frozen for sending.
- there are two types of trampoline payments: legacy and end-to-end (e2e).
- we decide to perform legacy or e2e based on the invoice:
- we use trampoline_routing_opt in features to detect Eclair and Phoenix invoices
- we use trampoline_routing_hints to detect Electrum invoices
- when trying a legacy payment, we add a second trampoline to the path to preserve privacy.
(we fall back to a single trampoline if the payment fails for all trampolines)
- the trampoline list is hardcoded, it will remain so until `trampoline_routing_opt` feature flag is in INIT.
- there are currently only two nodes in the hardcoded list, it would be nice to have more.
- similar to Phoenix, we find the fee/cltv by trial-and-error.
- if there is a second trampoline in the path, we use the same fee for both.
- the final spec should add fee info in error messages, so we will be able to fine-tune fees
exceptions below are raised when running python3 with "-X dev":
Traceback (most recent call last):
File "...\electrum\electrum\util.py", line 999, in run_with_except_hook
run_original(*args2, **kwargs2)
File "...\Python38\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "...\electrum\electrum\sql_db.py", line 55, in run_sql
future.set_result(result)
File "...\Python38\lib\asyncio\base_events.py", line 721, in call_soon
self._check_thread()
File "...\Python38\lib\asyncio\base_events.py", line 758, in _check_thread
raise RuntimeError(
RuntimeError: Non-thread-safe operation invoked on an event loop other than the current one
Traceback (most recent call last):
File "...\electrum\electrum\gui\qt\main_window.py", line 3009, in closeEvent
self.clean_up() #
File "...\electrum\electrum\gui\qt\main_window.py", line 3026, in clean_up
self.gui_object.close_window(self)
File "...\electrum\electrum\gui\qt\__init__.py", line 340, in close_window
self.daemon.stop_wallet(window.wallet.storage.path)
File "...\electrum\electrum\daemon.py", line 518, in stop_wallet
wallet.stop()
File "...\electrum\electrum\wallet.py", line 344, in stop
self.lnworker.stop()
File "...\electrum\electrum\lnworker.py", line 602, in stop
super().stop()
File "...\electrum\electrum\lnworker.py", line 273, in stop
self.listen_server.close()
File "...\Python38\lib\asyncio\base_events.py", line 337, in close
self._loop._stop_serving(sock)
File "...\Python38\lib\asyncio\proactor_events.py", line 849, in _stop_serving
future.cancel()
File "...\Python38\lib\asyncio\windows_events.py", line 80, in cancel
return super().cancel()
File "...\Python38\lib\asyncio\base_events.py", line 721, in call_soon
self._check_thread()
File "...\Python38\lib\asyncio\base_events.py", line 758, in _check_thread
raise RuntimeError(
RuntimeError: Non-thread-safe operation invoked on an event loop other than the current one