- lnworker.channels takes a copy of the whole dict, to make it thread-safe
- in LNWallet class, can just use self._channels.get(chan_id)
- otherwise there is lnworker.get_channel_by_id
- same for lnpeer.channels.get and lnpeer.get_channel_by_id
We tried to delete incoming channels that didn't get funded after
lnutil.CHANNEL_OPENING_TIMEOUT, however an assert prevented this:
```
3.63 | E | lnwatcher.LNWatcher.[default_wallet-LNW] | Exception in check_onchain_situation: AssertionError()
Traceback (most recent call last):
File "/home/user/code/electrum-fork/electrum/util.py", line 1233, in wrapper
return await func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/code/electrum-fork/electrum/lnwatcher.py", line 117, in check_onchain_situation
await self.update_channel_state(
...<5 lines>...
keep_watching=keep_watching)
File "/home/user/code/electrum-fork/electrum/lnwatcher.py", line 135, in update_channel_state
chan.update_onchain_state(
~~~~~~~~~~~~~~~~~~~~~~~~~^
funding_txid=funding_txid,
^^^^^^^^^^^^^^^^^^^^^^^^^^
...<2 lines>...
closing_height=closing_height,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
keep_watching=keep_watching)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/code/electrum-fork/electrum/lnchannel.py", line 341, in update_onchain_state
self.update_unfunded_state()
~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/home/user/code/electrum-fork/electrum/lnchannel.py", line 382, in update_unfunded_state
self.lnworker.remove_channel(self.channel_id)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/home/user/code/electrum-fork/electrum/lnworker.py", line 3244, in remove_channel
assert chan.can_be_deleted()
~~~~~~~~~~~~~~~~~~~^^
AssertionError
```
Adds the invoice features to the `PaymentInfo` class so we can check if
the sender respects our requested features (e.g. if they tried to send
mpp if we requested no mpp).
Store the channel id instead of the scid in ReceivedMPPHtlc.
The scid can be None, in theory even for multiple channels at the same
time. Using the channel_id which is always available and unique seems
less error prone at the cost of temporarily higher storage requirements
in the db for the duration of the pending htlcs.
Alternatively we could use the local scid alias however using the
channel_id seems less complex and leaves less room for ambiguity.
Deduct the just in time channel opening fees from the total amount so
htlcs don't get timed out if they come from a just in time channel with
opening fee.
Related: https://github.com/spesmilo/electrum/pull/9584
Calling dnssec.query() with missing "cryptography" dep behaves the same as if DNSSEC validation failed: validated=False will be returned.
When used for openalias, we mandate validated=True.
Allows replacing a saved `PaymentInfo` of `SENT` direction if the old
one is not yet paid.
This allows the user to retry paying a 0 amount invoice with different
amount if the previous attempt failed.
Allows storing two different payment info of the same payment hash by
including the direction into the db key.
We create and store PaymentInfo for sending attempts and for requests (receiving),
if we try to pay ourself (e.g. through a channel rebalance) the checks
in `save_payment_info` would prevent this and throw an exception.
By storing the PaymentInfos of outgoing and incoming payments separately in
the db this collision is avoided and it makes it easier to reason about
which PaymentInfo belongs where.
I was unable to do a "Max" amount submarine swap because the
`fee_estimate` method used by `LNWallet.num_sats_can_send()` uses a
hardcoded `fee_proportional_millionths` to estimate the fee for the
lightning payment.
When the actual fee determined later is higher
than the estimated fee the payment fails as the channel is unable to add
the htlc sum including the real fees as the amount exceeds the balance of
the channel.
Using the fees the maximum fees user has configured and estimate the
potential fee as inverse of PaymentFeeBudget is more
reliable/conservative as we definitely aren't going to pay more fees
than this amount.
When moving the lightning fee slider in the SettingsDialog by clicking
on the range instead of pulling the slider the new fee value wouldn't
get stored in the config as the sliderRelased signal is only emitted
when the slider is pulled.
This change updates it on valueChanged.