The Qt GUI refreshes all tabs on 'blockchain_updated', which is expensive for very large wallets.
Previously, on every new block, the GUI would get one notification for each connected interface,
now only the fastest interface triggers it.
(was testing with a wallet where refreshing all tabs takes 15 seconds, and 10*15 seconds is
even more annoying...)
Note in particular that _RSClient.__aexit__ calls session.close()
so a lot of time can pass between interface.taskgroup raising and
handle_disconnect seeing the exception.
related https://github.com/spesmilo/electrum/issues/7677
closes https://github.com/spesmilo/electrum/issues/7677
```
E/n | network | taskgroup died.
Traceback (most recent call last):
File "/opt/electrum/electrum/network.py", line 1204, in main
[await group.spawn(job) for job in self._jobs]
File "/home/voegtlin/.local/lib/python3.8/site-packages/aiorpcx/curio.py", line 297, in __aexit__
await self.join()
File "/opt/electrum/electrum/util.py", line 1255, in join
task.result()
File "/opt/electrum/electrum/network.py", line 1277, in _maintain_sessions
await maintain_main_interface()
File "/opt/electrum/electrum/network.py", line 1268, in maintain_main_interface
await self._ensure_there_is_a_main_interface()
File "/opt/electrum/electrum/network.py", line 1245, in _ensure_there_is_a_main_interface
await self._switch_to_random_interface()
File "/opt/electrum/electrum/network.py", line 648, in _switch_to_random_interface
await self.switch_to_interface(random.choice(servers))
File "/opt/electrum/electrum/network.py", line 714, in switch_to_interface
await i.taskgroup.spawn(self._request_server_info(i))
File "/home/voegtlin/.local/lib/python3.8/site-packages/aiorpcx/curio.py", line 204, in spawn
self._add_task(task)
File "/home/voegtlin/.local/lib/python3.8/site-packages/aiorpcx/curio.py", line 150, in _add_task
raise RuntimeError('task group terminated')
RuntimeError: task group terminated
```
I believe the "suppress spurious cancellations" block was added as SilentTaskGroup raised
CancelledError instead of RuntimeError for this scenario.
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
I think this was originally needed due to incorrect management of group lifecycles,
which our current code is doing better.
also note that if we needed this, in newer aiorpcx, the name of
the field was ~changed from `_closed` to `joined`:
239002689a
When receiving the history of an address, the client behaved unexpectedly
if either of two checks failed.
The client checked that the txids in the history are unique, and that the
history matches the previously announced status. If either failed, it
would just log a line and do nothing. Importantly, the synchronizer could
even consider itself is_up_to_date, i.e. the GUI could show the wallet is
synced.
This is now changed such that:
- if the txid uniqueness test fails, we simply disconnect
- if the history is not consistent with previously announced status,
we wait a bit, make sure is_up_to_date is False in the meantime,
and then potentially disconnect
See rationale for these in the comments.
related: https://github.com/spesmilo/electrum/issues/7058#issuecomment-783613084
This was a regression from e83f0dd3fc,
introduced by the change in connection_down() there.
(if the initial connection to the main interface is not successful, the
network status will not be set to 'disconnected' - but it should be)
That change is now reverted here.
That change was somewhat independent of the rest of that commit,
except the rest highlighted that something of the sort was needed:
as it might sometimes take many seconds for an interface to close
and we might launch another interface for the same server while the
first one is still closing, the "server == self.default_server" test
is highly problematic.
To fix this second - original - issue, we now introduce a "closing" state
for interfaces (in the form of network._closing_ifaces).
The GUI blocks until network.set_parameters returns when switching servers,
which waits for switch_to_interface, which used to wait until interface.close()
returns. interface.close() tries to flush buffered writes to the wire, with a
30 sec timeout.
If the server or the network connection is slow, flushing the buffer can take
several seconds. In particular, servers running Fulcrum always seem to
timeout in this case, freezing the GUI for 30 seconds (when switching away).
* network-dialog: include protocol in server field
In this way it is now possible again to use plain server connections
without reverting it automatically to tls connections.
* qt network dialog: hide trailing protocol ":s" in TextEdit
This hides some complexity from casual users, while still allowing
advanced users to set the protocol.
Co-authored-by: SomberNight <somber.night@protonmail.com>
some basic sanity checks
Previously if the server sent back a malformed response, it could partially corrupt a wallet file.
(as sometimes the response would get persisted, and issues would only arise later when the values were used)
* Add --fingerprint option
* Simplify conditional checks
* Improve warning wording
* Throw error instead of logging and returning
* --fingerprint => --serverfingerprint
* Only run fingerprint checks against main server
* Throw error if --serverfingerprint is set for a non SSL main server
* Fix linting errors
* Don't check certificate fingerprint in a seperate connection
* Disallow CA signed certs when a fingerprint is provided
* Show clear error and then exit for Qt GUI users
* Remove leading newlines from error dialog
* Always check is_main_server() when getting fingerprint
* Document how to generate SSL cert fingerprint