* Add a finalScriptPubKey field to DATA_CLOSING (no functional changes)
* Add an explicit finalScriptPubKey parameter to helper methods (no functional changes)
* Rename LocalParams field defaultFinalScriptPubKey to upfrontShutdownScript_opt
`localParams.upfrontShutdownScript_opt` is now optional, and a new field has been added to DATA_CLOSING: finalScriptPubKey, which is the actual pubkey script onchain funds are sent to.
When reading DATA_CLOSING data serialized with older codecs, we rely on the fact that `localParams.upfrontShutdownScript_opt` was always present and was actually used as the final onchain
destination: it is safe to use `localParams.upfrontShutdownScript_opt.get` to populate DATA_CLOSING's finalScriptPubKey field.
* Update closing address when possible
When a channel gets closed, and when possible, we send all onchain funds to a recent onchain address and not
to an address that was generated when the channel was created.
This is possible for new channels in all cases except when mutual-closing a channel that sets `upfront-shutdown-script`.
Existing channels, which will keep sending onchain funds to addresses generated when they were created. Migration for existing channels will be handled in another PR.
Co-authored-by: Pierre-Marie Padiou <pm47@users.noreply.github.com>
Move all the logic that was previously inside `Commitments` to `MetaCommitments`.
The code changes are quite minimal, with a few subtleties: we need to update the
local/remote commit indices separately of the commitments themselves, because
they're not in the same data structure (yet).
Some of these changes show where the current model doesn't work well:
- `remotePerCommitmentPoint` is duplicated across all remote commits:
it's not obvious, but it has to be the same value
- htlcs should be shared between commitments
- the coupling between `remoteNextCommitInfo` and `nextRemoteCommit_opt`
is really weird to work with (especially in `receiveRevocation`): this can be fixed
by slightly re-working the model
The data model will be updated in future commits to fix these issues.
We introduce a `Purpose` trait, which indicates what the operation is about. Currently there are two possibilities:
- `FundingTx`
- `FundingTxRbf`
This allows for some nice factoring, but more importantly it will be complemented by a third possibility for splices.
Note that this change preserves the original separation between two main concerns:
- creating the funding tx (in `InteractiveTxParams`)
- creating the commitment (in `InteractiveTxBuilder`).
Fixes#2478.
I tried to keep the changes minimal, but had to move the _read_ from `Setup` to `Setup.bootstrap`, otherwise we would have kept a reference of the initial channels list forever.
Checking the db now happens a bit further in the startup procedure, but it is still blocking, and before the actors are initiated.
Apparently lnd rejects keysend payments that contain a payment secret,
instead of simply ignoring that field.
The blip doesn't mention this requirement:
https://github.com/lightning/blips/blob/master/blip-0003.md
But we don't have a strong reason to send it either, so let's remove that.
* Update `require_confirmed_inputs` tlv
It has been assigned tlv type 2 in the specification.
* Add second per-commitment point to dual funding
We can send the second per-commitment point right at the beginning of the
channel opening flow, to avoid the awkwardness of having to store an
invalid value in `remoteNextCommitInfo` until we receive `channel_ready`.
* Echo incoming tx_abort
When we receive tx_abort, we echo it back to let our peer know we've seen
their tx_abort and have reset our internal state accordingly.
Spec commit:
07cc0edc79
This is a collection of independent changes in preparation for splices. We group them inside a single PR so we don't have to support multiple intermediate codecs versions:
- store the full funding tx inside `Commitments`
- store the local/remote status for the funding tx inside `Commitments`
- define a `MetaCommitments`, which is a list of `Commitments`
- split `Commitments` between `Params`/`Common`/`Commitment`.
⚠️ This PR includes a new db codec version, and restricts Eclair to `regtest` in order to be able to squash further codec changes before the next release, without having to support intermediate versions.
Co-authored-by: t-bast <bastuc@hotmail.fr>
The postman now has a higher level API to send messages: the user provides the content and the paths to use and the postman takes care of building the message packet and sending it to the next node.
Apparently lnd and cln don't send a payment secret when using keysend,
even when we advertize the feature as mandatory. This is ok though, we
don't actually need a payment secret to protect keysend payments as long
as the sender doesn't use MPP (which is their responsibility, not ours).
Since our codebase requires payment secrets to index payments, we simply
use the preimage as secret when receiving keysend payments.
* Add ChannelOpened event
Emit an event when a channel is opened and ready to process payments.
This event is distinct from the `ChannelCreated` event which is sent
earlier, once we think a funding transaction has been successfully created
(but cannot guarantee when we're not the initiator).
* Add event to websocket
This is a breaking change, but it should be ok since the previous event
wasn't reliable: it was emitted at a time where we couldn't guarantee
that the channel would really confirm.
In preparation for splices, we make `makeFirstCommitTxs` more generic:
- expose the `commitmentIndex`, which was hardcoded to `0`
- take the funding/push amounts arithmetic out
We rename the existing method to `makeCommitTxsWithoutHtlcs` and define a new `makeFirstCommitTxs` with the exact same signature as before, making the change transparent from the outside.
Since we only sign one-input txs, the input index was hardcoded to `0`,
but with splices we will spend previous funding txs, which may have a
change. The change is trivial since we do have all the info to figure
out the output index.
When our peer doesn't contribute to an interactive-tx session, we don't
need to wait for their `tx_signatures`: they will be empty anyway, so we
can create them locally and publish the transaction immediately.
We must *always* lock inputs selected for funding, otherwise locking
wouldn't work at all, as the following scenario highlights:
- we fund a transaction for which we don't lock utxos
- we fund another unrelated transaction for which we lock utxos
- the second transaction ends up using the same utxos as the first one
- but the first transaction confirms, invalidating the second one
This would break the assumptions of the second transaction: its inputs
are locked, so it doesn't expect to potentially be double-spent.
It's particularly dangerous if the node supports zero-conf, as this could
happen to a zero-conf transaction and completely break the channel.
* homogenize WatchFundingConfirmedTriggered handlers
The handling is mostly the same in connected/disconnected states. This
does some refactoring to make them as similar as possible.
NB: we don't make a difference between previous/latest commitment being
confirmed.
* properly factor the pruning of commitments
This is a first glimpse of what will happen when we prune commitments
that have been overriden by a splice.
* prevent duplicate logs when funding tx confirms
At restart, we always put a `WatchFundingConfirmed` on all funding txs,
because this is how we detect force close in state disconnected (we only
put a `WatchSpent` on the funding tx output _after_ we detect that the
funding tx itself is confirmed).
With current code, this would result in a log indicating that the
funding tx has been confirmed at restart, for each channel in
`WAIT_FOR_DUAL_FUNDING_CONFIRMED` state. It can be quite spammy.
Instead, we now only log two cases:
- when we are disconnected, and there were alternative funding txs that
we discard;
- when we are connected (this can only happen once because we will
then transition to the next state).
* factor code for accepting the funding tx
There are 4 code paths:
- single/dual funding
- zero/non-zero conf
Besides the factorization, note that in the dual funding + non-zero conf case, we reverse the calling order between `pruneCommitments` and `acceptDualFundingTx`. This prepares a future change where we store the funding tx inside `Commitments`: it makes more sense then to first update the status of the funding tx in the corresponding commitment, and then prune the remaining commitments.
When using zero-conf, we wait for the transaction to be published before
using a channel. This guarantees that the bitcoind wallet has successfully
recorded the transaction and won't double-spend it.
Otherwise if the transaction fails to publish and the utxos are unlocked,
or if bitcoind is restarted, we may accidentally double-spend it which
would break the channel and be very painful to recover.
Factor and group all `WatchFundingSpentTriggered` handlers in `whenUnhandled`
Special cases (`NEGOTIATING`, `WAIT_FOR_FUTURE_`) are kept outside for readability.
We remove utxos locks that were previously set, otherwise we may have
utxos that stay locked indefinitely. This may happen if we started funding
a channel and restarted before completing the funding flow: the channel
will be safely forgotten but the corresponding utxos stay locked.
The only drawback that this may have is if we have funded and signed a
funding transaction but didn't publish it and we accidentally double-spend
it after a restart. This shouldn't be an issue because:
- locks are automatically removed when the transaction is published anyway
- funding transactions are republished at startup if they aren't in the
blockchain or in the mempool
- funding transactions detect when they are double-spent and abort
the channel creation
- the only case where double-spending a funding transaction causes a loss
of funds is when we accept a 0-conf channel and our peer double-spends it,
but we should never accept 0-conf channels from peers we don't trust
We provide three strategies when locked utxos are detected: stop eclair,
unlock the utxos automatically, or ignore them.
* Set htlc-max-in-flight to 100% by default: it makes it easier to reason
about liquidity in tests, and can be overridden for tests that need a
different value
* Wait for Carol to receive Bob's scid-alias, otherwise blinded routes
will fail to relay
This is just refactoring, there is no feature change. The goal is to later be able to add an upper layer that manages several commitments and acts as a "meta commitments".
This actor spawns only a single `PeerReadyNotifier` actor for each peer that is watched to prevent multiple actors from redundantly polling for when the same peer reconnects.
This actor can be extended to watch for onion messages from async payment receivers, instead of only watching for local peer re-connections.
- link to plugins repository
- remove android mention for eclair
- update other implementations (renamed)
- update docker CI action versions
- missing eclair-cli APIs in help
Reduce the amount of logs generated by default by moving logs that are
redundant or only used for targeted debugging to `debug` level or removing
them entirely.
I focused on logs that generate some volume and that I never personnally
use for day-to-day log browsing, but let me know if some of these logs
are important for you and it would be annoying to have to turn on `debug`
level for their respective component.
We use router data to resolve both private and public channels, even
when scid-alias is used.
When a channel cannot be found, we simply skip it since adding it to the
ignore list wouldn't have any impact.
Fixes#2346 and #2426
We add an actor that waits for a given peer to be connected and ready to
process payments. This is useful in the context of async payments for
the receiver's LSP.
When sending an outgoing multi-part payment, we forward the preimage back
to the sender as soon as we receive the first `update_fulfill_htlc`.
This is particularly useful when relaying trampoline payments, to be able
to propagate the fulfill upstream as early as possible.
However this meant that callers of the HTTP API would receive this
preimage event instead of the final payment result, which was quite bad.
We now disable this first event when used with the `--blocking` argument,
which ensures that the API always returns the payment result.
Fixes#2389
* removed unused code
* remove WaitingForRevocation.reSignAsap
It was hacky and completely un-needed, we just need to check pending changes when we receive a revocation. Probably was a left over for when we batch-signed.
The codec change is more tricky than it may look:
- we keep writing 8 bits in order not to have to introduce a new version
- older codecs use 1 or 8 bits depending on version
* Make totalAmount required in blinded final payloads
And update the reference test vector for blinded payments.
* Handle failures inside blinded routes
When a failure occurs inside a blinded route, we must avoid leaking any
information to upstream nodes.
We do that by returning `update_fail_malformed_htlc` with the
`invalid_onion_blinding` code whenever we are inside the blinded route,
and `update_fail_htlc` with the `invalid_onion_blinding` code when we are
the introduction node (and we add a delay).
When we are using only dummy hops or not using any blinded hop, we can
return normal errors.
We also fix an issue we had with `update_fail_malformed_htlc`: when we
received that kind of error from the downstream node, we also returned
an `update_fail_malformed_htlc` error upstream, whereas the specification
says we must convert it to an `update_fail_htlc`.
We also add many e2e tests for blinded payments.
* Remove hard-coded minimum witness weight
The spec provided a value of 107WU for the minimum witness weight, but it
is incorrect: p2tr inputs have a smaller witness than that, and segwit
allows arbitrarily low witnesses.
We remove that hard-code value altogether and consider unsigned
transactions, as we simply cannot do better.
* Allow non segwit outputs
While we restrict inputs to be segwit-only, we can allow any type of
outputs in a dual-funded transaction.
Since blinded routes have to be used from start to end and are somewhat
similar to Bolt 11 routing hints, we model them as an abstract single hop
during path-finding. This makes it trivial to reuse existing algorithms
without any modifications.
We then add support for paying blinded routes. We introduce a new type
of recipient for those payments, that uses blinded hops and creates
onion payloads accordingly. There is a subtlety in the case where we're
the introduction of the blinded route: when that happens we need to
decrypt the first payload to figure out where to send the payment.
When we receive a failure from a blinded route, we simply ignore it in
retries: we don't know what caused the issue so we assume it's permanent,
which makes sense in most cases since we cannot change the relaying
parameters (fees and expiry delta are chosen by the recipient).
* mempooltxmonitor: no need to unsubscribe from event stream
Adapters are child actors that will die along with their parents, and
the eventstream watches all subscribers for termination:
a8ee6fa42b/akka-actor/src/main/scala/akka/event/EventStream.scala (L50).
* mempooltxmonitor: send block count to actor
This solves a race condition with event stream subscription.
* Fix failing NormalStateSpec test
The `recv CurrentBlockCount (fulfilled signed htlc ignored by upstream peer)`
test was sometimes failing because of an event stream concurrency
issue on busy/slow machines:
- the previous test emits a `LocalChannelDown` event
- the next test starts before this event was emitted and registers to the
event stream
- then it receives the previous `LocalChannelDown` event before the
`LocalChannelUpdate`s we expect
* Improve MinimalNodeFixture watcher autopilot
We create an alternative ZmqWatcher that waits for the channel funder
to publish funding transactions before triggering watches.
* Fix ZeroConfAliasIntegrationSpec
A test was added to verify that when building a route to self, we use the
correct scid-alias when available (remote alias instead of local).
This test sometimes failed because Carol hadn't received Alice's channel
update and couldn't build the Alice->Bob hop. The only thing that we meant
to test was the Bob->Carol hop, so we can simplify that and remove the
flakiness,
* Fix MempoolTxMonitorSpec
We use context.pipeToSelf when publishing the transaction, which creates
a race condition between the time when the tx is added to the mempool and
the time where we're ready to process `WrappedCurrentBlockHeight`.
If `WrappedCurrentBlockHeight` arrives before `PublishOk`, the test will
fail waiting for `TxInMempool`.
* Fix TxTimeLocksMonitorSpec
The usual race condition for registering to the event stream applies,
so we directly send the `WrappedCurrentBlockHeight` event.
* Fix ZmqWatcherSpec
Some tests are randomly failing because watches can be triggered several
times and new blocks from previous tests may trigger events in subsequent
tests. We fish for the specific messages we're interested in and ignore
others.
We were previously directly creating onion payloads inside the various
payment state machines and manipulating tlv fields. This was a layering
violation that was somewhat ok because in most cases we only needed to
create the onion payload for the recipient at the beginning of the payment
flow and didn't need to modify it, except for a small change in the MPP
case.
This forced us to handle trampoline onions directly in the payment
initiator and will not work for blinded payments, where we can only build
the onion payload for the recipient after we've chosen the routes and how
to split the amount.
We clean this up by introducing payment recipients that abstract away the
creation of onion payloads. This makes it much easier to integrate blinded
payments. It also allows us to clean up the way we do trampoline payments
and potentially support splitting across multiple trampoline routes (not
included in this PR as this change isn't immediately needed).
It also lets us simplify the MultiPartPaymentLifecycle FSM, by moving the
logic of computing how much remains to be sent and what fee can be used
to the route calculation component.
When wallet transactions are evicted from the mempool (because their fee
is too low), we have a strong dependency on bitcoind's behavior: it must
not double-spend the inputs of the evicted transaction, otherwise it
could break 0-conf channels.
We verify that behavior in a unit test where we set the mempool to
5MB (the minimum authorized mempool size) and simulate this eviction
scenario.
* Improve htlc_maximum_msat in channel updates
We previously set the `htlc_maximum_msat` inside `channel_update` to the
channel's capacity, but that didn't make any sense: we will reject htlcs
that are above the local or remote `max_htlc_value_in_flight_msat`.
We now set this value to match the lowest `max_htlc_value_in_flight_msat`
of the channel, and properly type our local value to be a millisatoshi
amount instead of a more generic UInt64.
* Set max-htlc-in-flight based on channel capacity
We introduce a new parameter to set `max-htlc-value-in-flight` based on
the channel capacity, when it provides a lower value than the existing
`max-htlc-value-in-flight-msat` static value.
* Allow disabling max-htlc-value-in-flight-msat
When opening a channel to a mobile wallet user, we may want to set our
`max-htlc-value-in-flight-msat` to something greater than the funding
amount to allow the wallet user to empty their channels using a single
HTLC per channel.
We weren't correctly closing SQL statements when comparing DBs and
migrating them. All the DB handlers for normal operation (read/write
channels, payments, etc) are already correctly closed after execution.
Fixes#2425
We used to store UNIX timestamps in the waitingSince field before moving
to block count. In order to ensure backward compatibility, we converted
from timestamps to blockheight based on the value.
This code has shipped more than a year ago, so we can safely remove that
compatibility code since it only applies during the channel open or close
period, which cannot last long anyway.
Fixes#2125