1
0
Fork 0
mirror of https://github.com/ACINQ/eclair.git synced 2025-02-23 22:46:44 +01:00
Commit graph

1430 commits

Author SHA1 Message Date
Pierre-Marie Padiou
71968d0616
More robust channels timestamps (#2674)
Previous implementation had the advantage of being all in one place, but it left holes:
- `last_connected_timestamp` was only set after the first disconnection
- in some corner cases the `closed_timestamp` was never set (nothing at stake, funding tx timeout, post-restart)
2023-05-25 18:03:16 +02:00
Bastien Teinturier
84f1d03970
Fix splice reconnection while signing (#2673)
And add tests for splice disconnection/reconnection scenarios.
2023-05-25 17:51:10 +02:00
Bastien Teinturier
41b8d5cacd
Fix Autoprobe dummy invoice (#2661)
The autoprobe feature creates fake invoices to send payments to remote
nodes. These fake invoices must include a payment secret.

Fixes #2623
2023-05-25 15:43:56 +02:00
Bastien Teinturier
0fa44534d3
Ignore non-relayed incoming HTLCs when closing (#2672)
If we force-close with HTLCs that have just been signed by our peer but
for which we haven't received their revocation, we should ignore them.
We have not relayed those HTLCs so they can't be fulfilled. It is our
peer's responsibility to claim them on-chain (using their HTLC-timeout),
but if for some reason they don't claim it, we don't want the channel to
be stuck in the closing state.

Fixes #2669
2023-05-25 15:38:51 +02:00
Bastien Teinturier
835b33b2b8
Add upper bound on fees paid during force-close (#2668)
The on-chain feerate can be arbitrarily high, but it wouldn't make sense
to pay more fees than the amount we have at risk and need to claim
on-chain.

We compute an upper bound on the fees we'll pay and make sure we don't
exceed it, even when trying to RBF htlc transactions that get close to
their deadline.
2023-05-25 14:53:26 +02:00
Bastien Teinturier
aaad2e1d61
Accept closing fee above commit fee (#2662)
When performing a mutual close, we initially rejected fees that were
higher to the commit tx fees. This was removed from the specification
for anchor output channels, and doesn't make a lot of sense for standard
channels either: even at a higher fee, it makes sense to do a mutual
close to avoid waiting for relative delays on our outputs.

Fixes #2646
2023-05-25 13:13:12 +02:00
Bastien Teinturier
4713a541b6
Relax reserve requirements on HTLC receiver (#2666)
Bolt 2 requires the receiver of an HTLC to pay able to pay the commit tx
fee while maintaining its channel balance. This is an issue because it
can lead to a situation where the peer that has most of the channel's
funds is unable to send outgoing payments: the channel is stuck.

From the receiver's point of view, it's ok to dip into the channel reserve
as long as we're able to pay the commit tx fee, so we should accept those
HTLCs. Moreover, if those HTLCs are failed, we'll go back above our
channel reserve, and if those HTLCs are fulfilled, that will increase our
balance which guarantees we're above our channel reserve.
2023-05-25 13:12:42 +02:00
Bastien Teinturier
2c01915af0
Add message size metric (#2671)
This is interesting to perform traffic analysis on the messages we send
and receive, to inform research about traffic shaping.
2023-05-23 19:50:56 +02:00
Thomas HUET
adaad5eee6
Fix interpretation of option_onion_messages (#2670)
According to the spec, option_onion_messages signals that the node can forward onion messages which is different from being able to send or receive them (there is no feature bit for that).
We now allow nodes with this feature disabled to still receive messages and remove the NoRelay relay policy as it is redundant.
2023-05-23 19:17:39 +02:00
Bastien Teinturier
50178be6fa
Update to bitcoind 23.2 (#2664) 2023-05-22 10:04:43 +02:00
Bastien Teinturier
c73db8479c
Ignore lnd's internal errors (#2659)
It seems like lnd sends this error whenever something wrong happens on
their side, regardless of whether the channel actually needs to be closed.
We ignore it to avoid paying the cost of a channel force-close, it's up
to them to broadcast their commitment if they wish.

See https://github.com/lightningnetwork/lnd/issues/7657 for example.
2023-05-17 08:39:19 +02:00
Pierre-Marie Padiou
fa985da59f
Reject unreasonably low splice feerate (#2657)
We let the initiator pick the feerate, but it must at least meet some
sanity requirements.
2023-05-12 15:40:57 +02:00
Bastien Teinturier
55a985adc8
Fix channels DB migration (#2655)
We were missing a match on `channel_id`, which means we were rewriting
every row N times!
2023-05-11 14:42:55 +02:00
Bastien Teinturier
14cbed9b12
Fix JSON Postgres index on channel's remote_node_id (#2649)
We were creating an index on the `remote_node_id` based on the channel's
JSON serialization, which isn't very robust. The data model changes for
splicing have changed the JSON format and thus broken that index.

We now use and explicit DB column for `remote_node_id`.
2023-05-10 15:31:31 +02:00
Pierre-Marie Padiou
9beccce300
Define channelReserve() methods in ChannelParams (#2653)
So it can be called from `InteractiveTx` for new commitments.
2023-05-10 11:52:11 +02:00
Pierre-Marie Padiou
7bf2e8c67f
Remove restriction to regtest/testnet (#2652)
Now that the model is stable we can remove restrictions.
2023-05-10 10:34:25 +02:00
Bastien Teinturier
77b333731f
Use a tx_hash instead of txid in all lightning messages (#2648) 2023-05-05 18:22:36 +02:00
Bastien Teinturier
ee63c65a1c
Add cpfp-bump-fees API (#1783)
We add a `cpfpbumpfees` API that lets node operators bump the fees
of a package of unconfirmed transactions.

Node operators can for example ensure their funding txs confirm before
they hit the `2016` funding timeout. It's also very useful when you have
a long chain of unconfirmed funding transactions and/or mutual close
transactions and want to bump them all at once.

NB: the node operator needs to figure out which outpoints belong to him
(which should be fairly easy using existing APIs).
2023-05-04 18:20:27 +02:00
Pierre-Marie Padiou
15e4986f3f
Cleanup ChannelKeyManager (#2639)
There was a confusion between `fundingKeyPath` and `channelKeyPath`.

Also simplified the funding key derivation. It's not backward compatible but current version of the code doesn't run on mainnet so it's fine.

---------

Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
2023-05-04 11:37:58 +02:00
Pierre-Marie Padiou
a010750de8
Minor fixes for splices (#2647)
* do not check features at all for splices

It makes more sense than having to announce the feature to all peers.

* check actual min_conf value in swichToZeroConf

When we receive an early `channel_ready`, we may decide to not wait for
confirmations even if the channel isn't formally zero-conf. However, when
checking whether the channel is zero-conf, we currently only look at the
`ZeroConf` feature, which is incorrect in the general case.

This is normally invisible, because the race between:
- local `WatchFundingTxPublished` event from the watcher
- remote `ChannelReady`
is normally won by `WatchFundingTxPublished`. But in tests
`ChannelReady` usually wins.

It causes us to go through the `swichToZeroConf` path even if the
channel is already zero-conf, which then leads us to send a
`splice_locked` for the initial funding tx.

* check features before ignoring sig at reconnection

Legacy single-funding channels may have
`localFundingStatus=SingleFundedUnconfirmedFundingTx`, so we cannot
just rely on the absence of `signedTx`.

* fix post-migration startup of channels

Legacy single-funded channels will all be restored with a
`localFundingStatus=SingleFundedUnconfirmedFundingTx`, whatever the
actual status of the funding confirmation. The idea is that we
immediately put a `watchFundingConfirmed()` and set the correct state
shortly after the first startup.

However, we currently also send a `GetTxWithMeta`, which we should only
do for channels that are in state `WAIT_FOR_FUNDING_CONFIRMED`,
otherwise we will have loads of `unhandled event GetTxWithMetaResponse`.

* ignore watcher events in CLOSED

With splices, notifications from the watcher are tricky, there may be
races due to dealing with multiple funding txs. When we eventually go to
the `CLOSED` state, we should ignore those events, otherwise they may
wrongly cause us to go back to `CLOSING`.

* use correct expiry when accepting splice

The non-initiator must use the `locktime` provided in the `splice_init`
and not choose its own, otherwise transactions and signatures won't
match if we splice around the time a block has been found.
2023-05-04 10:08:09 +02:00
Bastien Teinturier
25f4cd2df4
Remove minDepth from InteractiveTxParams (#2635)
We can recompute `minDepth` based on our default config, the channel
capacity and our local features.

The only parameter that could change is our local features, which could
create issues if we enable/disable zero-conf in the middle of a funding
attempt: we may accept an RBF attempt for a transaction that we previously
treated as zero-conf, which will break the channel. But since activating
zero-conf means we have trust in our peer, and this is an unlikely
scenario, this is acceptable.

Co-authored-by: Pierre-Marie Padiou <pm47@users.noreply.github.com>
2023-05-03 16:22:04 +02:00
Bastien Teinturier
a58b7e8fa8
Use tlv type 0 for next_funding_txid (#2637)
This is the official tlv type used in the dual funding specification.
2023-05-03 16:09:15 +02:00
rorp
25b92da0b0
Pass remote address to InterceptOpenChannelPlugin (#2641)
This change allows plugins to make decisions based on
peers' IP addresses.
2023-05-03 09:36:29 +02:00
Richard Myers
0d3de8f377
Fix test to prevent error from timeout waiting for no messages (#2640)
A peer that receives Disconnect *may* also be sent the Init message. The Init message is ignored by the two disconnect tests so these tests should occur after all of the tests that do not result in a disconnect. Otherwise the extra Init triggers an error when we expect no additional messages to be sent to the peer.
2023-04-15 15:43:13 +02:00
Thomas HUET
36745a63bb
Better validation of onion message payloads (#2631)
We now reject onion message payloads that contain unexpected fields and classify final payloads as being either an invoice request, an invoice response, an error or an invalid payload.
Each of these cases are mutually exclusive, it is not allowed to send both an invoice request and an invoice at the same time for instance.
Invalid payloads are not dropped immediately so that if they are the response we were waiting for, we can stop waiting and return an error without retrying.
2023-04-14 11:15:38 +02:00
Thomas HUET
46149c7ed2
Add padding to blinded payment routes (#2638)
The lengths of the encrypted recipient data leak the base fees as they are encoded with a variable length, to compensate for that we always add padding.
2023-04-14 10:46:34 +02:00
Thomas HUET
3973ffaee1
Onion message test vector (#2628)
Use latest test vector from the spec for onion messages.
2023-04-14 09:38:26 +02:00
Pierre-Marie Padiou
71568cae58
Dynamic funding pubkeys (#2634)
Funding pubkeys are now dynamic and change for each splice.

Main changes:
- `remoteFundingPubkey` has been moved from `RemoteParams` to `Commitment`
- `localFundingPubkey` is computed by appending the `fundingTxIndex` to a new dedicated `fundingKeyPath`. As a nice side-effect, the resulting funding pubkey is constant across rbf attempts. Also, there is no change in the data model, since the base `fundingKeyPath` is constant and still belongs to `LocalParams`.

---------

Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
2023-04-13 21:16:58 +02:00
Bastien Teinturier
a8471df156
Update tx_signature witness codec (#2633)
We treat each witness as a blob of bytes encoded using bitcoin
serialization.
2023-04-13 19:26:45 +02:00
Pierre-Marie Padiou
de6d3c1709
Add support for splices (#2584)
Add support for both splice-in and splice-out in Eclair. Mixing concurrent local/remote splice-in/splice-out is wired, although not supported in the API.

The implementation differs from the current wip BOLT proposal on at least the following points:
- we use a poor man's _quiescence_ protocol which just rejects the splice if the channel is not idle
- splice txs always _spend_ the previous funding/splice tx, even if it isn't confirmed yet and could theoretically be RBFed. This is done to be compatible with zero-conf splices
- the persistence/reconnection follows the logic described in https://gist.github.com/t-bast/1ac31f4e27734a10c5b9847d06db8d86.

We add a new `fundingTxIndex` to `Commitment`, which has two nice advantages:
- making debug much easier compared to dealing with txid:
  `splice=1 is now active, removed=0 remaining=2,1`
- allowing to discriminate between initial funding, splices, rbf, and
  combinations thereof.

We closely mimick RBFing the initial funding tx (e.g. `RbfStatus` vs `SpliceStatus`).

---------

Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
2023-04-13 19:14:02 +02:00
Bastien Teinturier
daf947fb60
Allow negative contributions in InteractiveTxBuilder (#2619)
* Allow negative contributions in InteractiveTxBuilder

When splicing over an existing channel, it is simpler to specify the amount
we will add or remove from the channel, rather than the resulting amount
that takes the previous balance into account. It removes the need for
truncating msat balances and trivially carries over those balances to
the new commitment.

* Update RBF contributions to allow negative amounts

When RBF-ing a splice, we will need to be consistent with the
`splice_init` and `splice_ack` messages and specify the funds we're
adding or removing from the channel instead of the absolute value.

We thus change the `tx_init_rbf` and `tx_ack_rbf` messages to use signed
amounts.
2023-04-05 15:22:15 +02:00
Bastien Teinturier
6d7b0fae57
Remove max-funding-satoshis config (#2624)
* Remove `max-funding-satoshis` config

This configuration parameter doesn't provide any meaningful guarantees
since there are no limits on the number of channels remote peers can open
to us. It's better to remove this check from eclair and let plugins decide
whether to accept channels or not, based on whatever metric makes sense
for their usecase.

* Remove wumbo from permanent channel features

We've never been really convinced that this feature made sense to keep in
the channel features. It becomes especially weird with splicing, since a
channel may initially be larger than the wumbo size, but could then shrink
and become smaller than that threshold. Similarly, a channel that is
initially below the wumbo size may exceed the wumbo size after a splice-in.
2023-04-05 14:52:39 +02:00
Bastien Teinturier
3a95a7deb5
Store channel state after sending commit_sig (#2614)
We must store the channel state after sending our `tx_signatures`,
because our peer may broadcast the transaction at that point.
But it's useful to store it earlier than that, to allow resuming the
signatures exchange if we get disconnected, otherwise we could
end up in a state where one peer has forgotten the channel while
the other has sent `tx_signatures` and must thus wait for the
channel to be spent or double-spent.

With that change, we can cleanly handle any disconnection:

- if we get disconnected before any peer sent `commitment_signed`,
  the channel is forgotten by both peers
- if we get disconnected after one peer send `commitment_signed`
  but the other peer didn't, the channel will be forgotten when
  reconnecting (this is safe because the peer that sent
  `commitment_signed` did *not* send `tx_signatures` since the
  other peer didn't send `commitment_signed`)
- if we get disconnected after both peers sent `commitment_signed`,
  we simply resume the signatures exchange on reconnection

We introduce a new TLV field to `channel_reestablish` that contains
the `txid` of the funding transaction that is partially signed: this lets
peers figure out which messages to send back on reconnection.
2023-04-05 14:52:16 +02:00
rorp
e383d81de8
Add listreceivedpayments RPC call (#2607)
Add a new RPC to list payments received by the node.
2023-04-04 19:44:45 +02:00
Pierre-Marie Padiou
dcedeccb05
Rework responses to channel open and rbf (#2608)
Main behavior changes (see commit messages for details):
- channel opening errors are returned with a 200/OK status from the api
- we return a success in the case of dual-funding or rbf, if the interactive tx has completed, even if the publish fails
- for rbf, we send the success response later in the flow: only when the rbf flow is successful, as opposed to when we initiate it

This is a prerequisite to splices, but also a first step towards reworking the channel request/response mechanism.

Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
2023-03-31 14:44:29 +02:00
Thomas HUET
df0e7121ef
Add offer manager (#2566)
Because offers are a very generic mechanism, handling them can require interacting with an inventory system (do we actually have the quantity that the payer is requesting) or other such systems which do not have their place inside eclair. For this reason offer handlers must be implemented as plugins that communicate with the offer manager.
On startup, the offer handlers must register their offers with the offer manager, the offer manager will then forward the invoice requests and blinded payments to the relevant offer handler for approval.
2023-03-27 18:37:14 +02:00
Richard Myers
732eb31681
Add limit for incoming connections from peers without channels (#2601) 2023-03-24 14:05:10 +01:00
Bastien Teinturier
e1cee96c12
Fix opportunistic zero-conf (#2616)
If we didn't plan on using zero-conf, but our peer sends us an early
channel_ready, we can opportunistically switch to zero-conf.

But we can only do that if we're sure that our peer cannot double-spend
the funding transaction. We previously checked their contribution to the
funding output, but that's not enough: they may add inputs to the funding
transaction even if they don't contribute to the funding output.

We were also setting duplicate `WatchPublished` in case we were already
using zero-conf, which is now fixed.

When our peer sends us channel_ready while we're still waiting for
confirmations, we may opportunistically switch to zero-conf, in which
case we have both a WatchPublished and a WatchConfirmed pending.
But it may not actually be a real switch to zero-conf: maybe the
transaction is confirmed, and they simply received the block slightly
before us. In that case, the WatchConfirmed may trigger first, and it
would be inefficient to let the WatchPublished override our funding
status: it will make us set a new WatchConfirmed that will instantly
trigger and rewrite the funding status again.
2023-03-23 18:50:35 +01:00
Fabrice Drouin
f4326f4b26
Use bitcoin-lib 0.27 (#2612) 2023-03-16 15:05:58 +01:00
Bastien Teinturier
a52a10a040
Update Bolt 3 tests (#2605)
Add latest changes from https://github.com/lightning/bolts/pull/1018
Add latest fixes from https://github.com/lightning/bolts/pull/1056
2023-02-28 15:17:43 +01:00
Richard Myers
1c9c694fb5
Add new command to fix flaky tests in PendingChannelsRateLimiterSpec (#2606) 2023-02-28 15:17:19 +01:00
Pierre-Marie Padiou
df590d8d30
Make updateLocalFundingStatus method return Either (#2602)
After calling this method, we perform actions at several places that
only make sense if the correct behavior happened. Instead of assuming
things went ok, we use proper typing and make the result explicit.
2023-02-20 17:32:08 +01:00
Bastien Teinturier
a3c6029e1d
Limit number of RBF attempts during dual funding (#2596)
Each RBF attempt adds more data that we need to store and process,
so we want to limit our peers to a reasonable use of RBF.

We send a warning to let them know that they are close to reaching the
limits.
2023-02-17 17:36:06 +01:00
Bastien Teinturier
1a79e75a63
Replace Commitments with MetaCommitments (#2599)
There are two possible strategies for MetaCommitments:

1. Move the duplication between every Commitment in a shared field
2. Access duplicated fields through the first Commitment

I initially wanted to go with solution 1., but it makes commitments really
hard to work with. The main reason is that the `CommitmentSpec` abstraction
is a very good abstraction to work with when updating commitments,
and it requires keeping the htlcs inside every commitment.

As long as we update commitments in a loop, there is no risk of common
values being desynchronized. Since they contain mostly pointers to shared
data, the memory overhead is negligible, as long as we make sure we don't
duplicate the data when serializing to disk. We're thus choosing solution 2.

We serialize htlcs separately and rebuild `CommitmentSpec` objects when
deserializing. We also only keep the main htlc fields during json serialization
to avoid performance issues when writing json fields to the DB. There was
no good reason to serialize everything as we previously did.
2023-02-17 16:57:53 +01:00
Bastien Teinturier
e3bba3d022
Remove reserve requirement on first commitment (#2597)
This requirement was always met for single-funded channels, but for dual
funded it may not be met if the non-initiator contributes a very large
amount (more than 100x what the initiator contributes). That scenario
could happen, and the funding attempt shouldn't fail as long as the
initiator's balance contains enough funds to pay the commit tx fees.
2023-02-17 13:37:27 +01:00
Bastien Teinturier
fcc52a84ca
Prepare InteractiveTxBuilder to support splicing (#2595)
Adding splicing to the InteractiveTxBuilder requires:

- adding a shared input (the current funding output)
- adding outputs (when splicing out)

The `localAmount` and `remoteAmount` provided are the amounts each peer
contributes to the new funding output. Those amounts should be computed
by the caller depending on what they intend to do (splice funds in/out).
This model allows batching operations: if the caller wants to do several
splices in and several splices out, this is easy to do by iterating over
these operations and updating the targeted `localAmount` accordingly,
the InteractiveTxFunder will take care of the rest.

Note that when splicing, we currently truncate previous balances to sats.
This results in 1 sat being given away to miners as fees, and a passive
participant losing up to 999 msat of their balance. This can be changed
in the future depending on the final spec choice, and shouldn't need a
codec update since the previous balances come from the commitment field
provided in the purpose.

When splicing, the tx_add_input message we send for the shared input
doesn't contain the previous transaction. There are two reasons for
that:

- it potentially doesn't fit into a lightning message (if > 65kB)
- we don't need it, we know it correctly uses segwit
2023-02-17 12:53:21 +01:00
Richard Myers
ddcb978ead
Add support for plugins that intercept open channel messages (#2552) 2023-02-17 08:56:51 +01:00
Thomas HUET
d4c32f99dd
Add support for paying offers (#2479)
Add a new actor paying an offer: sends an invoice request, wait for the invoice, retries if needed, pay the invoice
2023-02-16 18:57:43 +01:00
Bastien Teinturier
69042835a2
Handle next remote commit in ReplaceableTxPublisher (#2600)
The ReplaceableTxPublisher only looked at the remote commit and ignored
the case where our peer publishes their next commit. This created two
issues:

- eclair would keep trying to publish htlc transactions that had no chance
  of confirming, which is a waste of resources
- eclair would fail to RBF claim-htlc transactions: this had no impact today
  because we currently target the next 2 blocks so RBF isn't necessary,
  but it will become useful if we allow setting a more economical block
  target in the future
2023-02-16 17:37:41 +01:00
Pierre-Marie Padiou
202598d14e
Introduce a specific funding status for zeroconf (#2598)
We used to consider zero-conf funding txs as _confirmed_ as soon as they were _published_, but it was hacky. Before splices, it prevented RBF-ing zero-conf txs, which in theory make sense (we start using the channel without confirmations, but may still want to bump the fees later). After splices, it would prevent using a channel while a splice tx is pending confirmation (even if the channel isn't zero-conf).

What we are really doing is separating the state of the channel, from the state of the blockchain. As a consequence the management of the funding tx is more independent from the channel FSM, which is why we end up with catch-all handlers for `WatchPublishedTriggered`/`WatchFundingConfirmedTriggered`.

As a side effect, we also simplify how we put watchers: instead of putting them back at every connection, we do this once and for all (either when creating the channel, or at restart).

---------

Co-authored-by: t-bast <bastuc@hotmail.fr>
2023-02-16 11:23:32 +01:00