Liquidity is always provided by an on-chain transaction (channel open or splice), which can be triggered by:
- On-chain funds added by the wallet user.
- A lightning payment to the wallet user requiring additional liquidity.
- On-chain swaps using swap-in-potentiam
- Lightning payments triggering on-the-fly funding
- On-the-fly funding feature bits
- Liquidity Ads HTLC payment types
- The
will_add_htlc
message - On-the-fly funding examples
- On-the-fly channel creation
- On-the-fly splicing using channel balance
- On-the-fly splicing without channel balance
- Reject on-the-fly funding
- On-the-fly funding timeout
- On-the-fly funding with HTLCs timing out
- Disconnection before signing funding transaction
- Disconnection after signing funding transaction
- Disconnection after relaying post-funding HTLCs
- Lightning payments added to funding fee credit
- Implementation details
- Funds are sent to a swap-in-potentiam address.
- Once confirmed, a channel open or a splice can be initiated.
- If there is no channel:
- The wallet sends
open_channel2
. - The LSP will pay the commit tx fees, even though it's not the initiator (see ACINQ/eclair#2845).
- The wallet is only allowed to use swap-in-potentiam inputs in the
interactive-tx
session:- This ensures they cannot double-spend so 0-conf is safe for the LSP.
- 0-conf isn't mandatory, but provides a better UX (handling concurrent liquidity requests without 0-conf is confusing).
- The
request_funds
field MUST be set (at least100 000 sat
) to allow the LSP to pay the commit tx fees.- This also ensures that the LSP is paid some fees for acquiring this new user.
- The wallet amount MUST be sufficient to pay the fees directly during the
interactive-tx
session.
- The wallet sends
- Otherwise:
- The wallet sends
splice_init
. - The wallet is only allowed to use swap-in-potentiam inputs in the
interactive-tx
session. - The
request_funds
field MAY be set (not mandatory, the wallet may have enough inbound liquidity already). - If
request_funds
is set:- The future wallet balance MUST be sufficient to pay the fees directly during the
interactive-tx
session.
- The future wallet balance MUST be sufficient to pay the fees directly during the
- The wallet sends
Bits | Name | Description | Context | Dependencies |
---|---|---|---|---|
560/561 | on_the_fly_funding |
On-the-fly channel funding | IN | option_splice , option_will_fund |
We define a TLV field for update_add_htlc
that allows a relaying node to relay a smaller amount
than the amount encoded in the onion:
tlv_stream
:update_add_htlc_tlvs
- types:
- type: 41041 (
funding_fee
) - data:
- [
u64
:fee
] - [
sha256
:funding_txid
]
- [
- type: 41041 (
We define two new liquidity ads payment_type
s that leverage the TLV field above.
For both of these options, the funding fees are not paid during the interactive-tx
session,
because the buyer doesn't have enough funds to do so. Fees are instead paid from the HTLCs that
will be relayed once the corresponding liquidity has been added.
payment_type
: 128 (from_future_htlc
)- data:
- [
...*sha256
:payment_hashes
]
- [
In the from_future_htlc
option, the seller trusts that the buyer will fulfill the HTLCs when it
relays them after the funding transaction is complete. If the buyer doesn't fulfill, the seller
doesn't get paid for the funding transaction.
payment_type
: 129 (from_future_htlc_with_preimage
)- data:
- [
...*32*byte
:payment_preimages
]
- [
In the from_future_htlc_with_preimage
option, the preimages are immediately revealed, which
ensures that the seller is paid. The buyer trusts that the seller will relay the corresponding
HTLCs after the funding attempt, otherwise it overpaid for the funding transaction.
- type: 41041 (
will_add_htlc
) - data:
- [
chain_hash
:chain_hash
] - [
32*byte
:id
] - [
u64
:amount_msat
] - [
sha256
:payment_hash
] - [
u32
:cltv_expiry
] - [
1366*byte
:onion_routing_packet
] - [
will_add_htlc_tlvs
:tlvs
]
- [
The will_add_htlc
message supports the same TLVs as update_add_htlc
.
tlv_stream
:will_add_htlc_tlvs
- types:
- type: 0 (
blinding_point
) - data:
- [
point
:blinding
]
- [
- type: 0 (
We define a message similar to update_fail_htlc
.
- type: 41042 (
will_fail_htlc
) - data:
- [
32*byte
:id
] - [
sha256
:payment_hash
] - [
u16
:len
] - [
len*byte
:reason
]
- [
And another message similar to update_fail_malformed_htlc
.
- type: 41043 (
will_fail_malformed_htlc
) - data:
- [
32*byte
:id
] - [
sha256
:payment_hash
] - [
sha256
:sha256_of_onion
] - [
u16
:failure_code
]
- [
When rejecting an on-the-fly open_channel2
or splice_init
, we use an
explicit message instead of error
or tx_abort
.
- type: 41044 (
cancel_on_the_fly_funding
) - data:
- [
32*byte
:channel_id
] - [
u16
:payment_hashes_count
] - [
payment_hashes_count*sha256
:payment_hashes
] - [
u16
:reason_len
] - [
reason_len*byte
:reason
]
- [
The sending node:
- SHOULD send
will_add_htlc
if it doesn't have enough channel balance to sendupdate_add_htlc
. - When sending
will_add_htlc
:- MUST NOT fail the matching upstream HTLC.
- MUST reset the
will_add_htlc_timeout
timer associated with thatpayment_hash
. - SHOULD set
will_add_htlc_timeout
to at least 90 seconds (greater than the MPP timeout). - If the
will_add_htlc_timeout
is reached:- MUST fail the matching upstream HTLCs.
- MUST forget all
will_add_htlc
associated with thatpayment_hash
. - SHOULD send a
warning
to its peer.
- When receiving
open_channel2
containingrequest_funds
:- If the
payment_type
isfrom_future_htlc
orfrom_future_htlc_with_preimage
:- If the matching
will_add_htlc
sets cannot pay the liquidity fees orrequest_funds
is too small:- MUST send
cancel_on_the_fly_funding
. - MUST discard the matching
will_add_htlc
sets. - MUST fail the matching upstream HTLCs.
- MUST cancel the
will_add_htlc_timeout
timer associated with thosepayment_hash
es.
- MUST send
- Otherwise:
- SHOULD allow the sender to contribute nothing to the funding transaction.
- MUST cancel the
will_add_htlc_timeout
timer associated with thosepayment_hash
es. - MUST respond with
accept_channel2
including thewill_fund
field. - If an upstream HTLC for one of those
payment_hash
es is close to timing out:- MUST cancel the channel open if the transaction hasn't been signed yet.
- MUST fail all matching upstream HTLCs.
- MUST forget all matching
will_add_htlc
and not relay them later.
- After exchanging
channel_ready
:- MUST relay the HTLCs matching those
payment_hash
es. - MUST use the
funding_fee
field inupdate_add_htlc
to collect the liquidity fees. - SHOULD split the funding fee across multiple HTLCs if necessary.
- If the receiver fails those HTLCs:
- SHOULD blacklist that node and close the channel whenever possible.
- MUST relay the HTLCs matching those
- If the matching
- If the
- When receiving
splice_init
containingrequest_funds
:- If the sender has enough channel balance to pay the liquidity fees:
- MAY reject
splice_init
if it doesn't use thefrom_channel_balance
payment type. - MUST send
cancel_on_the_fly_funding
if it rejectssplice_init
.
- MAY reject
- If the
payment_type
isfrom_future_htlc
orfrom_future_htlc_with_preimage
:- MUST apply similar requirements as
open_channel2
above. - After exchanging
splice_locked
:- MUST relay the HTLCs matching those
payment_hash
es. - MUST use the
funding_fee
field inupdate_add_htlc
to collect the liquidity fees. - SHOULD split the funding fee across multiple HTLCs if necessary.
- If the receiver fails those HTLCs:
- SHOULD blacklist that node and close the channel whenever possible.
- MUST relay the HTLCs matching those
- MUST apply similar requirements as
- If the sender has enough channel balance to pay the liquidity fees:
- On disconnection or restart:
- If no funding transaction was signed that matches the pending
will_add_htlc
:- MUST cancel the
will_add_htlc_timeout
timer. - MUST forget all
will_add_htlc
associated with thatpayment_hash
. - MUST fail the matching upstream HTLCs.
- MUST cancel the
- Otherwise:
- MUST only fail the matching upstream HTLCs if they're close to timing out.
- MUST discard the matching
will_add_htlc
when failing the upstream HTLC.
- If no funding transaction was signed that matches the pending
The receiving node:
- SHOULD use a large enough
min_final_expiry_delta
in invoices to allow funding to complete before receiving HTLCs. - MUST process
will_add_htlc
as if it were a normal HTLC. - MUST use the latest
funding_rates
it has received from the sending node. - If it would have failed that HTLC:
- MUST send
will_fail_htlc
orwill_fail_malformed_htlc
. - MUST forget this
will_add_htlc
.
- MUST send
- If the funding fee is too high:
- MUST fail the corresponding
will_add_htlc
.
- MUST fail the corresponding
- Otherwise, if wants to accept that payment:
- If it has enough channel balance to pay the funding fee:
- MUST send
splice_init
using thefrom_channel_balance
payment type. - When receiving the matching
update_add_htlc
:- MUST reject them if
funding_fee
is included.
- MUST reject them if
- MUST send
- Otherwise:
- MUST send
open_channel2
orsplice_init
usingfrom_future_htlc
orfrom_future_htlc_with_preimage
. - When receiving the matching
update_add_htlc
:- If the
funding_fee
exceeds the expected fee:- MUST fail those
update_add_htlc
.
- MUST fail those
- Otherwise:
- MUST fulfill those
update_add_htlc
.
- MUST fulfill those
- If the
- MUST send
- When receiving
cancel_on_the_fly_funding
:- MUST consider the funding attempts for the corresponding
payment_hash
es failed.
- MUST consider the funding attempts for the corresponding
- If it has enough channel balance to pay the funding fee:
In the following examples, we omit the commit_sig
/ revoke_and_ack
messages
exchanged between Bob and Carol for simplicity.
In this example, Alice and Bob don't have a channel yet. Bob receives two HTLCs
that should be relayed to Alice. Those two HTLCs may or may not use the same
payment_hash
.
After successfully creating the channel, Bob relays the HTLCs and splits the funding fee. If the HTLC amount allows it, Bob may claim the entire funding fee in only one of the HTLCs.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| open_channel2 | |
| (from_future_htlc) | |
|----------------------------->| |
| accept_channel2 | |
| (will_fund) | funding_fee = 1200 sat |
|<-----------------------------| |
| | |
| <interactive-tx> | |
| | |
| channel_ready | |
|----------------------------->| |
| channel_ready | |
|<-----------------------------| |
| | |
| <relay HTLCs> | |
| | |
| update_add_htlc | |
| (funding_fee = 700 sat) | |
|<-----------------------------| |
| update_add_htlc | |
| (funding_fee = 500 sat) | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| update_fulfill_htlc | |
|----------------------------->| |
| update_fulfill_htlc | |
|----------------------------->| update_fulfill_htlc |
| commit_sig |----------------------------->|
|----------------------------->| update_fulfill_htlc |
| revoke_and_ack |----------------------------->|
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | |
In this example, Alice and Bob already have a channel, but all of the channel
liquidity is on Alice's side. Alice thus has enough channel balance to pay the
funding fee via the splice transaction. When relaying the HTLCs after sending
splice_locked
, Bob doesn't need to claim the funding fee since it has already
been paid.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| stfu | |
|----------------------------->| |
| stfu | |
|<-----------------------------| |
| splice_init | |
| (from_channel_balance) | |
|----------------------------->| |
| splice_ack | |
| (will_fund) | |
|<-----------------------------| |
| | |
| <interactive-tx> | |
| | |
| splice_locked | |
|----------------------------->| |
| splice_locked | |
|<-----------------------------| |
| | |
| <relay HTLCs> | |
| | |
| update_add_htlc | |
|<-----------------------------| |
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| update_fulfill_htlc | |
|----------------------------->| |
| update_fulfill_htlc | |
|----------------------------->| update_fulfill_htlc |
| commit_sig |----------------------------->|
|----------------------------->| update_fulfill_htlc |
| revoke_and_ack |----------------------------->|
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | |
In this example, Alice and Bob already have a channel. Alice doesn't have enough channel balance to pay the funding fee, and Bob doesn't have enough channel balance to relay the HTLCs coming from Carol.
After exchanging splice_locked
, Bob relays the HTLCs and splits the funding
fee. If the HTLC amount allows it, Bob may claim the entire funding fee in
only one of the HTLCs.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| stfu | |
|----------------------------->| |
| stfu | |
|<-----------------------------| |
| splice_init | |
| (from_future_htlc) | |
|----------------------------->| |
| splice_ack | |
| (will_fund) | funding_fee = 1500 sat |
|<-----------------------------| |
| | |
| <interactive-tx> | |
| | |
| splice_locked | |
|----------------------------->| |
| splice_locked | |
|<-----------------------------| |
| | |
| <relay HTLCs> | |
| | |
| update_add_htlc | |
| (funding_fee = 650 sat) | |
|<-----------------------------| |
| update_add_htlc | |
| (funding_fee = 850 sat) | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| update_fulfill_htlc | |
|----------------------------->| |
| update_fulfill_htlc | |
|----------------------------->| update_fulfill_htlc |
| commit_sig |----------------------------->|
|----------------------------->| update_fulfill_htlc |
| revoke_and_ack |----------------------------->|
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | |
In this example, Alice receives a multi-part payment that can be partially relayed with HTLCs. The remaining part requires on-the-fly funding, but Alice rejects it (e.g. the funding fee is too high).
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| will_fail_htlc | |
|----------------------------->| |
| | update_fail_htlc |
| |----------------------------->|
| | |
| <MPP timeout> | |
| | |
| update_fail_htlc | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | update_fail_htlc |
| |----------------------------->|
| | |
In this example, Alice receives a multi-part payment with one normal HTLC and the remaining part as an on-the-fly funding proposal. Alice accepts the funding proposal, but Bob times out before receiving Alice's response.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| stfu | |
|----------------------------->| |
| stfu | |
|<-----------------------------| |
| | |
| <will_add_htlc_timeout> | |
| | |
| warning | |
| <-----------| update_fail_htlc |
| splice_init |----------------------------->|
|---------------> | |
| warning | |
|<----------- | |
| splice_init | |
| --------------->| |
| cancel_on_the_fly_funding | |
|<-----------------------------| |
| | |
| <MPP timeout> | |
| | |
| update_fail_htlc | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | update_fail_htlc |
| |----------------------------->|
| | |
In this example, Alice accepts an on-the-fly funding proposal, but doesn't send
channel_ready
. The upstream HTLC times out, which forces Bob to fail them. At
that point, Bob cannot relay the HTLC to Alice anymore, and wasn't paid for the
channel funding. Bob may require using from_future_htlc_with_preimage
instead
of from_future_htlc
to protect against this issue.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| open_channel2 | |
| (from_future_htlc) | |
|----------------------------->| |
| accept_channel2 | |
| (will_fund) | |
|<-----------------------------| |
| | |
| <interactive-tx> | |
| | |
| channel_ready | |
|<-----------------------------| |
| | |
| | <HTLC close to expiry> |
| | |
| | update_fail_htlc |
| |----------------------------->|
| warning | |
|<-----------------------------| |
| channel_ready | |
|----------------------------->| |
| | |
| <no HTLCs relayed> | |
| | |
In this example, Alice and Bob are disconnected before completing the funding transaction. The funding attempt is aborted, and the matching upstream HTLC are failed. Once the MPP timeout hits, Alice fails the first payment part that was relayed with a normal HTLC.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| stfu | |
|----------------------------->| |
| stfu | |
|<-----------------------------| |
| splice_init | |
| (from_future_htlc) | |
|----------------------------->| |
| splice_ack | |
| (will_fund) | |
|<-----------------------------| |
| | |
| <disconnection> | update_fail_htlc |
| |----------------------------->|
| channel_reestablish | |
|<-----------------------------| |
| channel_reestablish | |
|----------------------------->| |
| | |
| <MPP timeout> | |
| | |
| update_fail_htlc | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | update_fail_htlc |
| |----------------------------->|
| | |
In this example, Alice and Bob are disconnected after completing the funding transaction. Bob must keep track of the HTLCs that need to be relayed when reconnecting (unless the upstream HTLCs timeout before that).
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| open_channel2 | |
| (from_future_htlc) | |
|----------------------------->| |
| accept_channel2 | |
| (will_fund) | |
|<-----------------------------| |
| | |
| <interactive-tx> | |
| | |
| channel_ready | |
|-----------------X | |
| | |
| <disconnection> | |
| | |
| channel_reestablish | |
|<-----------------------------| |
| channel_reestablish | |
|----------------------------->| |
| | |
| <relay HTLCs> | |
| | |
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| update_fulfill_htlc | |
|----------------------------->| update_fulfill_htlc |
| commit_sig |----------------------------->|
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | |
In this example, Alice and Bob are disconnected after completing the funding transaction and trying to relay the corresponding HTLCs. Bob must keep track of those HTLCs and relay them again when reconnecting (unless the upstream HTLCs timeout before that).
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| stfu | |
|----------------------------->| |
| stfu | |
|<-----------------------------| |
| splice_init | |
| (from_future_htlc) | |
|----------------------------->| |
| splice_ack | |
| (will_fund) | |
|<-----------------------------| |
| | |
| <interactive-tx> | |
| | |
| splice_locked | |
|<-----------------------------| |
| splice_locked | |
|----------------------------->| |
| | |
| <relay HTLCs> | |
| | |
| update_add_htlc | |
| X-------------------| |
| | |
| <disconnection> | |
| | |
| channel_reestablish | |
|<-----------------------------| |
| channel_reestablish | |
|----------------------------->| |
| | |
| <relay HTLCs> | |
| | |
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| update_fulfill_htlc | |
|----------------------------->| update_fulfill_htlc |
| update_fulfill_htlc |----------------------------->|
|----------------------------->| update_fulfill_htlc |
| commit_sig |----------------------------->|
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | |
Bits | Name | Description | Context | Dependencies |
---|---|---|---|---|
562/563 | funding_fee_credit |
On-the-fly funding fee credit | IN | on_the_fly_funding |
The add_fee_credit
message reveals the preimage associated with some will_add_htlc
messages
and expects the receiver to add the corresponding amount to its fee credit.
- type: 41045 (
add_fee_credit
) - data:
- [
chain_hash
:chain_hash
] - [
32*byte
:payment_preimage
]
- [
The current_fee_credit
message lets the receiver know how much fee credit they currently have.
- type: 41046 (
current_fee_credit
) - data:
- [
chain_hash
:chain_hash
] - [
u64
:amount_msat
] - [
current_fee_credit_tlvs
:tlvs
]
- [
The latest_payments
field provides the latest preimages received by the sender, which acts as an
acknowledgement for the corresponding add_fee_credit
messages. This lets the buyer detect when
add_fee_credit
messages have been lost during a disconnection.
tlv_stream
:current_fee_credit_tlvs
- types:
- type: 1 (
latest_payments
) - data:
- [
...*32*byte
:payment_preimages
]
- type: 1 (
We also define a new payment_type
for liquidity ads, which lets a buyer pay the funding fee
using its fee credit.
payment_type
: 130 (from_fee_credit
)
A node that supports buying fee credit:
- When accepting a set of
will_add_htlc
messages:- If it has enough fee credit to pay the funding fee:
- MUST send
open_channel2
orsplice_init
using thefrom_fee_credit
payment type.
- MUST send
- Otherwise:
- MUST send
add_fee_credit
, revealing the payment preimage. - MUST consider the incoming payment complete.
- MUST send
- If it has enough fee credit to pay the funding fee:
- When receiving
current_fee_credit
:- If
latest_payments
is set:- If
add_fee_credit
was sent andlatest_payments
does not contain itspayment_hash
:- MUST consider that the amount was not added to its fee credit.
- If
- If
A node that supports selling fee credit:
- When receiving
add_fee_credit
:- If it has some pending
will_add_htlc
matching thatpayment_hash
:- MUST cancel the
will_add_htlc_timeout
timer associated with thatpayment_hash
. - MUST fulfill the matching upstream HTLCs.
- MUST forget all
will_add_htlc
associated with that payment_hash. - MUST add the
will_add_htlc
amount to the sender's fee credit. - MUST sent
current_fee_credit
with the updated fee credit.
- MUST cancel the
- Otherwise:
- SHOULD send a
warning
. - MUST send
current_fee_credit
with the current fee credit.
- SHOULD send a
- If it has some pending
- When receiving
open_channel2
orsplice_init
with thefrom_fee_credit
payment type:- If the sender has enough fee credit to pay the funding fee:
- SHOULD allow the sender to contribute nothing to the funding transaction.
- MUST respond with
accept_channel2
orsplice_ack
including thewill_fund
field. - After exchanging
tx_signatures
:- MUST send
current_fee_credit
with the updated fee credit. - For all pending
will_add_htlc
that can now be relayed:- MUST send a matching
update_add_htlc
without afunding_fee
field. - MUST cancel the
will_add_htlc_timeout
timer associated with thatpayment_hash
. - MUST forget that
will_add_htlc
.
- MUST send a matching
- MUST send
- Otherwise:
- MUST send
cancel_on_the_fly_funding
. - MUST send
current_fee_credit
.
- MUST send
- If the sender has enough fee credit to pay the funding fee:
In this example, Alice receives a multi-part payment with one HTLC and one
will_add_htlc
. She decides to fulfill that payment and add the
will_add_htlc
part to her fee credit.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| add_fee_credit | |
|----------------------------->| |
| | update_fulfill_htlc |
| |----------------------------->|
| current_fee_credit | |
|<-----------------------------| |
| update_fulfill_htlc | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | update_fulfill_htlc |
| |----------------------------->|
| | |
In this example, Alice receives will_add_htlc
. She decides to add it to her
fee credit, but unfortunately, it concurrently times out on Bob's side, who
fails the upstream HTLCs. The amount is not added to Alice's fee credit, and
Carol doesn't receive the payment preimage.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| | |
| <will_add_htlc_timeout> | |
| | update_fail_htlc |
| |----------------------------->|
| add_fee_credit | |
|----------------------------->| |
| warning | |
|<-----------------------------| |
| current_fee_credit | |
|<-----------------------------| |
| | |
In this example, Alice receives a multi-part payment with one HTLC and one
will_add_htlc
. She decides to fulfill that payment and add the
will_add_htlc
part to her fee credit. Unfortunately, the will_add_htlc
times out on Bob's side, who fails the upstream HTLCs. The will_add_htlc
amount is not added to Alice's fee credit, and Carol receives the preimage
with a partial payment. If the buyer wants to ensure that this cannot happen,
they shouldn't send add_fee_credit
for multi-part payments that contain an
HTLC.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| | |
| <will_add_htlc_timeout> | |
| | update_fail_htlc |
| |----------------------------->|
| add_fee_credit | |
|----------------------------->| |
| warning | |
|<-----------------------------| |
| current_fee_credit | |
|<-----------------------------| |
| update_fulfill_htlc | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | update_fulfill_htlc |
| |----------------------------->|
| | |
In this example, Alice receives a multi-part payment with one HTLC and one
will_add_htlc
. She decides to fulfill that payment and add the
will_add_htlc
part to her fee credit. A disconnection happens before Bob
can receive her add_fee_credit
message. Bob forgets the pending
will_add_htlc
and fails the upstream HTLC. On reconnection, Alice detects
that Bob didn't receive add_fee_credit
and can update her internal state.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| add_fee_credit | |
|------------------X | |
| update_fulfill_htlc | |
|-----------------------X | |
| | |
| <disconnection> | |
| | update_fail_htlc |
| |----------------------------->|
| channel_reestablish | |
|----------------------------->| |
| channel_reestablish | |
|<-----------------------------| |
| current_fee_credit | |
|<-----------------------------| |
| | |
| update_fulfill_htlc | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | update_fulfill_htlc |
| |----------------------------->|
| | |
In this example, Alice receives a multi-part payment with one HTLC and one
will_add_htlc
. She has enough fee credit and initiates on-the-fly funding.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| stfu | |
|----------------------------->| |
| stfu | |
|<-----------------------------| |
| splice_init | |
| (from_fee_credit) | |
|----------------------------->| |
| splice_ack | |
| (will_fund) | |
|<-----------------------------| |
| | |
| <interactive-tx> | |
| | |
| current_fee_credit | |
|<-----------------------------| |
| | |
| splice_locked | |
|----------------------------->| |
| splice_locked | |
|<-----------------------------| |
| | |
| <relay HTLCs> | |
| | |
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| update_fulfill_htlc | |
|----------------------------->| |
| update_fulfill_htlc | |
|----------------------------->| update_fulfill_htlc |
| commit_sig |----------------------------->|
|----------------------------->| update_fulfill_htlc |
| revoke_and_ack |----------------------------->|
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | |
In this example, Alice receives a multi-part payment with one HTLC and one
will_add_htlc
. She has enough fee credit and initiates on-the-fly funding.
The will_add_htlc
times out before funding completes.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| stfu | |
|----------------------------->| |
| stfu | |
|<-----------------------------| |
| splice_init | |
| (from_fee_credit) | |
|----------------------------->| |
| splice_ack | |
| (will_fund) | |
|<-----------------------------| |
| | |
| <interactive-tx> | |
| | |
| <will_add_htlc_timeout> | |
| | |
| warning | |
|<-----------------------------| update_fail_htlc |
| |----------------------------->|
| current_fee_credit | |
|<-----------------------------| |
| | |
| splice_locked | |
|----------------------------->| |
| splice_locked | |
|<-----------------------------| |
| | |
| <MPP timeout> | |
| | |
| update_fail_htlc | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | update_fail_htlc |
| |----------------------------->|
| | |
In this example, Alice receives a multi-part payment with one HTLC and one
will_add_htlc
. She initiates on-the-fly funding, but doesn't have enough
fee credit.
Alice Bob Carol
| | update_add_htlc |
| |<-----------------------------|
| update_add_htlc | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| | update_add_htlc |
| |<-----------------------------|
| will_add_htlc | |
|<-----------------------------| |
| stfu | |
|----------------------------->| |
| stfu | |
|<-----------------------------| |
| splice_init | |
| (from_fee_credit) | |
|----------------------------->| |
| cancel_on_the_fly_funding | |
|<-----------------------------| |
| current_fee_credit | |
|<-----------------------------| |
| | |
| <will_add_htlc_timeout> | |
| | |
| warning | |
|<-----------------------------| update_fail_htlc |
| |----------------------------->|
| | |
| <MPP timeout> | |
| | |
| update_fail_htlc | |
|----------------------------->| |
| commit_sig | |
|----------------------------->| |
| revoke_and_ack | |
|<-----------------------------| |
| commit_sig | |
|<-----------------------------| |
| revoke_and_ack | |
|----------------------------->| |
| | update_fail_htlc |
| |----------------------------->|
| | |
The following implementation details are specific to eclair
and
lightning-kmp
, but may be useful for other implementations.
The HTLC recipient should handle all will_add_htlc
parts together with normal
HTLC parts. When it wants to accept a set of will_add_htlc
parts, it should
send open_channel2
or splice_init
and flush the will_add_htlc
parts from
the incoming payment handler. If there are normal HTLC parts, it should extend
the MPP timeout timer to ensure that the will_add_htlc
parts are relayed as
normal HTLCs before the timeout.
When accepting a set of will_add_htlc
parts, the total funding fee must be
stored with the funding transaction, to allow checking that it matches the fees
that may later be subtracted from incoming HTLCs.
If from_channel_balance
was used, store an outgoing payment for a liquidity
purchase in the payments DB when the funding transaction completes.
If from_future_htlc
or from_future_htlc_with_preimage
was used, don't store
anything in the payments DB when the funding transaction completes. An incoming
payment will be stored when we later receive the HTLCs, and the funding fees
will be correctly recorded since they're included in the funding_fee
field.
If from_fee_credit
was used, store an outgoing payment for a liquidity
purchase in the payments DB when the funding transaction completes.
When funding_fee_credit
is supported and we send add_fee_credit
, we should
immediately store an incoming payment in the DB and mark it as received as fee
credit. It should initially be flagged as unconfirmed, since we don't know yet
if our peer received our add_fee_credit
message and if the will_add_htlc
have not timed out on its side. When we then receive current_fee_credit
, we
can check the latest_payments
field and update our payments DB to mark the
fee credit as confirmed.
When signing an on-the-fly funding transaction (before sending commit_sig
),
the node must record the corresponding HTLC set and the funding fee. On
disconnection or restart, it must not fail the corresponding upstream HTLCs
(unless they are close to timing out). If an upstream HTLC is failed because
it is close to timing out, the HTLC set must be cleared from the DB.
The node may want to check the HTLC expiry before offering will_add_htlc
and
only offer it when the expiry is far enough in the future.
If a buyer cheats and fails the relayed HTLCs, it's unclear whether we should
use a scorched earth strategy and immediately force-close, since we've already
broadcast the transaction (and the buyer may be buggy instead of malicious).
Maybe we should simply mark them as fishy, and not accept from_future_htlc
from them anymore and only allow from_channel_balance
and from_fee_credit
.
When receiving open_channel2
or splice_init
using from_fee_credit
, we
should only decrease the fee credit in our DB when we send tx_signatures
for the funding transaction (which guarantees that both sides are committed
to complete that funding transaction even if they get disconnected). There
may be some edge cases when we disconnect after receiving commit_sig
but
before sending tx_signatures
, we must make sure we get this right during
the implementation.