Always use "." as decimal point, and " " as thousands separator.
Previously,
- for decimal point, we were using
- "." in some places (e.g. AmountEdit, most fiat amounts), and
- `locale.localeconv()['decimal_point']` in others.
- for thousands separator, we were using
- "," in some places (most fiat amounts), and
- " " in others (format_satoshis)
I think it is better to be consistent even if whatever we pick differs from the locale.
Using whitespace for thousands separator (vs comma) is probably less confusing for people
whose locale would user "." for ts and "," for dp (as in e.g. German).
The alternative option would be to always use the locale. Even if we decide to do that later,
this refactoring should be useful.
closes https://github.com/spesmilo/electrum/issues/2629
We poll the fx rate provider every 2.5 minutes (unchanged).
Previously if there was any error during a tick, there was no fx rate
available in the client until the next tick.
Now, instead, we keep the last rates received with a 10 minute expiry.
One potential drawback is that previously there was instant feedback
to the user when e.g. changing proxy settings, and this is no longer
the case. E.g. consider a provider that bans Tor exit nodes. If a user
enables using a Tor proxy in the network settings, the fxrate used to
disappear immediately - but now the cached rate would still be
available.
- separate AddressSynchronizer from Wallet and LNWatcher
- the AddressSynchronizer class is referred to as 'adb' (address database)
- Use callbacks to replace overloaded methods
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
- use_recoverable_channel is a user setting, available
only in standard wallets with a 'segwit' seed_type
- if enabled, 'lightning_xprv' is derived from seed
- otherwise, wallets use the existing 'lightning_privkey2'
Recoverable channels:
- channel recovery data is added funding tx using an OP_RETURN
- recovery data = 4 magic bytes + node id[0:16]
- recovery data is chacha20 encrypted using funding_address as nonce.
(this will allow to fund multiple channels in the same tx)
GUI:
- whether channels are recoverable is shown in wallet info dialog.
- if the wallet can have recoverable channels but has an old node_id,
users are told to close their channels and restore from seed
to have that feature.
Enables lightning by creating a node private key and storing it in
the wallet. The gossiper is not launched at start up, only if there
are existing channels.
The few other cases that used SimpleConfig.get_instance() now
either get passed a config instance, or they try to get a reference
to something else that has a reference to a config.
(see lnsweep, qt/qrcodewidget, qt/qrtextedit)
Previously commands did not run on the asyncio thread but now they do.
"restore" was polling like "while 1: time.sleep()", blocking the event loop.
Now "restore" does not sync the wallet; which is actually cleaner
as previously this wallet would never get unloaded from the daemon (syncing forever).
This is also symmetric with the "create" cmd which also does not try to sync with the network.
However now it became difficult to write a script that restores a wallet and wants to wait
until it gets synced. Workaround for now is to poll with "list_wallets" whether it's synced.
We could create a new command that blocks until the loaded wallet gets synced.
This should speed up synchronization / restoration of large wallets.
Wallets are written only when they switch to up_to_date state, or
when stop_threads() is called when closing the daemon, or when
a command line command finishes.