From 043b698471c4cc0f2d0e4cb6856f132690e377f9 Mon Sep 17 00:00:00 2001 From: t-bast Date: Thu, 11 Jul 2024 10:50:33 +0200 Subject: [PATCH] blip-0041: channel funding fee credit Onboarding users to the lightning network is hard, because opening a channel requires paying on-chain fees and allocating capital, hoping that it will be used to earn routing fees. It is not economical nor sustainable to open channels for users that receive a tiny amount and may not use the network frequently enough. Wallet providers usually work around this issue by requiring users to receive a large enough first payment to pay on-chain fees for their channel. However, a collection of unrelated tiny payments received over a period of time may be enough to justify creating a channel. We thus introduce a funding fee credit, that lets users prepay for future channel(s) by proactively revealing htlc preimages for small payments. When that fee credit reaches a sufficient amount, it is used by the remote node to cover the on-chain costs of opening a channel or splicing additional liquidity. --- README.md | 1 + blip-0002.md | 3 + blip-0041.md | 597 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 601 insertions(+) create mode 100644 blip-0041.md diff --git a/README.md b/README.md index 602b3c7..f8dd82d 100644 --- a/README.md +++ b/README.md @@ -27,3 +27,4 @@ For more detail on the process, please read [bLIP-0001](./blip-0001.md) and | [17](./blip-0017.md) | Hosted Channels | Anton Kumaigorodskiy | Active | | [25](./blip-0025.md) | Forward less than onion value | Valentine Wallace | Active | | [32](./blip-0032.md) | Onion Message DNS Resolution | Matt Corallo | Active | +| [41](./blip-0041.md) | Channel Funding Fee Credit | Bastien Teinturier | Active | diff --git a/blip-0002.md b/blip-0002.md index 14b104c..4b2fef7 100644 --- a/blip-0002.md +++ b/blip-0002.md @@ -50,6 +50,7 @@ bLIPs may reserve feature bits by adding them to the following table: | 54/55 | `keysend` | A form of spontaneous payment | N | `var_onion_optin` | [bLIP 3](./blip-0003.md) | | 256/257 | `hosted_channels` | This node accepts requests for hosted channels | IN | | [bLIP 17](./blip-0017.md) | | 258/259 | `dns_resolver` | This node accepts DNSSEC proof requests | N | | [bLIP 32](./blip-0032.md) | +| 562/563 | `funding_fee_credit` | This node provides fee credit for channel funding | IN | `on_the_fly_funding` | [bLIP 41](./blip-0041.md) | ### Messages @@ -61,6 +62,8 @@ bLIPs may create new messages and reserve their type in the following table: | Type | Name | Link | | ------- | ------------------------------- | -------------------------- | +| 41045 | `add_fee_credit` | [bLIP 41](./blip-0041.md) | +| 41046 | `current_fee_credit` | [bLIP 41](./blip-0041.md) | | 65535 | `invoke_hosted_channel` | [bLIP 17](./blip-0017.md) | | 65533 | `init_hosted_channel` | [bLIP 17](./blip-0017.md) | | 65531 | `last_cross_signed_state` | [bLIP 17](./blip-0017.md) | diff --git a/blip-0041.md b/blip-0041.md new file mode 100644 index 0000000..cb1bed2 --- /dev/null +++ b/blip-0041.md @@ -0,0 +1,597 @@ +``` +bLIP: 41 +Title: Channel funding fee credit +Status: Active +Author: Bastien Teinturier +Created: 2024-07-09 +License: CC0 +``` + +## Abstract + +Onboarding users to the lightning network is hard, because opening a channel +requires paying on-chain fees and allocating capital, hoping that it will be +used to earn routing fees. It is not economical nor sustainable to open +channels for users that receive a tiny amount and may not use the network +frequently enough. + +Moreover, tiny payments may be too small to pay fees for an on-chain +transaction: but a collection of unrelated tiny payments received over a +potentially long period of time may be enough to justify creating a channel. + +We introduce a funding fee credit, where users prepay for future channel(s) +by proactively revealing htlc preimages for small payments. When that fee +credit reaches a sufficient amount, it is used by the remote node to cover +the on-chain costs of opening a channel or splicing additional liquidity. + +## Copyright + +This bLIP is licensed under the CC0 license. + +## Motivation + +This feature ensures that liquidity providers can onboard new users without +worrying about threshold effects for small payments. It also reduces the +frequency of on-chain funding operations whenever more liquidity needs to be +allocated, which lowers the on-chain footprint of users who frequently receive +small payments (such as donations). + +## Specification + +This feature depends on the on-the-fly funding feature specified in +[bLIP 36](./blip-0036.md). It provides an additional response path for +`will_add_htlc` messages. + +### The `add_fee_credit` and `current_fee_credit` messages + +The `add_fee_credit` message reveals the preimage associated with some +incoming `will_add_htlc` messages in exchange for fee credit with the +sending node. + +1. type: 41045 (`add_fee_credit`) +2. 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. + +1. type: 41046 (`current_fee_credit`) +2. data: + - [`chain_hash`:`chain_hash`] + - [`u64`:`amount_msat`] + +### Requirements + +A node that supports buying fee credit: + +- When accepting a set of `will_add_htlc` messages: + - If its current channel balance combined with its current fee credit is enough + to pay the on-the-fly funding fees: + - SHOULD send `open_channel2` or `splice_init`. + - MUST use the `from_channel_balance_for_future_htlc` payment type. + - If the incoming payment combined with its current fee credit is enough to pay + the on-the-fly funding fees: + - SHOULD send `open_channel2` or `splice_init`. + - MUST use the `from_future_htlc` or `from_future_htlc_with_preimage` payment type, + depending on what the remote node supports. + - Otherwise: + - SHOULD send `add_fee_credit` to add the payment amount to its fee credit. + - MUST consider the incoming payment complete. + +A node that supports selling fee credit: + +- When receiving `add_fee_credit`: + - If it has some pending `will_add_htlc` matching that `payment_hash`: + - MUST cancel the `will_add_htlc_timeout` timer associated with that `payment_hash`. + - MUST fulfill all 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. + - Otherwise: + - SHOULD send a `warning`. + - MAY send `current_fee_credit` with the current fee credit. +- When receiving `splice_init` using the `from_channel_balance_for_future_htlc` payment type: + - If the current fee credit is higher than the on-the-fly funding fees: + - SHOULD accept the splice. + - MUST use that fee credit to pay the on-the-fly funding fees. + - MUST NOT collect fees from the remote channel balance. + - Otherwise, if the remote channel balance can pay the missing fees: + - SHOULD accept the splice. + - MUST use all of the fee credit to partially pay the on-the-fly funding fees. + - MUST collect the remaining fees from the remote channel balance. + - Otherwise: + - MUST send `cancel_on_the_fly_funding`. + - SHOULD send `current_fee_credit`. +- When receiving `open_channel2` or `splice_init` using the `from_future_htlc` or `from_future_htlc_with_preimage` payment type: + - If the current fee credit is higher than the on-the-fly funding fees: + - SHOULD accept the channel open or splice. + - MUST use that fee credit to pay the on-the-fly funding fees. + - MUST NOT collect fees from future HTLCs. + - Otherwise, if the payment amount can pay the missing fees: + - SHOULD accept the channel open or splice. + - MUST use all of the fee credit to partially pay the on-the-fly funding fees. + - MUST collect the remaining fees from future HTLCs. + - Otherwise: + - MUST send `cancel_on_the_fly_funding`. + - SHOULD send `current_fee_credit`. +- After exchanging `commitment_signed` for the funding transaction: + - MUST send `current_fee_credit` with the updated fee credit. +- After exchanging `channel_ready` or `splice_locked`: + - MUST relay the HTLCs matching the on-the-fly payment. + - MUST set `funding_fee` in `update_add_htlc` to collect the fees that weren't paid from fee credit. + - MUST set `funding_fee`, even if `fees_msat` is `0 msat`. + +### Rationale + +The fee credit is always used in combination with on-the-fly funding payment +types. We collect fees from the fee credit first, which ensures that it +converges to 0. + +The node sending `add_fee_credit` is trusting its peer to correctly keep track +of the current fee credit and use it when funding channels. It may choose to +limit its exposure by only adding payments that are below a given threshold to +its fee credit. + +Liquidity providers may use the fee credit feature to avoid the trust issues +associated with the `from_future_htlc` and `from_future_htlc_with_preimage` +payment types, and only allow using the channel balance combined with some +fee credit to pay for on-the-fly channel funding. + +### Fee credit examples + +This section contains protocol flows that show how messages are exchanged in +various common scenarios. This is also a good check-list to verify that your +implementation correctly handles known edge cases. + +Note that we omit the `commit_sig` / `revoke_and_ack` messages exchanged +between Bob and Carol for simplicity. + +#### Fee credit purchase + +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. + +```txt + Alice Bob Carol + | | update_add_htlc | + | | (id = 7) | + | |<-----------------------------| + | update_add_htlc | | + | (id = 0) | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | | update_add_htlc | + | | (id = 8) | + | |<-----------------------------| + | will_add_htlc | | + |<-----------------------------| | + | add_fee_credit | | + |----------------------------->| | + | | update_fulfill_htlc | + | | (id = 8) | + | |----------------------------->| + | current_fee_credit | | + |<-----------------------------| | + | update_fulfill_htlc | | + | (id = 0) | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | | update_fulfill_htlc | + | | (id = 7) | + | |----------------------------->| + | | | +``` + +#### Fee credit purchase with funding timeout + +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. + +```txt + Alice Bob Carol + | | update_add_htlc | + | |<-----------------------------| + | will_add_htlc | | + |<-----------------------------| | + | | | + | | | + | | update_fail_htlc | + | |----------------------------->| + | add_fee_credit | | + |----------------------------->| | + | warning | | + |<-----------------------------| | + | current_fee_credit | | + |<-----------------------------| | + | | | +``` + +#### Fee credit purchase with funding timeout and HTLC part + +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. + +Another option is to wait for the remote `current_fee_credit` after sending +`add_fee_credit` and before sending `update_fulfill_htlc`. If the amount +was not added, they can then send `update_fail_htlc` instead. This may not +work in some edge cases with concurrent operations. + +```txt + Alice Bob Carol + | | update_add_htlc | + | | (id = 7) | + | |<-----------------------------| + | update_add_htlc | | + | (id = 3) | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | | update_add_htlc | + | | (id = 8) | + | |<-----------------------------| + | will_add_htlc | | + |<-----------------------------| | + | | | + | | | + | | update_fail_htlc | + | | (id = 8) | + | |----------------------------->| + | add_fee_credit | | + |----------------------------->| | + | warning | | + |<-----------------------------| | + | current_fee_credit | | + | (amount = 0 msat) | | + |<-----------------------------| | + | update_fulfill_htlc | | + | (id = 3) | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | | update_fulfill_htlc | + | | (id = 7) | + | |----------------------------->| + | | | +``` + +#### Fee credit purchase with disconnection + +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. 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. + +Another option is to keep track of the current fee credit, and wait to receive +`current_fee_credit` on reconnection before sending `update_fulfill_htlc`. +They can detect that the amount was not added and send `update_fail_htlc` +instead. This may not work in some edge cases with concurrent operations. + +```txt + Alice Bob Carol + | | update_add_htlc | + | | (id = 7) | + | |<-----------------------------| + | update_add_htlc | | + | (id = 3) | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | | update_add_htlc | + | | (id = 8) | + | |<-----------------------------| + | will_add_htlc | | + |<-----------------------------| | + | add_fee_credit | | + |------------------X | | + | update_fulfill_htlc | | + | (id = 3) | | + |-----------------------X | | + | | | + | | | + | | update_fail_htlc | + | | (id = 8) | + | |----------------------------->| + | channel_reestablish | | + |----------------------------->| | + | channel_reestablish | | + |<-----------------------------| | + | current_fee_credit | | + | (amount = 0 msat) | | + |<-----------------------------| | + | | | + | update_fulfill_htlc | | + | (id = 3) | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | | update_fulfill_htlc | + | | (id = 7) | + | |----------------------------->| + | | | +``` + +#### Funding using fee credit + +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. + +```txt + Alice Bob Carol + | current_fee_credit | | + | (600 msat) | | + |<-----------------------------| | + | | update_add_htlc | + | | (id = 7) | + | |<-----------------------------| + | update_add_htlc | | + | (id = 3) | | + | (amount = 500 msat) | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | | update_add_htlc | + | | (id = 8) | + | |<-----------------------------| + | will_add_htlc | | + | (amount = 750 msat) | | + |<-----------------------------| | + | stfu | | + |----------------------------->| | + | stfu | | + |<-----------------------------| | + | splice_init | | + | (from_future_htlc) | | + |----------------------------->| | + | splice_ack | | + | (will_fund) | | + | (fees = 1000 msat) | | + |<-----------------------------| | + | | | + | | | + | | | + | current_fee_credit | | + | (0 msat) | | + |<-----------------------------| | + | | | + | splice_locked | | + |----------------------------->| | + | splice_locked | | + |<-----------------------------| | + | | | + | | | + | | | + | update_add_htlc | | + | (id = 4) | | + | (amount = 350 msat) | | + | (funding_fee = 400 msat) | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | update_fulfill_htlc | | + | (id = 3) | | + |----------------------------->| | + | update_fulfill_htlc | | + | (id = 4) | | + |----------------------------->| update_fulfill_htlc | + | | (id = 7) | + | commit_sig |----------------------------->| + |----------------------------->| update_fulfill_htlc | + | revoke_and_ack | (id = 8) | + |<-----------------------------|----------------------------->| + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | | | +``` + +#### Funding using fee credit with timeout + +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. + +```txt + Alice Bob Carol + | | update_add_htlc | + | | (id = 7) | + | |<-----------------------------| + | update_add_htlc | | + | (id = 3) | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | | update_add_htlc | + | | (id = 8) | + | |<-----------------------------| + | will_add_htlc | | + |<-----------------------------| | + | stfu | | + |----------------------------->| | + | stfu | | + |<-----------------------------| | + | splice_init | | + | (from_future_htlc) | | + |----------------------------->| | + | splice_ack | | + | (will_fund) | | + |<-----------------------------| | + | | | + | | | + | | | + | | | + | | | + | warning | | + |<-----------------------------| update_fail_htlc | + | | (id = 8) | + | |----------------------------->| + | splice_locked | | + |----------------------------->| | + | splice_locked | | + |<-----------------------------| | + | | | + | | | + | | | + | update_fail_htlc | | + | (id = 3) | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | | update_fail_htlc | + | | (id = 7) | + | |----------------------------->| + | | | +``` + +#### Funding without enough fee credit + +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. + +```txt + Alice Bob Carol + | current_fee_credit | | + | (500 msat) | | + |<-----------------------------| | + | | update_add_htlc | + | | (id = 7) | + | |<-----------------------------| + | update_add_htlc | | + | (id = 3) | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | | update_add_htlc | + | | (id = 8) | + | |<-----------------------------| + | will_add_htlc | | + |<-----------------------------| | + | stfu | | + |----------------------------->| | + | stfu | | + |<-----------------------------| | + | splice_init | | + | (from_future_htlc) | | + |----------------------------->| | + | cancel_on_the_fly_funding | | + |<-----------------------------| | + | current_fee_credit | | + | (500 msat) | | + |<-----------------------------| | + | | | + | | | + | | | + | warning | | + |<-----------------------------| update_fail_htlc | + | | (id = 8) | + | |----------------------------->| + | | | + | | | + | | | + | update_fail_htlc | | + | (id = 3) | | + |----------------------------->| | + | commit_sig | | + |----------------------------->| | + | revoke_and_ack | | + |<-----------------------------| | + | commit_sig | | + |<-----------------------------| | + | revoke_and_ack | | + |----------------------------->| | + | | update_fail_htlc | + | | (id = 7) | + | |----------------------------->| + | | | +``` + +## Reference Implementations + +- eclair: +- lightning-kmp: