If the latest splice transaction doesn't confirm, we allow exchanging
`tx_init_rbf` and `tx_ack_rbf` to create another splice transaction to
replace it. We use the same funding contribution as the previous splice.
When 0-conf isn't used, we reject `splice_init` while the previous
splice transaction hasn't confirmed. Our peer should either use RBF
instead of creating a new splice, or they should wait for our node
to receive the block that confirmed the previous transaction. This
protects against chains of unconfirmed transactions.
When using 0-conf, we reject `tx_init_rbf` and allow creating chains of
unconfirmed splice transactions: using RBF with 0-conf can lead to one
side stealing funds, which is why we prevent it.
If our peer was buying liquidity but tries to cancel the purchase with
an RBF attempt, we reject it: this prevents edge cases where the seller
may end up adding liquidity to the channel without being paid in return.
* Add support for extensible liquidity ads
The initiator of `open_channel2`, `tx_init_rbf` and `splice_init` can
request funding from the remote node. The non-initiator node will:
- let the open-channel-interceptor plugin decide whether to provide
liquidity for new channels or not, and how much
- always honor liquidity requests on existing channels (RBF and splice)
when funding rates have been configured
Liquidity ads are included in the `node_announcement` message, which
lets buyers compare sellers and connect to sellers that provide rates
they are comfortable with. They are also included in the `init` message
which allows providing different rates to specific peers.
This implements https://github.com/lightning/bolts/pull/1153. We
currently use the temporary tlv tag 1339 while we're waiting for
feedback on the spec proposal.
* Add `channelCreationFee` to liquidity ads
Creating a new channel has an additional cost compared to adding
liquidity to an existing channel: the channel will be closed in the
future, which will require paying on-chain fees. Node operators can
include a `channel-creation-fee-satoshis` in their liquidity ads to
cover some of that future cost.
* Add liquidity purchases to the `AuditDb`
Whenever liquidity is purchased, we store it in the `AuditDb`. This lets
node operators gather useful statistics on their peers, and which ones
are actively using the liquidity that is purchased.
We store minimal information about the liquidity ads itself to be more
easily compatible with potential changes in the spec.
When nodes only have private channels, they must include routing hints
in their Bolt 11 invoices to be able to receive payments. We add a
parameter to the `createinvoice` RPC for this. Note that this may leak
the channel outpoint if `scid_alias` isn't used.
Fixes#2802
* Reject new static_remote_key channels
We will still load and use existing static_remote_key channels, we can still open static_remote_key channels, but we will not accept new static_remote_key channels.
This behaviour can be overridden by setting `eclair.channel.accept-incoming-static-remote-key-channels` to `true`.
* Reject new obsolete incoming channels
We reject new incoming channels that don't even support `option_static_remotekey` (which is assumed to be on in the BOLTs).
Unit tests have been modified to use static_remote_key or anchor channels (default used to be the obsolete "standard" channel).
---------
Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
Bitcoin Core 26.1 contains ancestor-aware funding: it will automatically
fetch unconfirmed ancestors during funding and adapt the fee to apply
the target feerate to the whole unconfirmed package.
We had custom code to implement this entirely in eclair, which we can
now remove.
* Add configurable threshold on maximum anchor fee
We previously bumped up to 5% of our channel balance when no HTLCs were
at risk. For large channels, 5% is an unreasonably high value. In most
cases it doesn't matter, because the transaction confirms before we try
to bump it to unreasonable levels. But if the commitment transaction
was pruned and couldn't be relayed to miners, then eclair would keep
trying to bump until it reached that threshold. We now restrict this to
a value configurable by the node operator. Note that when HTLCs are at
risk, we still bump up to the HTLC amount, which may be higher than the
new configuration parameter: we want that behavior as a scorched earth
strategy against pinning attacks.
* Add feerate upper bound from fee estimator
We add a new limit to the feerate used for fee-bumping, based on the
fastest feerate returned by our fee estimator. It doesn't make sense
to use much higher values, since this feerate should guarantee that
the transaction is included in the next block.
When opening an important channel we may be willing to pay a high feerate that we wouldn't want to use when consolidating UTXOs. However because we delegate the transaction creation to bitcoin core, we can sometimes be surprised by funding transactions that are much bigger than expected. This PR protects us from such cases by refusing to open the channel if the transaction fee is too high.
Based on original work from @thomash-acinq.
Some channels have only a few sats available to send but other nodes don't know it so they try to use them and fail.
When the balance goes below configurable thresholds we now advertize a lower maxHtlcAmount.
This should reduce the number of failed attempts and benefit the network.
* Make Eclair manage bitcoin core's wallet private keys
We create an empty watch-only wallet and import public descriptors generated by Eclair.
Bitcoin Core can fund transaction and manage utxos, but can no longer sign transactions.
* Check that spent amounts and utxos are consistent before we sign a PSBT
PSBT utxo fields include the amount that are being spent by the PSBT inputs, but there is a "fee attack"
where using amounts that are lower than what is actually spent may make us sign a tx that spends much more
in fees than we think.
* Check that non-segwit uxto has been provided and inputs are signed with SIGHASH_ALL
* Verify that Bitcoin Core's fee match what we specified
When we call Bitcoin Core's `fundrawtransaction` RPC method, we check that the fee that we pay match the fee rate that we requested.
The fee is computed using the utxo information that Bitcoin Core adds to our PSBT before we sign it.
We can safely used this information because if Bitcoin Core lies about the value of the inputs that we're spending then the signature we produce will also not be valid (it commits to the value being spent).
When we're adding wallet inputs to "bump" the fees of a parent transaction we need to take the whole package into account when we verify the actual fee rate, which is why some internal methods were modified to return the package weight that was used as reference when `fundrawtransaction` was called.
* Check that fundrawtransaction does not add more than 1 change output
* Validate addresses and keys generated by bitcoin core
When eclair manages private keys, make sure that we can re-compute addresses and keys
generated by bitcoin core.
* Add a separate configuration file for Eclair's onchain signer
Eclair's onchain signer now has its own `eclair-signer.conf` configuration file in HOCON format.
It includes BIP39 mnemonic codes and passphrase, a wallet name and a timestamp.
When an `eclair-signer.conf` file is found, Eclair's API will return descriptors that can be imported into an
empty watch-only Bitcoin Wallet.
When wallet name in `eclair-signer.conf` matches the name of the Bitcoin Core wallet defined in `eclair.conf`
(`eclair.bitcoind.wallet`), Eclair will bypass Bitcoin Core and sign onchain transactions directly.
* Skip validation of local non-change outputs:
Local non-change outputs send to an external address, for splicing out funds for example.
We assume that these inputs are trusted i.e have been created by a trusted API call and our local
onchain key manager will not validate them during the signing process.
* Document why we use a separate, specific file for the onchain key manager
Using a new signer section is eclair.conf would be simpler but "leaks" because it becomes available everywhere
in the code through the actor system's settings instead of being contained to where it is actually needed
and could potentially be exposed through a bug that "exports" the configuration (through logs, ....)
though this is highly unlikely.
* Additional changes to delegate bitcoin core keys to eclair (#2726)
Refactor the `BitcoinCoreClient` and `LocalOnChainKeyManager` to:
- rely less on exceptions
- use more idiomatic scala (reduce dependency on kotlin types)
- provide more detailed logs
We also simplify the `useEclairSigner` field in `BitcoinCoreClient`.
The complexity of handling the case where there was an on-chain key
manager but for a different wallet than the one configured isn't
something that should be used, so it wasn't worth supporting.
Some checks were inconsistent and are now unified:
- checking the exact `scriptPubKey` in our outputs in TODO and TODO
- we allow using `fundTransaction` with a tx that already includes a
change output (which may happen when RBF-ing a transaction)
- `getP2wpkhPubkeyHashForChange` didn't verify the returned key
We completely separate the two cases in `signPsbt`, because otherwise
in the non eclair-backed case, we were calling bitcoind's `processpsbt`
twice for no good reason, which is bad for performance.
We also decouple the `OnChainKeyManager` from the `BitcoinCoreClient`.
This lets users keep running their eclair node with a bitcoin client that
owns the private key while configuring the on-chain key manager for a
future bitcoin client that will leverage this on-chain key manager.
Users can use the eclair APIs to get the master xpub and descriptors to
properly configure their next bitcoin core node, and switch to it once it
has synchronized the descriptors.
* Simplify replaceable tx funding
We were previously signing twice (with makes a call to `bitcoind`),
just to get the final weights and adjust the change outputs. This was
unnecessary, as we can adjust the weights before adding inputs.
We were also duplicating the checks where we verify that `bitcoind` is
malicious. We only need to check that once, during the final signing step.
---------
Co-authored-by: Bastien Teinturier <31281497+t-bast@users.noreply.github.com>
Node operators may disable automatic fee-bumping on their local commit if
they don't have anything at stake (no pending HTLCs), which saves fees in
most cases. A drawback in that case is that if the commitment doesn't
confirm quickly enough, the remote's funds are also locked.
This can be an issue for LSPs, where the remote peer doesn't have a good
ability to fee-bump commit txs. We give more control to the node operator
by letting them fee-bump local commit txs explicitly through the RPC to
unblock wallet users funds.
Move away from the "block target" approach.
Get rid of the `FeeEstimator` abstraction and use an `AtomicReference` to store and update the current feerates, similar to the block count.
This RPC allows to access the historic channel data without
relying on third party services like LN explorers.
Note that when the `remoteNodeId` filter is not provided, this
query may be expensive on nodes with a lot of closed channels.
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`.
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).
* 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.
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.
* 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.
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.
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
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.
Starting with bitcoind 23.0, a new `changetype` parameter was introduced.
If not specified, bitcoind will generate a change output with a type that
matches the main output to make it harder for chain analysis to detect
which output is the change.
The issue is that lightning requires segwit utxos: if an on-chain payment
is sent to a non-segwit address, we still want our change output to use
segwit, otherwise we won't be able to use it. We thus must set
`addresstype` and `changetype` in `bitcoin.conf` to ensure we never
generate legacy change addresses.
This release of bitcoind contains several bug fixes that let us simplify
our fee bumping logic:
- fixed a bug where bitcoind dropped non-wallet signatures
- added an option to fund transactions containing non-wallet inputs
It also has support for Taproot, which we want in eclair.
We previously only supported `scid_alias` and `zero_conf` when used in
combination with `anchors_zero_fee_htlc_tx`, but we have no way of
advertising that to our peers, which leads to confusing failures when
opening channels.
Some nodes that don't have good access to a utxo pool may not migrate to
anchor outputs, but may still want to use `scid_alias` (and potentially
`zero_conf` as well).
Fixes#2394
Add support for bumping the fees of a dual funding transaction.
We spawn a transient dedicated actor: if the RBF attempt fails, or if we
are disconnected before completing the protocol, we should forget it.
Add more tests for scenarios where an unconfirmed channel is force-closed,
where the funding transaction that confirms may not be the last one.
It is now possible to specify a DNS host name as one of your
`server.public-ips` addresses.
DNS host names will not be resolved until eclair attempts to
connect to the peer.
See https://github.com/lightning/bolts/pull/911
When a channel force-close without any pending htlcs, funds are not at
risk. We want to eventually get our main output back, but if we are not
in a rush we can save on fees by never spending the anchors.
This is disabled by default as there is a potential risk: if the commit
tx doesn't confirm and the feerate rises, the commit tx may eventually be
below the network's min-relay-fee and won't confirm (at least until package
relay is available).
We now use either our local alias or the real scid in the channel update
that we store internally. When we send that channel update directly to
our peer, we override it to use the remote alias when it makes sense.
The `override-init-features` field in `eclair.conf` was not previously
applied on top of the `features` field, so node operators were usually
copy-pasting their `features` overrides in every `override-init-features`.
The overrides are now applied on top of the base `features` configuration,
which makes it easier and more intuitive to configure per-node features.