If a trampoline forwarder fails to find a path, it may return a list
of trampolines it knows how to reach, so that clients can add these
trampolines to their route.
The list of trampolines and fees is written in the error data of
the 'update_fail_htlc' message.
The LnAddr, lndecode and lnencode naming didn't imply that it is
bolt 11 specific, making it confusing to work with, now that there are
also bolt 12 "lnaddr".
Renaming it to *bolt11* creates a clear separation to bolt 12 things and
reduces mental load.
This commit is pure renaming (using the PyCharm IDE refactor function),
except for the removal of the `object` inheritance of LnAddr/BOLT11Addr,
this is Python 2 legacy.
Only signal `OPTION_ZEROCONF_OPT` to peers if we either:
1. Have no trusted peer configured (assuming that we are LSP)
2. Have a trusted peer configured, and the peer we are connecting
to is this trusted peer.
Otherwise peers that are LSPs but are not the clients trusted LSP
might try to open a channel to the client but it would get rejected.
Make the just in time channel fees and channel size
configvars, as in practice not every provider would
use the same hardcoded fees or channel sizes.
Add the mining fees required for the funding transaction on top of the
opening fees to prevent opening channels at a loss in a higher
fee environment.
Adds cleanup logic to `LNWallet.open_channel_just_in_time` so
that the channel provider removes unfunded channels again, e.g. if
the client didn't release the preimage or the provider failed
to broadcast the funding transaction.
Also adds more robust transaction broadcast logic so we retry to
broadcast if it failed and check against adb to see if any previous
broadcast was successful.
...so we can have multiple just in time channels with the same lsp.
We already save a remote scid alias in `on_channel_ready` which we
already have received after the new zeroconf channel is in open state.
So setting the alias to the static node id hash is counterproductive
because it doesn't allow to differentiate between channels.
Also extends the regtest (`just_in_time`) to do a second channel
opening, to cover this scenario. This doesn't add much runtime to
the test, so the cost seems reasonable.
On LSP side we were only checking if ACCEPT_ZEROCONF_CHANNELS
is enabled while forwarding a non-trampoline htlc.
During trampoline forwarding the config was ignored.
The ACCEPT_* prefix implied this was only for accepting inbound
zeroconf channels, but it also controls whether we open them when
forwarding HTLCs.
Renames the config var to OPEN_ZEROCONF_CHANNELS
to clarify it enables zeroconf channel opens in both directions,
and add the missing check when forwarding trampoline HTLCs.
Make the trampoline signaling in bolt11 invoices dependent upon all
unfrozen channels being with trampoline peers instead of the trampoline
config.
Stops automatically freezing non-trampoline channels for receiving if
trampoline is enabled.
One effect of this change is that now we don't signal trampoline support
anymore in the invoice even if trampoline is enabled, if one of the
channels is with a non trampoline peer.
"When should we reveal preimages onchain?"
This commit tries to simplify the thinking by making the observation:
- we can reveal preimages (actually in any context) if they are already public
- a preimage is public if any other lightning node knows it besides us
- if we learn the preimage from another LN node, it is public
- if we send update_fulfill_htlc, it becomes public
- if we see a preimage onchain, it is public
- in lnsweep._maybe_reveal_preimage_for_htlc:
- partial mpp check is not relevant if preimage is already public
- let's just always do KeepWatchingTXO, for sanity/safety
Co-authored-by: ThomasV <thomasv@electrum.org>
When gossip is enabled we waste a lot of time trying to connect
to onion peers if we don't have a proxy enabled. We should just skip
them and try to connect to clearnet peers instead.
LNPeerManager.add_peer would only check if self.network.proxy is set,
which it is always as Network is initialized with self.proxy =
ProxySettings(). Instead it should check if proxy is set and enabled.
- if multiple LN-enabled wallets are open, need to know which peer is for which wallet
- note: LNGossip is a singleton
- if a wallet is named LNGossip, can't distinguish. I think that's ok.
compare log lines:
before:
```
84.82 | I | lnpeer.Peer.[LNWallet, 034cc6216f-f8dcaa6e] | Disconnecting: GracefulDisconnect('Failed to initialize: TimeoutError()')
17.97 | D | lnpeer.Peer.[LNGossip, 0259d4116d-1618547b] | Sending INIT
```
after:
```
5.80 | D | lnpeer.Peer.[test_segwit_2, 038863cf8a-fd53ef9c] | Sending CHANNEL_READY
5.92 | D | lnpeer.Peer.[LNGossip, 038863cf8a-6286ffd4] | Received INIT
```
- LNWallet no longer "is-an" LNWorker, instead LNWallet "has-an" LNWorker
- the motivation is to make the unit tests nicer, and allow writing unit tests for more things
- I hope this makes it possible to e.g. test lnsweep in the unit tests
- some stuff we would previously have to write a regtest for, maybe we can write a unit test for, now
- in unit tests, MockLNWallet now
- inherits LNWallet
- the Wallet is no longer being mocked
In some parts of the application 0 (sec) == no expiry, however we
use `LN_EXPIRY_NEVER` (100 years) instead of 0 for lightning invoices.
This replaces a 0 second expiry with `LN_EXPIRY_NEVER` in
`LNWallet.create_payment_info()` to prevent htlcs for no-expiry invoices
from getting failed incorrectly (which the assert prevented)
and fix the assertion error in #10350.
Fixes#10350.
# Conflicts:
# electrum/lnworker.py
- 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
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.
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.
Splits `LNWallet.dont_settle_htlcs` into `LNWallet.dont_settle_htlcs`
and `LNWallet.dont_expire_htlcs`.
Registering a payment hash in dont_settle_htlcs will prevent it from
getting fulfilled if we have the preimage stored. The preimage will not
be released before the the payment hash gets removed from
dont_settle_htlcs. Htlcs can still get expired as usual or failed if no
preimage is known.
This is only used by Just-in-time channel openings.
Registering a payment hash in dont_expire_htlcs allows to overwrite the
minimum final cltv delta value after which htlcs would usually get
expired. This allows to delay expiry of htlcs or, if the value in the
dont_settle_htlcs dict is None, completely prevent expiry and let the
htlc get expired onchain.
Splitting this up in two different dicts makes it more explicit and
easier to reason about what they are actually doing.
Please enter the commit message for your changes. Lines starting
refactor `htlc_switch` to new architecture to make it more robust
against partial settlement of htlc sets and increase maintainability.
Htlcs are now processed in two steps, first the htlcs are collected into
sets from the channels, and potentially failed on their own already.
Then a second loop iterates over the htlc sets and finalizes only on
whole sets.
# Conflicts:
# electrum/lnpeer.py
There is a race when initiating multiple lightning payments concurrently
(e.g. when doing a reverse swap with prepayment + swap payment).
suggest_splits might overallocate
split amounts for a channel as the splitting of both invoice amounts runs
concurrently and before acutal htlcs that reduce the channels balance
have been added to the channel yet. This results in a "not
enough balance" PaymentFailure once we try to send the htlcs and the
other payment attempt already reduced the available balance of the
channel.
This fix takes a lock from splitting the amount until the htlcs are
put on the channel, so suggest_splits always acts on the correct channel
balance.