asyncio.get_event_loop() became deprecated in python3.10. (see https://github.com/python/cpython/issues/83710)
```
.../electrum/electrum/daemon.py:470: DeprecationWarning: There is no current event loop
self.asyncio_loop = asyncio.get_event_loop()
.../electrum/electrum/network.py:276: DeprecationWarning: There is no current event loop
self.asyncio_loop = asyncio.get_event_loop()
```
Also, according to that thread, "set_event_loop() [... is] not deprecated by oversight".
So, we stop using get_event_loop() and set_event_loop() in our own code.
Note that libraries we use (such as the stdlib for python <3.10), might call get_event_loop,
which then relies on us having called set_event_loop e.g. for the GUI thread. To work around
this, a custom event loop policy providing a get_event_loop implementation is used.
Previously, we have been using a single asyncio event loop, created with
util.create_and_start_event_loop, and code in many places got a reference to this loop
using asyncio.get_event_loop().
Now, we still use a single asyncio event loop, but it is now stored as a global in
util._asyncio_event_loop (access with util.get_asyncio_loop()).
I believe these changes also fix https://github.com/spesmilo/electrum/issues/5376
Scenario:
- 2of2 multisig wallet with device1 and device2
- disconnect all devices
- open wallet file
- fail all pairings at wallet-open
- connect device2
- try to sign a tx
At this point Electrum will try to find the device for keystore1 first, and there is only a single unpaired device: device2.
Automatic pairing of keystore1 and device2 will fail, due to device id mismatching compared to what is persisted on disk for keystore1, so the user is prompted for manual selection. The selection dialog is somewhat confusing as it is not clear that the app is asking to select a device for keystore1. Pairing would fail, so the user is expected to cancel the dialog. If they cancel, keystore1 is skipped, and we try to pair for keystore2 now, and device2 will pair with it automatically.
fixes https://github.com/spesmilo/electrum/issues/4199#issuecomment-1112552416
I had a ledger nano S and a ledger nano S plus connected at the same time,
and the "id_"s were colliding resulting in weird behaviour. Multisig was pretty
much not usable with both devices connected simultaneously.
Example dicts returned by `hid.enumerate(0, 0)`:
{'path': b'\\\\?\\hid#vid_2c97&pid_1015&mi_00#a&2a30{REDACTED}&0&0000#{REDACTED_UUID}', 'vendor_id': 11415, 'product_id': 4117, 'serial_number': '0001', 'release_number': 513, 'manufacturer_string': 'Ledger', 'product_string': 'Nano S', 'usage_page': 65440, 'usage': 1, 'interface_number': 0},
{'path': b'\\\\?\\hid#vid_2c97&pid_5011&mi_00#a&28d{REDACTED}&0&0000#{REDACTED_UUID}', 'vendor_id': 11415, 'product_id': 20497, 'serial_number': '0001', 'release_number': 513, 'manufacturer_string': 'Ledger', 'product_string': 'Nano S Plus', 'usage_page': 65440, 'usage': 1, 'interface_number': 0}
see https://github.com/spesmilo/electrum/issues/5376
crash report for electrum 4.2.1:
```
Traceback (most recent call last):
File "/home/user/wspace/electrum/.buildozer/android/platform/build-arm64-v8a/build/python-installs/Electrum/kivy/base.py", line 347, in mainloop
File "/home/user/wspace/electrum/.buildozer/android/platform/build-arm64-v8a/build/python-installs/Electrum/kivy/base.py", line 391, in idle
File "/home/user/wspace/electrum/.buildozer/android/platform/build-arm64-v8a/build/python-installs/Electrum/kivy/base.py", line 342, in dispatch_input
File "/home/user/wspace/electrum/.buildozer/android/platform/build-arm64-v8a/build/python-installs/Electrum/kivy/base.py", line 308, in post_dispatch_input
File "kivy/_event.pyx", line 724, in kivy._event.EventDispatcher.dispatch
File "/home/user/wspace/electrum/.buildozer/android/platform/build-arm64-v8a/build/python-installs/Electrum/kivy/uix/behaviors/button.py", line 179, in on_touch_up
File "kivy/_event.pyx", line 720, in kivy._event.EventDispatcher.dispatch
File "kivy/_event.pyx", line 1263, in kivy._event.EventObservers.dispatch
File "kivy/_event.pyx", line 1147, in kivy._event.EventObservers._dispatch
File "/home/user/wspace/electrum/.buildozer/android/platform/build-arm64-v8a/build/python-installs/Electrum/kivy/lang/builder.py", line 57, in custom_callback
File "<string>", line 42, in <module>
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/gui/kivy/uix/dialogs/wallets.py", line 70, in cb
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/gui/kivy/main_window.py", line 710, in load_wallet_by_name
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/gui/kivy/main_window.py", line 728, in on_open_wallet
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/gui/kivy/main_window.py", line 691, in on_wizard_success
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/wallet.py", line 3267, in __new__
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/wallet.py", line 3111, in __init__
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/wallet.py", line 2904, in __init__
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/wallet.py", line 288, in __init__
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/address_synchronizer.py", line 97, in __init__
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/wallet.py", line 402, in load_and_cleanup
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/address_synchronizer.py", line 106, in load_and_cleanup
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/util.py", line 439, in <lambda>
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/util.py", line 435, in do_profile
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/address_synchronizer.py", line 432, in load_local_history
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/address_synchronizer.py", line 533, in _add_tx_to_local_history
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/address_synchronizer.py", line 548, in _mark_address_history_changed
File "/home/user/wspace/electrum/.buildozer/android/platform/build-arm64-v8a/build/other_builds/python3/arm64-v8a__ndk_target_21/python3/Lib/asyncio/locks.py", line 260, in __init__
File "/home/user/wspace/electrum/.buildozer/android/platform/build-arm64-v8a/build/other_builds/python3/arm64-v8a__ndk_target_21/python3/Lib/asyncio/events.py", line 639, in get_event_loop
RuntimeError: There is no current event loop in thread 'GUI'.
```
see https://github.com/spesmilo/electrum/issues/5376
crash report for electrum 4.2.1:
```
Traceback (most recent call last):
File "/home/user/wspace/electrum/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/Electrum/kivy/base.py", line 347, in mainloop
File "/home/user/wspace/electrum/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/Electrum/kivy/base.py", line 391, in idle
File "/home/user/wspace/electrum/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/Electrum/kivy/base.py", line 342, in dispatch_input
File "/home/user/wspace/electrum/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/Electrum/kivy/base.py", line 308, in post_dispatch_input
File "kivy/_event.pyx", line 724, in kivy._event.EventDispatcher.dispatch
File "/home/user/wspace/electrum/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/Electrum/kivy/uix/behaviors/button.py", line 179, in on_touch_up
File "kivy/_event.pyx", line 720, in kivy._event.EventDispatcher.dispatch
File "kivy/_event.pyx", line 1263, in kivy._event.EventObservers.dispatch
File "kivy/_event.pyx", line 1147, in kivy._event.EventObservers._dispatch
File "/home/user/wspace/electrum/.buildozer/android/platform/build-armeabi-v7a/build/python-installs/Electrum/kivy/lang/builder.py", line 57, in custom_callback
File "<string>", line 39, in <module>
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/gui/kivy/uix/dialogs/settings.py", line 173, in cb
File "kivy/properties.pyx", line 498, in kivy.properties.Property.__set__
File "kivy/properties.pyx", line 545, in kivy.properties.Property.set
File "kivy/properties.pyx", line 600, in kivy.properties.Property.dispatch
File "kivy/_event.pyx", line 1263, in kivy._event.EventObservers.dispatch
File "kivy/_event.pyx", line 1169, in kivy._event.EventObservers._dispatch
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/gui/kivy/main_window.py", line 206, in on_use_gossip
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/network.py", line 368, in start_gossip
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/channel_db.py", line 308, in __init__
File "/home/user/wspace/electrum/.buildozer/android/app/electrum/sql_db.py", line 30, in __init__
File "/home/user/wspace/electrum/.buildozer/android/platform/build-armeabi-v7a/build/other_builds/python3/armeabi-v7a__ndk_target_21/python3/Lib/asyncio/locks.py", line 260, in __init__
File "/home/user/wspace/electrum/.buildozer/android/platform/build-armeabi-v7a/build/other_builds/python3/armeabi-v7a__ndk_target_21/python3/Lib/asyncio/events.py", line 639, in get_event_loop
RuntimeError: There is no current event loop in thread 'GUI'.
```
The call to super was removed in 4efcb53d24 ,
so that LNWallet's taskgroup would not run _maintain_connectivity, AFAICT.
The way it was done meant that "main_loop" itself would not run for LNWallet, only for LNGossip - very confusing.
It is only due to a quirk in the behaviour of TaskGroups that the group "started" at all.
Change convert_version_25 to delete invoices instead of converting them.
convert_version_25 was released ~2 years ago. Wallet files not opened since will have old bip70 invoices deleted upon upgrading.
In general it is ~unsafe for convert_version_* to depend on other modules of the code.
(using e.g. sha256 is fine as its API will never change,
but using e.g. PaymentRequest is dangerous as its API might change over time)
```
Traceback (most recent call last):
File "...\electrum\electrum\gui\qt\main_window.py", line 898, in timer_actions
self.update_wallet()
File "...\electrum\electrum\gui\qt\main_window.py", line 1040, in update_wallet
self.update_tabs()
File "...\electrum\electrum\gui\qt\main_window.py", line 1047, in update_tabs
self.history_model.refresh('update_tabs')
File "...\electrum\electrum\util.py", line 439, in <lambda>
return lambda *args, **kw_args: do_profile(args, kw_args)
File "...\electrum\electrum\util.py", line 435, in do_profile
o = func(*args, **kw_args)
File "...\electrum\electrum\gui\qt\history_list.py", line 275, in refresh
transactions = wallet.get_full_history(
File "...\electrum\electrum\util.py", line 439, in <lambda>
return lambda *args, **kw_args: do_profile(args, kw_args)
File "...\electrum\electrum\util.py", line 435, in do_profile
o = func(*args, **kw_args)
File "...\electrum\electrum\wallet.py", line 947, in get_full_history
lnworker_history = self.lnworker.get_onchain_history() if self.lnworker and include_lightning else {}
File "...\electrum\electrum\lnworker.py", line 911, in get_onchain_history
tx_height = self.lnwatcher.get_tx_height(swap.funding_txid)
AttributeError: 'NoneType' object has no attribute 'get_tx_height'
```
E | gui.qt.ElectrumGui |
Traceback (most recent call last):
File "...\electrum\electrum\gui\qt\__init__.py", line 361, in start_new_window
window = self._create_window_for_wallet(wallet)
File "...\electrum\electrum\gui\qt\__init__.py", line 304, in _create_window_for_wallet
w = ElectrumWindow(self, wallet)
File "...\electrum\electrum\gui\qt\main_window.py", line 223, in __init__
self.send_tab = self.create_send_tab()
File "...\electrum\electrum\gui\qt\main_window.py", line 1537, in create_send_tab
self.invoice_list = InvoiceList(self)
File "...\electrum\electrum\gui\qt\invoice_list.py", line 76, in __init__
self.update()
File "...\electrum\electrum\gui\qt\invoice_list.py", line 109, in update
amount = item.get_amount_sat()
File "...\electrum\electrum\invoices.py", line 158, in get_amount_sat
return int(amount_msat / 1000)
TypeError: unsupported operand type(s) for /: 'str' and 'int'