Our mechanism to detect double-spending wasn't correctly taking into
account unconfirmed inputs. This was only used in single-funder scenarios
so it could only be an issue in rare edge cases, where it would not lead
to any loss of funds as we keep commit tx data in our DB even for closed
channels.
There was a race condition when testing fee-bumping: we could emit the new
block event before the underlying actor registered to this event type.
This is fixed by emitting the `TransactionPublished` event after registering
to the new block events, and waiting for that in tests before publishing a
new block event.
We have two sources for channel routing parameters:
- channel updates
- routing hints in invoices
Instead of generating fake `channel_update`s from routing hints, we
define a `ChannelRelayParams` that can be built from announcements
or routing hints.
This is cleaner but also is a first step to decorrelate the identifier
of a channel in our graph, from whatever identifies the source.
While zlib provides good compression results for gossip, it's a dependency
that had a few important CVEs in the past. Some implementations are
reluctant to import it, so we decided to remove it from the specification
in https://github.com/lightning/bolts/pull/981
We stop compressing with zlib and only send uncompressed results, while
still supporting receiving compressed data. We will remove support for
decompression once our monitoring indicates that we stopped receiving
compressed data.
We also reduce the maximum allowed chunk size.
The previous calculation was wrong and could lead to messages bigger than 65kB.
Dijkstra's algorithm assumes that each edge has a fixed weight that does not depend on the rest of the path. In our case this assumption is broken when computing a cost for failed payments as it depends on all the edges of the path. We fix this by adding the possibility to use log probabilities which can be added per edge and offer a good approximation as long as the probabilities stay close to 1.
Edges still don't have a perfectly fixed weight because the fee of an edge depends on the fees of the previous edges, however since fees are typically low, it shouldn't matter in practice.
It was creating a race condition in the test
`MultiPartHandlerSpec`.`PaymentHandler should reject incoming
multi-part payment with an invalid expiry` due the 0-expiry
invoice being immediately purged.
In path-finding, we give a better score to channels with higher capacity because they have a higher change to have enough balance to relay the payment. But for local channels we know the balance so we can be sure that the payment can be relayed.
Add dual funding feature bit, but keep it disabled for now.
Add dual funding protocol messages and codecs.
We don't actually handle these messages yet.
When we receive them, they will simply be ignored and log a warning.
* Add a "stop" API method
This API call was added for certain uses cases where killing the process was impractical but internally it just calls `sys.exit()`.
Eclair is designed to shutdown cleanly when its process is killed and this is still the recommended way of stopping it.
When Phoenix was based on a branch of eclair, we needed a workaround for
invoice backwards-compatibility. Now that Phoenix uses lightning-kmp
instead of eclair, we can remove that work-around.
* Check that channel seed has not been modified
On startup, we check that for each of our channels the public key derived from the channel seed matches the key that was
used when the channel was funded.
* Rename DBCompatChecker to DBChecker and move channel seed check there
* Rename HasCommitments
* Introduce a TransientChannelData trait, which lets us have complete pattern
matching on channel data
* Remove channel data from the ChannelErrorOccured event
* A few fixes in Channel.scala
* Refactor channel transition handlers
The `option_scid_alias` feature (https://github.com/lightning/bolts/pull/910)
is going to clash with the feature bit we use for trampoline payments.
Fortunately we've never advertized it, so we can simply update it to a much
higher value for now (until the final version of trampoline is specified).
We use a version of bitcoin-lib that uses bitcon-kmp under the hood.
Its API is the same as before, but its package is now fr.acinq.bitcoin.scalacompat
The `channelbalances` API call retrieves information about the balances of all local channels, not just those with usable outgoing balances that are enabled for sending.
This change also adds the `isEnabled` attribute to the json results for both the new `channelbalances` and old `usablebalances` API calls.
Refactor the channel state machine into several separate traits.
This lets us split its logic into multiple files while keeping a single actor.
It also lets us isolate some parts of the state machines as if they were
small state machines: we apply this to the channel opening flow which
will let us add a new flow for dual funding.
This can also be applied to the closing mechanism in the future.
When using multipart payments, the path-finding request sent to the router does not match the actual payment, it is only a request to route a fraction of the amount but the fee budget is still the one for the full payment. As a consequence the router will return routes that will not satisfy the fee budget.
The fee budget is checked one last time before relaying the payment but ignoring the fee of the first channel (which should not be ignored for trampoline relays). I fix this last check.
* use `NodeAddress` everywhere instead of `InetAddress`
This makes us control more strictly when and where name resolution happens, which is important in a security-hardened setup. The `InetAddress` jdk class indeed does a lot of things behind the scenes, but now we restrict it to tcp-related classes like `Client` and `Server`.
Also, in _cluster mode_ all outgoing connections (including tor) are now made on the front.
* upgrade guava and rewrite nodeuri tests
There is no reason to use the version of guava targetting android anymore. Also `HostAndPort` was in beta in our current lib version.
We now use guava's `InetAddresses.toUriString()` to format host string, instead of manually adding brackets.
Reworked `NodeURI` tests:
- less repetition with one single test and multiple `testCases`
- focus on non-reg (no need to verify what we know we don't support)
We've seen a few reports of local channels sometimes being ignored during
path-finding (e.g. #2176).
When that happens, it's currently hard to know whether the channel is in
the graph or not: knowing that would let us know if there is a bug in the
graph management code or the path-finding algorithm itself.
Eclair fails at startup when eclair.bitcoind.wallet is mis-configured or not loaded by bitcoind. We now show different error messages for specific failure situations and report the current wallet configuration and loaded wallets where appropriate.
This is a classic race condition that can appear when we register to
events in tests. We need to make sure that the subscription is taken
into account before moving forward.
Instead of defining a separate type `FeatureScope` with its own
hierarchy, that was then mixed in `Feature` using the cake pattern, we
go with a simpler type hierarchy for `Feature`.
This significantly simplifies type declarations (no more `Feature with
FeatureScope`) especially in the tests.
Add the ability to set different min-funding limits for private and public channels.
Replace min-funding-satoshis config parameter with min-public-funding-satoshis and min-private-funding-satoshis.
Show a deprecation message if min-funding-satoshis is defined.
Prevent relayed payments from failing due to an insufficient fee rate caused by a delay in gossip propagation with the new fee rate. Payments that satisfy the base and proportional relay fee rates from either the current or previous local channel update will not be failed during the `relay.fees.enforcement-delay` period (default 10 minutes) after the latest local fee update.
The previous fee update is only stored in memory, so after restarting the node all fee updates will be enforced immediately. To enforce a fee update with out a delay you can also issue the same update twice so that the previous and current fee rates are the same.
When we know for sure that an incoming htlc will never be fulfilled, we can safely ignore it. We used to only handle htlc fulfillment. Fixes#2168.
Note that when we receive a preimage for a htlc during a local/remote force close, we need to only update the htlcs and keep the rest of `LocalCommitPublished` untouched. In particular, we don't regenerate the claim-main tx (which can cause issues if fees change), and leave the `irrevocablySpent` untouched.
Also renamed and reorganized a few helper methods.
An invoice that doesn't explicitly set min_final_cltv_expiry has an default min_final_cltv_expiry of 18.
This default allows invoices to be slightly shorter but does not mean that the min_final_cltv_expiry can be unknown and needs to be provided from somewhere else.
Because of the virtual cost per hop, a path with several "good" channels may be considered better than using a direct channel.
We remove the virtual cost for the first hop of the path to ensure that a direct channel is always selected when available.
Building an inconsistent intermediate `RemoteCommitPublished` object was error-prone and defeats the purpose of strong typing.
We also handle the `paysDirectlyToWallet` case directly in the method, which enables a nice factorization and better contains this now deprecated feature.
When Eclair first starts, search for all unpaid expired incoming payments and purge them from the payments database. These payments take up space in the database but will no longer be paid and so should be removed to improve performance and reduce the size of the database.
Purges will be triggered every 24 hours by default but can be disabled or configured with a different interval.
The invoice purger only looks back 15 days for expired invoices when triggered after the initial scan to reduce its impact on database performance.
Co-authored-by: Thomas HUET <81159533+thomash-acinq@users.noreply.github.com>
Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
When starting bitcoind on regtest, it sets the IBD flag until a few blocks
have been mined. However, this isn't a real IBD and it doesn't prevent
eclair from working at all, so we should ignore that requirement.
We changed the logging MDC key for tx-publishing in #2131, but forgot to
add a formatting rule in logback.xml for that new field, so it wasn't
written to logs.
We used to compute the edge weight before checking that the edge could actually relay the payment.
Since #2111 we throw an exception in case `heuristicsConstants` are used and the edge can't relay the payment instead of just ignoring the edge.
We fix this by checking that the edge can relay the payment before trying to call `addEdgeWeight`.
Give different types to init features / node announcement features / invoice features.
We now accept more invoices (we would previously reject invoices if they required a feature that we don't support but that we know is irrelevant for invoices).
Makes the code a bit cleaner and fixes a bug where `Postman` could respond with both a failure to send and later a `NoReply` after the timeout in case we were expecting a reply.
Refactoring of `PaymentRequest` to pave the way for bolt12 invoices
`PaymentRequest` is renamed to `Invoice` and is now a trait extended by `Bolt11Invoice` and `Bolt12Invoice`. `Bolt12Invoice` will come in a future PR.
Co-authored-by: t-bast <bastuc@hotmail.fr>
If a channel is force-closed before the funding transaction is confirmed,
broadcasting our local commit can be a problem if the funding
tx is double spent. When that happens, the channel stays stuck in the
closing state trying to publish a commit tx with an invalid input.
If we haven't even seen the funding tx in the mempool, we have no way of
being sure that it was double spent, so we would need to keep trying
forever, which pollutes the logs with publishing errors.
Whenever the funding transaction isn't confirmed and we have nothing
at stake, we now directly go to the closed state without publishing our
commitment. This will be an issue for peers who lost state and rely on
us for dataloss protection, but it's not worth exposing ourselves to that
annoying edge case. Our peers should be able to at least keep state
long enough for the funding tx to confirm or for them to force-close.
When we restart, if a downstream channel is closing with a revoked commit,
we should fail the corresponding htlcs in upstream channels.
Otherwise they will be ignored until they timeout, which will cause the
upstream channel to force-close.
If a funding tx is double-spent, we can't publish our commit tx. However,
the previous code would retry very regularly in a loop, polluting the logs.
When that happens, we now only retry when a new block is found.