- new version of flake8-bugbear (24.1.16) introduced new tests (B036), which we were failing
- that's fine, but our CI should not suddenly break because of this
- better to do explicit manual version bumps of the linter
In particular, lnd sends both chan_reest and then an error ("sync error").
It is critical we process the chan_reest and transition to WE_ARE_TOXIC before
processing the error (which would trigger us to force-close).
see spec 8a64c6a1ce/02-peer-protocol.md (L1504-L1506) :
> - upon reconnection:
> [...]
> - MUST transmit channel_reestablish for each channel.
> - MUST wait to receive the other node's channel_reestablish message before sending any other messages for that channel.
if the remote does not know we are behind, they will try to send us chan_reest
```
38.52 | W | P/lnpeer.Peer.[LNWallet, 034cd7a09f-ed50cf95] | channel_reestablish (533x1x1): remote is ahead of us! They should force-close. Remote PCP: 03857eabd943eec820d56b94d2f162763294565627cc42c4a0db0e7c6b77da46be
38.52 | E | P/lnpeer.Peer.[LNWallet, 034cd7a09f-ed50cf95] | Exception in main_loop: Exception('Transition not allowed: WE_ARE_TOXIC -> WE_ARE_TOXIC')
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/util.py", line 1148, in wrapper
return await func(*args, **kwargs)
File "/home/user/wspace/electrum/electrum/lnpeer.py", line 426, in wrapper_func
return await func(self, *args, **kwargs)
File "/home/user/wspace/electrum/electrum/lnpeer.py", line 440, in main_loop
async with self.taskgroup as group:
File "/home/user/.local/lib/python3.10/site-packages/aiorpcx/curio.py", line 297, in __aexit__
await self.join()
File "/home/user/wspace/electrum/electrum/util.py", line 1319, in join
task.result()
File "/home/user/wspace/electrum/electrum/lnpeer.py", line 1231, in on_channel_reestablish
chan.set_state(ChannelState.WE_ARE_TOXIC)
File "/home/user/wspace/electrum/electrum/lnchannel.py", line 215, in set_state
raise Exception(f"Transition not allowed: {old_state.name} -> {state.name}")
Exception: Transition not allowed: WE_ARE_TOXIC -> WE_ARE_TOXIC
```
Assume Alice and Bob have a channel, and Alice is on an old state,
but neither of them knows the latter yet.
Timing scenarios:
1. Alice sends reest first, and Bob receives it before sending reest himself
- old code: Bob realises Alice is behind, Bob will force-close,
Bob won't send reest to Alice, so Alice does not learn she is behind
- new code: Bob realises Alice is behind, Bob will force-close,
Bob will still send reest to Alice, so Alice learns she is behind.
2. Bob sends reest first, and Alice receives it before sending reest herself
- old code: Alice learns she is behind. Alice won't send reest to Bob,
so Bob does not learn he is ahead, so Bob won't force-close.
- new code: Alice learns she is behind. Alice will still send reest to Bob
though with ctn=0 instead of actual. Bob learns he is ahead, so
Bob will force close.
3. Alice and Bob both send reest, and then they both receive what the other sent
- no change: Alice and Bob both learn Alice is behind. Bob will force-close.
lnworker.suggest_splits for non-trampoline case tries to split amts over 5000 sat
but mpp_split.suggest_splits does not return splits where any part is smaller than 10000 sat.
So in practice, without trampoline, invoices between 5k and ~20k sats could not be paid.
This suggests that the logic should not be scattered in multiple places but merged into mpp_split.py...
This commit just does a quick fix though, to try again without splitting if there was no solution.
"18 pixels" is too large when using qdarkstyle on "low" DPI screens, on Windows
(if there is also a high DPI screen connected as another monitor... eh)
- without this, in send tab paytoedit, try_payment_identifier will get called and it will error
df1b9a223c/electrum/gui/qt/paytoedit.py (L153)
- also, in all text fields this used to result in clearing the current text (but now it is kept instead)
```
25.30 | E | gui.qt.exception_window.Exception_Hook | exception caught by crash reporter
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/gui/qt/__init__.py", line 439, in _start_wizard_to_select_or_create_wallet
wallet = self.daemon.load_wallet(wallet_file, d['password'], upgrade=True)
File "/home/user/wspace/electrum/electrum/daemon.py", line 481, in func_wrapper
return func(self, *args, **kwargs)
File "/home/user/wspace/electrum/electrum/daemon.py", line 491, in load_wallet
wallet = self._load_wallet(path, password, upgrade=upgrade, config=self.config)
File "/home/user/wspace/electrum/electrum/util.py", line 481, in do_profile
o = func(*args, **kw_args)
File "/home/user/wspace/electrum/electrum/daemon.py", line 516, in _load_wallet
raise WalletUnfinished(db)
electrum.wallet_db.WalletUnfinished: <electrum.wallet_db.WalletDB object at 0x7f11db3a7ca0>
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/user/wspace/electrum/electrum/gui/qt/wizard/wizard.py", line 203, in on_next_button_clicked
if self.is_finalized(wd):
File "/home/user/wspace/electrum/electrum/gui/qt/wizard/wallet.py", line 178, in is_finalized
if not wizard_data['wallet_exists'] or wizard_data['wallet_is_open']:
KeyError: 'wallet_exists'
```
With wallet_type=="standard", if the user enters a 2fa electrum seed, the "next" btn is disabled.
This is a regression in the new wizard, the old one used to "redirect" seamlessly.
This commit does not fix this, but at least shows a user-friendly warning message.
Note: would be nice if the wizard redirected automatically, in both directions (2fa->std, std->2fa).
The old wizard implemented std->2fa (probably the more common case hit by users), and had this
warning message shown for the 2fa->std case. Now I am repurposing the warning also for std->2fa.