aiorpcx 0.20 changed the behaviour/API of TaskGroups.
When used as a context manager, TaskGroups no longer propagate
exceptions raised by their tasks. Instead, the calling code has
to explicitly check the results of tasks and decide whether to re-raise
any exceptions.
This is a significant change, and so this commit introduces "OldTaskGroup",
which should behave as the TaskGroup class of old aiorpcx. All existing
usages of TaskGroup are replaced with OldTaskGroup.
closes https://github.com/spesmilo/electrum/issues/7446
The daemon by default listens for RPC over a socket.
Before this change, this socket was a TCP/IP network socket (over localhost),
but now we change it to be a unix domain socket by default (if available).
This socket is used not only when sending commands over JSON-RPC,
but also when using the CLI, and to a tiny extent even used when running the GUI.
The type of socket used (and hence this change) is invisible to CLI and GUI users.
JSON-RPC users might want to use either the --rpcsock CLI flag
or set the "rpcsock" config key (to "tcp") to switch back to using a TCP/IP socket.
In practice it seems unix domain sockets are available on
all mainstream OSes/platforms, except for Windows.
closes https://github.com/spesmilo/electrum/issues/7553
If daemon.taskgroup dies
- in GUI mode, show a crash reporter window to the user,
instead of immediately stopping the whole process.
- in daemon mode, log exception and stop process, as before.
- 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
The gossip db is loaded early when the network is started to save
time when the gui is locked and a wallet not yet loaded. Side effects
of the LNWallet to start peering when a channel db is loaded is
circumvented.
Before commit 46ffab0b55 all of these used to work:
./run_electrum -o signmessage tb1qeh090ruc3cs5hry90tev4fsvrnegulw8xssdzx "asdasd" -w ~/.electrum/testnet/wallets/test_segwit_2 --testnet
./run_electrum -o signmessage -w ~/.electrum/testnet/wallets/test_segwit_2 tb1qeh090ruc3cs5hry90tev4fsvrnegulw8xssdzx "asdasd" --testnet
./run_electrum -w ~/.electrum/testnet/wallets/test_segwit_2 -o signmessage tb1qeh090ruc3cs5hry90tev4fsvrnegulw8xssdzx "asdasd" --testnet
Since then, the last one no longer works.
Related: 9d2ede8796
- some commands expect a 'wallet_path' arg, while others expect 'wallet'
- 'wallet_path' in the end is supposed to be a str,
'wallet' in the end is supposed to be an Optional[Abstract_Wallet]
- initially, in the decorator, 'wallet' can be a str, in which case
the decorator replaces it with an Abstract_Wallet (from the daemon)
- Previously the decorator sometimes converted 'wallet_path' to 'wallet'.
This was because when called from the CLI it was always given 'wallet_path' (and never 'wallet),
while when called from JSON-RPC it was given either 'wallet' or 'wallet_path' (depending on command).
Now, the CLI also behaves as JSON-RPC, and hence 'wallet_path' and 'wallet' are fully separate.
- A bug is fixed where, when a command that only optionally takes a 'wallet' (such as gettransaction),
was called from the JSON-RPC with the arg present, it raised; and when called from CLI with the arg present
the arg was not actually passed to the command.
- A bug is fixed where if one command calls another command (that both take a 'wallet'),
it would raise (due to assuming 'wallet' is str and needs to be converted to Abstract_Wallet).
This fixes#6154.
-----
$ ./run_electrum --testnet daemon -d
$ ./run_electrum --testnet load_wallet -w ~/.electrum/testnet/wallets/default_wallet
$ curl --data-binary '{"id":"curltext","jsonrpc":"2.0","method":"gettransaction","params":{"txid":"9f43ff71ea2594873e4e7d15e61254a3661ff2df1af76325c854d9aa199550ce"}}' http://user:pass@127.0.0.1:7777
{"jsonrpc": "2.0", "result": "0200000001caaac6b5eb916e3067d0224f942fb331ce1dcfb4031cfb479e7941dcf95e409801000000fdfe0000483045022100e2a508bb78c2172eb03f081a342454ba1d24669e959700973b1a742a4fedd0c302203174e06feda265031cf9aa0364d4a4eafb71b0c0a62e76be7795cfbb307b677a01483045022100d0e14564838fac754395158741d64c73da2b86e7900dfdc6a63c7492b232ba130220778e7e7c21d94ebcd340057302aeff7e9a797a3aa3e0ac4884e9ff27339ea6e9014c69522102091f0b4d8ab30016a5d1c088249e02883fad8160f06fa53588ad8598650a3e6221035f2f8263bb3608d6cc4ee03bd4cb8d65c4d70af71049f05fbfee4978832a1fd22103fe42dab58718ea0413f7c8de693cdeee22ce19b1dc34c0bbdd7a48245465c5a253aefdffffff01cb9f0700000000001976a914c13fd6294d1be7b9410a5538f4b4ef10fc594ee788ac802c1800", "id": "curltext"}
$ curl --data-binary '{"id":"curltext","jsonrpc":"2.0","method":"gettransaction","params":{"txid":"9f43ff71ea2594873e4e7d15e61254a3661ff2df1af76325c854d9aa199550ce", "wallet":"~/.electrum/testnet/wallets/default_wallet"}}' http://user:pass@127.0.0.1:7777
{"jsonrpc": "2.0", "error": {"code": -32000, "message": "'str' object has no attribute 'db'"}, "id": "curltext"}
previously, if GUI-related imports raised, the GUI would not start
but the process would not exit (e.g. asyncio event loop would go on)
Traceback (most recent call last):
File "...\electrum\electrum\daemon.py", line 517, in run_gui
gui = __import__('electrum.gui.' + gui_name, fromlist=['electrum'])
File "...\electrum\electrum\gui\qt\__init__.py", line 39, in <module>
from PyQt5.QtGui import QGuiApplication
ImportError: DLL load failed while importing QtGui: The specified module could not be found.