From 2b4193735668b07ed9b7dd5e8a70c80ca39280a8 Mon Sep 17 00:00:00 2001 From: t-bast Date: Tue, 24 Oct 2023 12:41:33 +0200 Subject: [PATCH 1/3] bLIP-0030: zero-reserve channels Nodes can opt-in to remove the channel reserve requirements, which makes better use of their channel liquidity. --- README.md | 1 + blip-0002.md | 21 +++++++- blip-0030.md | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 blip-0030.md diff --git a/README.md b/README.md index bba6b55..68d6531 100644 --- a/README.md +++ b/README.md @@ -25,3 +25,4 @@ For more detail on the process, please read [bLIP-0001](./blip-0001.md) and | [10](./blip-0010.md) | Podcasting 2.0 | Satoshis Stream | Active | | [11](./blip-0011.md) | NameDesc | Hampus Sjöberg | Active | | [17](./blip-0017.md) | Hosted Channels | Anton Kumaigorodskiy | Active | +| [xx](./blip-0030.md) | Zero-reserve channels | Bastien Teinturier | Active | diff --git a/blip-0002.md b/blip-0002.md index 5efcc35..530de7f 100644 --- a/blip-0002.md +++ b/blip-0002.md @@ -32,8 +32,9 @@ network split. * [Messages](#messages) * [TLV fields in BOLT messages](#tlv-fields-in-bolt-messages) * [`init`](#init) + * [`open_channel2`](#open_channel2) + * [`accept_channel2`](#accept_channel2) * [`ping`](#ping) - * [`update_add_htlc`](#update_add_htlc) ### Feature bits @@ -48,6 +49,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 | `zero_reserve` | This node may accept zero-reserve channels | IN | | [bLIP 30](./blip-0030.md) | ### Messages @@ -92,6 +94,22 @@ The following table contains extension tlv fields for the `init` message: |-------|-----------------------------|--------------------------------| | 65536 | `tlv_field_name` | Link to the corresponding bLIP | +#### `open_channel2` + +The following table contains extension tlv fields for the `open_channel2` message: + +| Type | Name | Link | +|-------|-----------------------------|---------------------------| +| 32768 | `zero_reserve` | [bLIP 30](./blip-0030.md) | + +#### `accept_channel2` + +The following table contains extension tlv fields for the `accept_channel2` message: + +| Type | Name | Link | +|-------|-----------------------------|---------------------------| +| 32768 | `zero_reserve` | [bLIP 30](./blip-0030.md) | + #### `payment_onion_payload` The following table contains extension tlv fields for the `payment_onion_payload` message: @@ -101,7 +119,6 @@ The following table contains extension tlv fields for the `payment_onion_payload | 7629169 | `podcasting_2_0` | [bLIP 10](./blip-0010.md) | | 5482373484 | `keysend_preimage` | [bLIP 3](./blip-0003.md) | - #### `ping` The following table contains extension tlv fields for the `ping` message: diff --git a/blip-0030.md b/blip-0030.md new file mode 100644 index 0000000..4ed293a --- /dev/null +++ b/blip-0030.md @@ -0,0 +1,132 @@ +``` +bLIP: 30 +Title: Zero-reserve channels +Status: Active +Author: Bastien Teinturier +Created: 2023-10-24 +License: CC0 +``` + +## Abstract + +Standard lightning channels require nodes to lock some of their channel funds +into a channel reserve, which cannot be used for payments made on that channel. +This guarantees that both nodes always have an output in the commitment +transaction, which they will lose if they publish a revoked commitment. + +While this requirement is generally useful, it creates some inefficiencies +since that liquidity can't be used to relay payments, and provides a bad user +experience. In some settings, we may want to remove that channel reserve and +allow nodes to use all of their channel funds. + +## Copyright + +This bLIP is licensed under the CC0 license. + +## Specification + +### TLV extensions + +Additional TLV fields for the `open_channel2` message: + +1. `tlv_stream`: `open_channel2_tlvs` +2. types: + 1. type: 32768 (`zero_reserve`) + 2. data: + * [`byte`:`use_zero_reserve`] + +Additional TLV fields for the `accept_channel2` message: + +1. `tlv_stream`: `accept_channel2_tlvs` +2. types: + 1. type: 32768 (`zero_reserve`) + 2. data: + * [`byte`:`use_zero_reserve`] + +### Requirements + +A node that wants to support zero-reserve channels: + +* MUST set the `zero_reserve` feature bit + +When sending `open_channel`: + +* If `zero_reserve` was negotiated: + * MAY set `channel_reserve_satoshis` to `0` + +When receiving `open_channel`: + +* If `channel_reserve_satoshis` is set to `0`: + * If it wants to use `zero_reserve`: + * MUST set `channel_reserve_satoshis` to `0` in `accept_channel` + * Otherwise: + * MUST send an `error` and forget the channel + +When sending `open_channel2`: + +* If `zero_reserve` was negotiated: + * MAY set the `zero_reserve` TLV field to `1` + +When receiving `open_channel2`: + +* If `zero_reserve` is set to `1`: + * If it wants to use `zero_reserve`: + * MUST set the `zero_reserve` TLV field to `1` in `accept_channel2` + * Otherwise: + * MUST send an `error` and forget the channel + +When sending or receiving `update_add_htlc`: + +* If `zero_reserve` has been negotiated: + * MUST ignore any channel reserve standard requirement + +If the channel is not public, both nodes: + +* When the funding transaction confirms: + * MUST send a `channel_update` using the final `short_channel_id` + +### Rationale + +The use of zero-reserve is symmetrical: it is either offered to both nodes or +unused. + +### Fraud proofs + +If one of the nodes publishes a revoked commitment, the other node can create +a fraud proof that shows which node tried to cheat. This proof may be shared +publicly to harm the cheating node's reputation. + +That proof contains: + +1. the revoked commitment transaction +2. a proof of knowledge of the revocation secret +3. a proof of knowledge of the private key associated to the main output of the + honest participant +4. if the channel is public, its `channel_announcement` +5. if the channel is not public, a `channel_update` from the malicious peer + that uses the final `short_channel_id` + +The second and third items prove the identity of the honest user in that +channel, while the last two items tie the identity of the malicious user to +its public `node_id`. + +## Motivation + +In some cases, there may be some trust between nodes that the other node won't +try to publish a revoked commitment: when that is the case, it is wasteful to +enforce a channel reserve. + +In other cases, different incentives may be sufficient to remove the need for +channel reserves. + +A mobile wallet using a service provider is a good candidate for removing the +reserve requirements. The wallet user is regularly paying fees to the service +provider: this incentivizes the service provider to offer zero-reserve, which +provides a better user experience. The service provider isn't taking any risk +here, as they should always be online and able to punish revoked transactions. +It also makes sense for the wallet user to offer zero-reserve to the service +provider: even on a mobile wallet, users should be able to react to revoked +transactions. If the service provider publishes a revoked transaction, the +wallet user can additionnally create a public proof that the service provider +tried to cheat: this harms the service provider's reputation, which is another +incentive for them to avoid cheating. From 95f7ad10acbb492e2dfe04b5cd06692c0347b9d5 Mon Sep 17 00:00:00 2001 From: t-bast Date: Wed, 25 Oct 2023 09:18:51 +0200 Subject: [PATCH 2/3] Use empty TLV flag Similar to what is done for `require_confirmed_inputs`. We add a requirement for the receiver of `accept_channel` and `accept_channel2`. --- blip-0030.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/blip-0030.md b/blip-0030.md index 4ed293a..b2acfe0 100644 --- a/blip-0030.md +++ b/blip-0030.md @@ -32,16 +32,12 @@ Additional TLV fields for the `open_channel2` message: 1. `tlv_stream`: `open_channel2_tlvs` 2. types: 1. type: 32768 (`zero_reserve`) - 2. data: - * [`byte`:`use_zero_reserve`] Additional TLV fields for the `accept_channel2` message: 1. `tlv_stream`: `accept_channel2_tlvs` 2. types: 1. type: 32768 (`zero_reserve`) - 2. data: - * [`byte`:`use_zero_reserve`] ### Requirements @@ -51,7 +47,7 @@ A node that wants to support zero-reserve channels: When sending `open_channel`: -* If `zero_reserve` was negotiated: +* If the `zero_reserve` feature was negotiated: * MAY set `channel_reserve_satoshis` to `0` When receiving `open_channel`: @@ -62,19 +58,31 @@ When receiving `open_channel`: * Otherwise: * MUST send an `error` and forget the channel +When receiving `accept_channel`: + +* If `channel_reserve_satoshis` was set to `0` in `open_channel`, and it is + not set to `0` in `accept_channel`: + * MUST send an `error` and forget the channel + When sending `open_channel2`: -* If `zero_reserve` was negotiated: - * MAY set the `zero_reserve` TLV field to `1` +* If the `zero_reserve` feature was negotiated: + * MAY set the `zero_reserve` TLV field When receiving `open_channel2`: -* If `zero_reserve` is set to `1`: +* If the `zero_reserve` TLV field is set: * If it wants to use `zero_reserve`: - * MUST set the `zero_reserve` TLV field to `1` in `accept_channel2` + * MUST set the `zero_reserve` TLV field in `accept_channel2` * Otherwise: * MUST send an `error` and forget the channel +When receiving `accept_channel2`: + +* If `zero_reserve` was set in `open_channel2`, and it is not set in + `accept_channel2`: + * MUST send an `error` and forget the channel + When sending or receiving `update_add_htlc`: * If `zero_reserve` has been negotiated: From a912d64c2565623b800bea9201fcaac32f94767c Mon Sep 17 00:00:00 2001 From: t-bast Date: Wed, 22 Nov 2023 17:13:46 +0100 Subject: [PATCH 3/3] Prevent empty commitment transactions As suggested by @JssDWt --- blip-0030.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/blip-0030.md b/blip-0030.md index b2acfe0..913ce81 100644 --- a/blip-0030.md +++ b/blip-0030.md @@ -83,10 +83,19 @@ When receiving `accept_channel2`: `accept_channel2`: * MUST send an `error` and forget the channel -When sending or receiving `update_add_htlc`: +When sending `update_add_htlc`: * If `zero_reserve` has been negotiated: * MUST ignore any channel reserve standard requirement + * If the resulting commitment transaction would have no outputs: + * MUST NOT send `update_add_htlc` + +When receiving `update_add_htlc`: + +* If `zero_reserve` has been negotiated: + * MUST ignore any channel reserve standard requirement + * If the resulting commitment transaction would have no outputs: + * MUST send an `error` and fail the channel If the channel is not public, both nodes: @@ -98,6 +107,14 @@ If the channel is not public, both nodes: The use of zero-reserve is symmetrical: it is either offered to both nodes or unused. +In theory, the channel could be in a state where the commitment transaction has +no outputs, if all of the channel liquidity is allocated to pending dust HTLCs. +This state wouldn't make sense: all of the channel value would be burned to +miner fees. We make sure we never get into this state. In practice though, this +should never happen since nodes set `max_dust_htlc_exposure_msat` to ensure +that dust HTLCs don't grow unbounded and set `max_htlc_value_in_flight_msat` to +restrict their exposure to pending HTLCs. + ### Fraud proofs If one of the nodes publishes a revoked commitment, the other node can create