From 767b46fc1df2d53775050486b59af4bff8c27ea8 Mon Sep 17 00:00:00 2001 From: t-bast Date: Wed, 17 Jul 2024 09:58:27 +0200 Subject: [PATCH 1/3] Extensible liquidity ads rates Add the ability to advertise rates at which nodes wish to sell their liquidity. Buyers can then connect to sellers and request liquidity, at one of the advertised rates. This can be used when creating a dual-funded channel, where both participants contribute to the funding transaction, and one of them is paid for (some of) their contribution. This can also be used to splice additional liquidity into existing channels, when splicing is supported. We introduce an extensible `payment_type` field to control how the funding fees are paid. The only `payment_type` currently defined pays funding fees from the buyer's channel balance during the interactive-tx session, but it is easy to introduce different `payment_type`s (to pay the fees using HTLCs for example). We don't add any constraints to the commitment transactions. Sellers should keep the channel open for at least a month, but there is no way to guarantee that. The seller could immediately close the channel, or splice funds out. It is up to the buyer to then blacklist that seller. Credits to @niftynei for the original design. --- 01-messaging.md | 8 ++ 02-peer-protocol.md | 40 +++++++++ 07-routing-gossip.md | 180 ++++++++++++++++++++++++++++++++++++++ bolt07/liquidity-ads.json | 118 +++++++++++++++++++++++++ 4 files changed, 346 insertions(+) create mode 100644 bolt07/liquidity-ads.json diff --git a/01-messaging.md b/01-messaging.md index 67ca9e370..71e82d6b3 100644 --- a/01-messaging.md +++ b/01-messaging.md @@ -291,10 +291,18 @@ The `features` field MUST be padded to bytes with 0s. 1. type: 3 (`remote_addr`) 2. data: * [`...*byte`:`data`] + 1. type: 5 (`option_will_fund`) + 2. data: + * [`will_fund_rates`:`will_fund_rates`] The optional `networks` indicates the chains the node is interested in. + The optional `remote_addr` can be used to circumvent NAT issues. +`option_will_fund` allows nodes to announce their willingness to provide funding +to other nodes using one of the included funding rates, as described in the +[liquidity ads section](07-routing-gossip.md#liquidity-ads). + #### Requirements The sending node: diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 27b01fe04..225d68dae 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -1163,6 +1163,9 @@ This message initiates the v2 channel establishment workflow. 2. data: * [`...*byte`:`type`] 1. type: 2 (`require_confirmed_inputs`) + 1. type: 3 (`request_funding`) + 2. data: + * [`request_funds`:`request_funds`] Rationale and Requirements are the same as for [`open_channel`](#the-open_channel-message), with the following additions. @@ -1177,11 +1180,18 @@ The sending node: - MUST set `funding_feerate_perkw` to the feerate for this transaction - If it requires the receiving node to only use confirmed inputs: - MUST set `require_confirmed_inputs` + - If it wants the receiving node to contribute to the funding transaction + using `option_will_fund`: + - MUST send `request_funding` containing one of the funding rates and + `payment_type`s supported by the receiving node. + - MUST set `requested_sats` to the amount of sats it wants to pay for at + the advertised funding rate. The receiving node: - MAY fail the negotiation if: - the `locktime` is unacceptable - the `funding_feerate_perkw` is unacceptable + - `request_funds.funding_rate` does not match a rate it advertised. - MUST fail the negotiation if: - `require_confirmed_inputs` is set but it cannot provide confirmed inputs @@ -1250,6 +1260,9 @@ acceptance of the new channel. 2. data: * [`...*byte`:`type`] 1. type: 2 (`require_confirmed_inputs`) + 1. type: 3 (`provide_funding`) + 2. data: + * [`will_fund`:`will_fund`] Rationale and Requirements are the same as listed above, for [`accept_channel`](#the-accept_channel-message) with the following @@ -1262,10 +1275,29 @@ The accepting node: - MAY respond with a `funding_satoshis` value of zero. - If it requires the opening node to only use confirmed inputs: - MUST set `require_confirmed_inputs` + - If the `request_funding` TLV was sent in `open_channel2`: + - If it does not want to contribute funds or to be paid for its + funding contributions: + - SHOULD omit the `provide_funding` TLV. + - Otherwise, if it decides to be paid for its contributions: + - MUST include the `provide_funding` TLV. + - MUST set `funding_satoshis` to a value greater than `0`. + - MAY set `funding_satoshis` less or more than `requested_sats`. The receiving node: + - MAY fail the negotiation if: + - It sent `request_funding` and `provide_funding` is not set. + - It sent `request_funding` and `provide_funding` is set and: + - `funding_satoshis` is smaller than requested. - MUST fail the negotiation if: - `require_confirmed_inputs` is set but it cannot provide confirmed inputs + - `provide_funding` is set but `request_funding` was not sent in `open_channel2`. + - `provide_funding` is set and: + - `will_fund.funding_rate` does not match `request_funds.funding_rate`. + - `will_fund.funding_script` does not match the channel funding script. + - `will_fund.signature` is invalid. + - MUST pay fees for the `option_will_fund` amount using the `payment_type` selected, + as detailed in the [liquidity ads section](07-routing-gossip.md#liquidity-ads). #### Rationale @@ -1278,6 +1310,14 @@ Instead, the channel reserve is fixed at 1% of the total channel balance rounded down to the nearest whole satoshi or the `dust_limit_satoshis`, whichever is greater. +If the opener sent `request_funding` in their `open_channel2` message, the +accepter node may choose to contribute funds, but they don't have to. + +If the accepter node has run out of available funds, they should either fail +the negotiation or reply with a `funding_satoshis` set to `0` and omit the +`provide_funding` TLV, allowing the opener to decide whether they want to +proceed anyway or fail the negotiation. + ### Funding Composition Funding composition for channel establishment v2 makes use of the diff --git a/07-routing-gossip.md b/07-routing-gossip.md index 22353278c..1946a914b 100644 --- a/07-routing-gossip.md +++ b/07-routing-gossip.md @@ -32,6 +32,7 @@ To support channel and node discovery, three *gossip messages* are supported: * [HTLC Fees](#htlc-fees) * [Pruning the Network View](#pruning-the-network-view) * [Recommendations for Routing](#recommendations-for-routing) + * [Liquidity Ads](#liquidity-ads) * [References](#references) ## Definition of `short_channel_id` @@ -269,6 +270,13 @@ nodes not associated with an already known channel are ignored. * [`32*byte`:`alias`] * [`u16`:`addrlen`] * [`addrlen*byte`:`addresses`] + * [`node_announcement_tlvs`:`tlvs`] + +1. `tlv_stream`: `node_announcement_tlvs` +2. types: + 1. type: 1 (`option_will_fund`) + 2. data: + * [`will_fund_rates`:`will_fund_rates`] `timestamp` allows for the ordering of messages, in the case of multiple announcements. `rgb_color` and `alias` allow intelligence services to assign @@ -279,6 +287,10 @@ connections: it contains a series of `address descriptor`s for connecting to the node. The first byte describes the address type and is followed by the appropriate number of bytes for that type. +`option_will_fund` allows nodes to announce their willingness to provide funding +to other nodes using one of the included funding rates, as described in the +[liquidity ads section](#liquidity-ads). + The following `address descriptor` types are defined: * `1`: ipv4; data = `[4:ipv4_addr][2:port]` (length 6) @@ -322,6 +334,9 @@ The origin node: bits it sets. - SHOULD not announce a Tor v2 onion service. - MUST NOT announce more than one `type 5` DNS hostname. + - If it includes `option_will_fund`: + - MAY include multiple funding rates. + - SHOULD NOT include more than 10 funding rates. The receiving node: - if `node_id` is NOT a valid compressed public key: @@ -1107,6 +1122,171 @@ A->D's `update_add_htlc` message would be: And D->C's `update_add_htlc` would again be the same as B->C's direct payment above. +## Liquidity Ads + +Liquidity ads allow nodes to announce their willingness to provide funding to +other nodes for a fee. Sellers advertise various rates for the liquidity they +are selling. + +1. subtype: `funding_rate` +2. data: + * [`u32`:`min_funding_amount_sat`] + * [`u32`:`max_funding_amount_sat`] + * [`u16`:`funding_weight`] + * [`u16`:`funding_fee_basis`] + * [`u32`:`funding_fee_base_sat`] + +Sellers also define how the fees can be paid by listing the `payment_type`s +they support. + +1. `payment_type`: 0 (`from_channel_balance`) + +Payment types are encoded using the TLV format, using the `payment_type` for +the type field. + +Sellers advertize their rates and payment types using `will_fund_rates`. + +1. subtype: `will_fund_rates` +2. data: + * [`u16`:`funding_rates_count`] + * [`funding_rates_count*funding_rate`:`funding_rates`] + * [`u16`:`payment_types_len`] + * [`payment_types_len*byte`:`payment_types`] + +Buyers select a specific rate and a `payment_type` offered by the seller +and use `request_funds` to purchase that liquidity. + +1. subtype: `request_funds` +2. data: + * [`u64`:`requested_sats`] + * [`funding_rate`:`funding_rate`] + * [`payment_type`:`payment_type`] + +Sellers accept the purchase with `will_fund` containing a signature that +commits to the liquidity purchase parameters. + +1. subtype: `will_fund` +2. data: + * [`funding_rate`:`funding_rate`] + * [`u16`:`funding_script_len`] + * [`funding_script_len*byte`:`funding_script`] + * [`signature`:`signature`] + +### Requirements + +A node selling liquidity: + - MUST advertise its funding rates with `will_fund_rates`: + - MUST include a list of `funding_rate`s for the amounts it may provide. + - MUST include a `payment_types` bitfield: for each `payment_type` that + it supports, the bit at the position matching this type MUST be set. + - When receiving `request_funds`: + - If the `funding_rate` does not match a rate it offers: + - MUST reject the funding attempt. + - If the `payment_type` is not supported: + - MUST reject the funding attempt. + - Otherwise: + - MUST send `will_fund` with the received `funding_rate`, the funding + script and a signature covering those fields (see below). + - MUST keep the channel open for at least a month to honor the + liquidity purchase. + +A node buying liquidity: + - MUST ignore any unknown `payment_type` in `will_fund_rates.payment_types`. + - MUST create `request_funds` with a `funding_rate` from the `funding_rates` + and a `payment_type` from the `payment_types` bitfield. + - MUST encode `payment_type` using the TLV format. + +### Computing liquidity fees + +When `request_funds` and `will_fund` have been exchanged, the buyer agrees to +pay fees to the seller for the funding they provide to the channel based on +the proposed `funding_weight`, `funding_fee_basis` and `funding_fee_base_sat`. + +The funding fee has three components: + +* a fixed amount: `funding_fee_base_sat` +* a proportional amount based on the seller's `funding_amount`: + * `paid_funding_contribution = min(funding_amount, request_funds.requested_sats)` + * `funding_fee_proportional_sat = paid_funding_contribution * funding_fee_basis / 10_000` +* a contribution to the on-chain fees paid by the seller: + * `funding_fee_mining_sat = funding_weight * funding_feerate_perkw / 1000` + +The total fee is then: + + funding_fee_total = funding_fee_base_sat + funding_fee_proportional_sat + funding_fee_mining_sat + +The seller provides an ECDSA signature in `will_fund` using the private key +associated with their `node_id`. The data signed is: + + SHA256("liquidity_ads_purchase" || funding_rate || funding_script) + +We use a tagged hash to ensure that this signature cannot be used in a +different context. + +#### Requirements + +A node advertising a `funding_rate`: + - MUST set `min_funding_amount_sat` and `max_funding_amount_sat` to the + minimum and maximum amount it will contribute at this rate. + - MUST set `funding_fee_base_sat` to the base fee (in satoshi) it will charge. + - MUST set `funding_fee_basis` to the amount it will charge per contributed + satoshi (in basis points, ie 1/10_000). + - MUST set `funding_weight` to the transaction weight that will be charged. + It ensures that the funding node is refunded for some of the on-chain + fees it will pay to contribute the requested funds to a channel. + +### The `from_channel_balance` payment type + +The funding fee is taken from the buyer's transaction inputs and added to the +seller's channel balance during the funding flow, using the +[interactive-tx](./02-peer-protocol.md#interactive-transaction-construction) +protocol. The buyer must contribute enough funds to cover their channel +balance, the funding fee, and the on-chain fees for the weight of the funding +transaction they're responsible for. + +#### Example + +A node contributes `500_000 sats` to a channel and requests `1_000_000 sats` +from its peer, at a feerate of `2500 sat/kw`. The total weight of their inputs +and outputs in the funding transaction is 720. More details about transaction +weight can be found in the [interactive-tx section](02-peer-protocol.md#interactive-transaction-construction). + +The seller contributes `1_100_000 sats` with the following funding rate: + + funding_weight = 444 + funding_fee_base_sat = 233 sats + funding_fee_basis = 22 + +The funding fee is: + + funding_fee_base_sat = 233 sats + funding_fee_proportional_sat = min(1_000_000, 1_100_000) * 22 / 10_000 = 2200 sats + funding_fee_mining_sat = 444 * 2500 / 1000 = 1110 sats + funding_fee_total = 3543 sats + +The outputs to the peers in the commitment transaction will be + + to-buyer: 500_000 sats + to-seller: 1_103_543 sats + +The miner fee for the buyer will be `720 * 2500 / 1000 = 1800 sats`. + +Minimum funds that the buyer must contribute to the funding transaction: + + open_channel2.funding_satoshis: 500_000 sats + funding fee: 3_543 sats + miner fee: 1_800 sats + total required contribution: 505_343 sats + +Minimum funds that the seller must contribute to the funding transaction: + + accept_channel2.funding_satoshis: 1_100_000 sats + miner fee [1]: 1_110 sats + total required contribution: 1_101_110 sats + +[1] assumes `funding_weight = 444` is their total weight for this transaction. + +## References ![Creative Commons License](https://i.creativecommons.org/l/by/4.0/88x31.png "License CC-BY")
diff --git a/bolt07/liquidity-ads.json b/bolt07/liquidity-ads.json new file mode 100644 index 000000000..59299b1e9 --- /dev/null +++ b/bolt07/liquidity-ads.json @@ -0,0 +1,118 @@ +{ + "node_private_key": "57ac961f1b80ebfb610037bf9c96c6333699bde42257919a53974811c34649e3", + "node_announcement": { + "node_id": "03ca9b880627d2d4e3b33164f66946349f820d26aa9572fe0e525e534850cbd413", + "alias": "LN-liquidity", + "features": [], + "color": [ + 42, + 117, + 87 + ], + "addresses": [], + "timestamp": 1713171401, + "tlvStream": { + "option_will_fund": { + "funding_rates": [ + { + "min_funding_amount_sat": 100000, + "max_funding_amount_sat": 500000, + "funding_weight": 550, + "funding_fee_basis": 100, + "funding_fee_base_sat": 5000, + "encoded": "000186a0 0007a120 0226 0064 00001388" + }, + { + "min_funding_amount_sat": 500000, + "max_funding_amount_sat": 5000000, + "funding_weight": 1100, + "funding_fee_basis": 75, + "funding_fee_base_sat": 0, + "encoded": "0007a120 004c4b40 044c 004b 00000000" + } + ], + "payment_types": { + "supported": [ + "from_channel_balance" + ], + "encoded": "01" + } + } + }, + "signature": "a822c88c3807659ce1c74866f3346444d0fe6ceb25f86804b245af064f77d0a83b8457732d77386a3b10cf4c80a1811d02f34770eefbef9548ab3a3ce3d629df", + "encoded": "0101 a822c88c3807659ce1c74866f3346444d0fe6ceb25f86804b245af064f77d0a83b8457732d77386a3b10cf4c80a1811d02f34770eefbef9548ab3a3ce3d629df 0000 661cebc9 03ca9b880627d2d4e3b33164f66946349f820d26aa9572fe0e525e534850cbd413 2a7557 4c4e2d4c69717569646974790000000000000000000000000000000000000000 0000 01250002000186a00007a12002260064000013880007a120004c4b40044c004b00000000000101" + }, + "open_channel2": { + "chainHash": "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000", + "temporaryChannelId": "0100000000000000000000000000000000000000000000000000000000000000", + "fundingFeerate": 5000, + "commitmentFeerate": 4000, + "fundingAmount": 250000, + "dustLimit": 500, + "maxHtlcValueInFlightMsat": 50000, + "htlcMinimum": 15, + "toSelfDelay": 144, + "maxAcceptedHtlcs": 483, + "lockTime": 650000, + "fundingPubkey": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", + "revocationBasepoint": "024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766", + "paymentBasepoint": "02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337", + "delayedPaymentBasepoint": "03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b", + "htlcBasepoint": "0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7", + "firstPerCommitmentPoint": "03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a", + "secondPerCommitmentPoint": "02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f", + "channelFlags": { + "announceChannel": true + }, + "tlvStream": { + "request_funding": { + "requested_sats": 750000, + "funding_rate": { + "min_funding_amount_sat": 500000, + "max_funding_amount_sat": 5000000, + "funding_weight": 1100, + "funding_fee_basis": 75, + "funding_fee_base_sat": 0 + }, + "payment_type": { + "type": "from_channel_balance", + "encoded": "0000" + }, + "encoded": "03 1a 00000000000b71b0 0007a120004c4b40044c004b00000000 0000" + } + }, + "encoded": "0040 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 0100000000000000000000000000000000000000000000000000000000000000 00001388 00000fa0 000000000003d090 00000000000001f4 000000000000c350 000000000000000f 0090 01e3 0009eb10 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 01 031a00000000000b71b00007a120004c4b40044c004b000000000000" + }, + "accept_channel2": { + "temporaryChannelId": "0100000000000000000000000000000000000000000000000000000000000000", + "fundingAmount": 700000, + "dustLimit": 473, + "maxHtlcValueInFlightMsat": 100000000, + "htlcMinimum": 1, + "minimumDepth": 6, + "toSelfDelay": 144, + "maxAcceptedHtlcs": 50, + "fundingPubkey": "031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f", + "revocationBasepoint": "024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766", + "paymentBasepoint": "02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337", + "delayedPaymentBasepoint": "03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b", + "htlcBasepoint": "0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7", + "firstPerCommitmentPoint": "03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a", + "secondPerCommitmentPoint": "02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f", + "tlvStream": { + "provide_funding": { + "funding_rate": { + "min_funding_amount_sat": 500000, + "max_funding_amount_sat": 5000000, + "funding_weight": 1100, + "funding_fee_basis": 75, + "funding_fee_base_sat": 0 + }, + "funding_script": "00202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103c", + "signature": "35962783e077e3c5214ba829752be2a3994a7c5e0e9d735ef5a9dab3ce1d6dda6282c3252b20af52e58c33c0e164167fd59e19114a8a8f9eb76b33008205dcb6", + "encoded": "03 74 0007a120004c4b40044c004b00000000 002200202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103c 35962783e077e3c5214ba829752be2a3994a7c5e0e9d735ef5a9dab3ce1d6dda6282c3252b20af52e58c33c0e164167fd59e19114a8a8f9eb76b33008205dcb6" + } + }, + "encoded": "0041 0100000000000000000000000000000000000000000000000000000000000000 00000000000aae60 00000000000001d9 0000000005f5e100 0000000000000001 00000006 0090 0032 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 03740007a120004c4b40044c004b00000000002200202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103c35962783e077e3c5214ba829752be2a3994a7c5e0e9d735ef5a9dab3ce1d6dda6282c3252b20af52e58c33c0e164167fd59e19114a8a8f9eb76b33008205dcb6" + } +} \ No newline at end of file From 69aca1424023e3b164d374df9bcb6039d98d5483 Mon Sep 17 00:00:00 2001 From: t-bast Date: Tue, 3 Sep 2024 15:07:18 +0200 Subject: [PATCH 2/3] Add `channel_creation_fee_sat` to funding rate 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 some `channel_creation_fee_sat` to their liquidity ads to cover some of that future cost. --- 07-routing-gossip.md | 28 ++++++++++++++++++++++------ bolt07/liquidity-ads.json | 26 +++++++++++++++----------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/07-routing-gossip.md b/07-routing-gossip.md index 1946a914b..8b58e6a13 100644 --- a/07-routing-gossip.md +++ b/07-routing-gossip.md @@ -1135,6 +1135,7 @@ are selling. * [`u16`:`funding_weight`] * [`u16`:`funding_fee_basis`] * [`u32`:`funding_fee_base_sat`] + * [`u32`:`channel_creation_fee_sat`] Sellers also define how the fees can be paid by listing the `payment_type`s they support. @@ -1202,16 +1203,27 @@ When `request_funds` and `will_fund` have been exchanged, the buyer agrees to pay fees to the seller for the funding they provide to the channel based on the proposed `funding_weight`, `funding_fee_basis` and `funding_fee_base_sat`. +If the buyer is opening a new channel, an additional `channel_creation_fee_sat` +is applied. This can be used to hedge some of the future cost of closing that +channel, which doesn't apply when additional liquidity is purchased on an +existing channel (since the creation fee has already been paid). + The funding fee has three components: -* a fixed amount: `funding_fee_base_sat` +* a fixed amount: + * `funding_fee_base_sat` if liquidity is purchased on an existing channel + * `funding_fee_base_sat + channel_creation_fee_sat` when opening a channel * a proportional amount based on the seller's `funding_amount`: * `paid_funding_contribution = min(funding_amount, request_funds.requested_sats)` * `funding_fee_proportional_sat = paid_funding_contribution * funding_fee_basis / 10_000` * a contribution to the on-chain fees paid by the seller: * `funding_fee_mining_sat = funding_weight * funding_feerate_perkw / 1000` -The total fee is then: +The total fee for a channel creation is then: + + funding_fee_total = funding_fee_base_sat + channel_creation_fee_sat + funding_fee_proportional_sat + funding_fee_mining_sat + +The total fee for buying liquidity on an existing channel is: funding_fee_total = funding_fee_base_sat + funding_fee_proportional_sat + funding_fee_mining_sat @@ -1229,6 +1241,8 @@ A node advertising a `funding_rate`: - MUST set `min_funding_amount_sat` and `max_funding_amount_sat` to the minimum and maximum amount it will contribute at this rate. - MUST set `funding_fee_base_sat` to the base fee (in satoshi) it will charge. + - MUST set `channel_creation_fee_sat` to the additional fee it will charge for + channel creation. - MUST set `funding_fee_basis` to the amount it will charge per contributed satoshi (in basis points, ie 1/10_000). - MUST set `funding_weight` to the transaction weight that will be charged. @@ -1255,28 +1269,30 @@ The seller contributes `1_100_000 sats` with the following funding rate: funding_weight = 444 funding_fee_base_sat = 233 sats + channel_creation_fee_sat = 500 sats funding_fee_basis = 22 The funding fee is: funding_fee_base_sat = 233 sats + channel_creation_fee_sat = 500 sats funding_fee_proportional_sat = min(1_000_000, 1_100_000) * 22 / 10_000 = 2200 sats funding_fee_mining_sat = 444 * 2500 / 1000 = 1110 sats - funding_fee_total = 3543 sats + funding_fee_total = 4043 sats The outputs to the peers in the commitment transaction will be to-buyer: 500_000 sats - to-seller: 1_103_543 sats + to-seller: 1_104_043 sats The miner fee for the buyer will be `720 * 2500 / 1000 = 1800 sats`. Minimum funds that the buyer must contribute to the funding transaction: open_channel2.funding_satoshis: 500_000 sats - funding fee: 3_543 sats + funding fee: 4_043 sats miner fee: 1_800 sats - total required contribution: 505_343 sats + total required contribution: 505_843 sats Minimum funds that the seller must contribute to the funding transaction: diff --git a/bolt07/liquidity-ads.json b/bolt07/liquidity-ads.json index 59299b1e9..710a88585 100644 --- a/bolt07/liquidity-ads.json +++ b/bolt07/liquidity-ads.json @@ -20,7 +20,8 @@ "funding_weight": 550, "funding_fee_basis": 100, "funding_fee_base_sat": 5000, - "encoded": "000186a0 0007a120 0226 0064 00001388" + "channel_creation_fee_sat": 1000, + "encoded": "000186a0 0007a120 0226 0064 00001388 000003e8" }, { "min_funding_amount_sat": 500000, @@ -28,7 +29,8 @@ "funding_weight": 1100, "funding_fee_basis": 75, "funding_fee_base_sat": 0, - "encoded": "0007a120 004c4b40 044c 004b 00000000" + "channel_creation_fee_sat": 1500, + "encoded": "0007a120 004c4b40 044c 004b 00000000 000005dc" } ], "payment_types": { @@ -39,8 +41,8 @@ } } }, - "signature": "a822c88c3807659ce1c74866f3346444d0fe6ceb25f86804b245af064f77d0a83b8457732d77386a3b10cf4c80a1811d02f34770eefbef9548ab3a3ce3d629df", - "encoded": "0101 a822c88c3807659ce1c74866f3346444d0fe6ceb25f86804b245af064f77d0a83b8457732d77386a3b10cf4c80a1811d02f34770eefbef9548ab3a3ce3d629df 0000 661cebc9 03ca9b880627d2d4e3b33164f66946349f820d26aa9572fe0e525e534850cbd413 2a7557 4c4e2d4c69717569646974790000000000000000000000000000000000000000 0000 01250002000186a00007a12002260064000013880007a120004c4b40044c004b00000000000101" + "signature": "22ec2e2a6e02f54d949e332cbce571d123ae20dda98d0340ac7e64f60f11d413659a2a9645adea8f886bb5dd40cc589bd3e0f4f8b2ab333d323b74b7762b4ca1", + "encoded": "0101 22ec2e2a6e02f54d949e332cbce571d123ae20dda98d0340ac7e64f60f11d413659a2a9645adea8f886bb5dd40cc589bd3e0f4f8b2ab333d323b74b7762b4ca1 0000 661cebc9 03ca9b880627d2d4e3b33164f66946349f820d26aa9572fe0e525e534850cbd413 2a7557 4c4e2d4c69717569646974790000000000000000000000000000000000000000 0000 012d0002000186a00007a1200226006400001388000003e80007a120004c4b40044c004b00000000000005dc000101" }, "open_channel2": { "chainHash": "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000", @@ -72,16 +74,17 @@ "max_funding_amount_sat": 5000000, "funding_weight": 1100, "funding_fee_basis": 75, - "funding_fee_base_sat": 0 + "funding_fee_base_sat": 0, + "channel_creation_fee_sat": 1500 }, "payment_type": { "type": "from_channel_balance", "encoded": "0000" }, - "encoded": "03 1a 00000000000b71b0 0007a120004c4b40044c004b00000000 0000" + "encoded": "03 1e 00000000000b71b0 0007a120004c4b40044c004b00000000000005dc 0000" } }, - "encoded": "0040 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 0100000000000000000000000000000000000000000000000000000000000000 00001388 00000fa0 000000000003d090 00000000000001f4 000000000000c350 000000000000000f 0090 01e3 0009eb10 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 01 031a00000000000b71b00007a120004c4b40044c004b000000000000" + "encoded": "0040 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 0100000000000000000000000000000000000000000000000000000000000000 00001388 00000fa0 000000000003d090 00000000000001f4 000000000000c350 000000000000000f 0090 01e3 0009eb10 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 01 031e00000000000b71b00007a120004c4b40044c004b00000000000005dc0000" }, "accept_channel2": { "temporaryChannelId": "0100000000000000000000000000000000000000000000000000000000000000", @@ -106,13 +109,14 @@ "max_funding_amount_sat": 5000000, "funding_weight": 1100, "funding_fee_basis": 75, - "funding_fee_base_sat": 0 + "funding_fee_base_sat": 0, + "channel_creation_fee_sat": 1500 }, "funding_script": "00202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103c", - "signature": "35962783e077e3c5214ba829752be2a3994a7c5e0e9d735ef5a9dab3ce1d6dda6282c3252b20af52e58c33c0e164167fd59e19114a8a8f9eb76b33008205dcb6", - "encoded": "03 74 0007a120004c4b40044c004b00000000 002200202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103c 35962783e077e3c5214ba829752be2a3994a7c5e0e9d735ef5a9dab3ce1d6dda6282c3252b20af52e58c33c0e164167fd59e19114a8a8f9eb76b33008205dcb6" + "signature": "c57cf393f6bd534472ec08cbfbbc7268501b32f563a21cdf02a99127c4f25168249acd6509f96b2e93843c3b838ee4808c75d0a15ff71ba886fda980b8ca954f", + "encoded": "03 78 0007a120004c4b40044c004b00000000000005dc 002200202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103c c57cf393f6bd534472ec08cbfbbc7268501b32f563a21cdf02a99127c4f25168249acd6509f96b2e93843c3b838ee4808c75d0a15ff71ba886fda980b8ca954f" } }, - "encoded": "0041 0100000000000000000000000000000000000000000000000000000000000000 00000000000aae60 00000000000001d9 0000000005f5e100 0000000000000001 00000006 0090 0032 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 03740007a120004c4b40044c004b00000000002200202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103c35962783e077e3c5214ba829752be2a3994a7c5e0e9d735ef5a9dab3ce1d6dda6282c3252b20af52e58c33c0e164167fd59e19114a8a8f9eb76b33008205dcb6" + "encoded": "0041 0100000000000000000000000000000000000000000000000000000000000000 00000000000aae60 00000000000001d9 0000000005f5e100 0000000000000001 00000006 0090 0032 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 03780007a120004c4b40044c004b00000000000005dc002200202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103cc57cf393f6bd534472ec08cbfbbc7268501b32f563a21cdf02a99127c4f25168249acd6509f96b2e93843c3b838ee4808c75d0a15ff71ba886fda980b8ca954f" } } \ No newline at end of file From 910c07091ce30feddcf84f9cc7cd217bc05499ca Mon Sep 17 00:00:00 2001 From: t-bast Date: Thu, 10 Oct 2024 09:29:51 +0200 Subject: [PATCH 3/3] Add liquidity ads TLVs to RBF messages Every RBF attempts provided the opportunity to modify the liquidity purchase: we thus must explicitly state whether we're purchasing liquidity in `tx_init_rbf`. We also update the TLV tags to prevent a conflict with the released version of `cln` which already uses those TLVs with an experimental format. This will make the migration to the new TLVs easier for them without disrupting existing users. --- 02-peer-protocol.md | 22 ++++++++++++++++++++-- 07-routing-gossip.md | 2 +- bolt07/liquidity-ads.json | 12 ++++++------ 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 225d68dae..1bd621166 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -453,6 +453,9 @@ completed. 2. data: * [`s64`:`satoshis`] 1. type: 2 (`require_confirmed_inputs`) + 1. type: 5 (`request_funding`) + 2. data: + * [`request_funds`:`request_funds`] #### Requirements @@ -463,6 +466,12 @@ The sender: - MUST set `funding_output_contribution` - If it requires the receiving node to only use confirmed inputs: - MUST set `require_confirmed_inputs` + - If it wants the receiving node to contribute to the funding transaction + using `option_will_fund`: + - MUST send `request_funding` containing one of the funding rates and + `payment_type`s supported by the receiving node. + - If the previous transaction included `request_funding`: + - SHOULD include `request_funding`. The recipient: - MUST respond either with `tx_abort` or with `tx_ack_rbf` @@ -472,6 +481,8 @@ The recipient: - MAY send `tx_abort` for any reason - MUST fail the negotiation if: - `require_confirmed_inputs` is set but it cannot provide confirmed inputs + - `request_funding` was included in the previous transaction but is not + included in `tx_init_rbf`. #### Rationale @@ -505,6 +516,9 @@ not contributing to the funding output. 2. data: * [`s64`:`satoshis`] 1. type: 2 (`require_confirmed_inputs`) + 1. type: 5 (`provide_funding`) + 2. data: + * [`will_fund`:`will_fund`] #### Requirements @@ -513,12 +527,16 @@ The sender: - MUST set `funding_output_contribution` - If it requires the receiving node to only use confirmed inputs: - MUST set `require_confirmed_inputs` + - If the `request_funding` TLV was sent in `tx_init_rbf`: + - MUST apply the same requirements as `accept_channel2` The recipient: - MUST respond with `tx_abort` or with a `tx_add_input` message, restarting the interactive tx collaboration protocol. - MUST fail the negotiation if: - `require_confirmed_inputs` is set but it cannot provide confirmed inputs + - MAY fail the negotiation if `provide_funding` does not match what it + expects, similar to the requirements for `accept_channel2`. #### Rationale @@ -1163,7 +1181,7 @@ This message initiates the v2 channel establishment workflow. 2. data: * [`...*byte`:`type`] 1. type: 2 (`require_confirmed_inputs`) - 1. type: 3 (`request_funding`) + 1. type: 5 (`request_funding`) 2. data: * [`request_funds`:`request_funds`] @@ -1260,7 +1278,7 @@ acceptance of the new channel. 2. data: * [`...*byte`:`type`] 1. type: 2 (`require_confirmed_inputs`) - 1. type: 3 (`provide_funding`) + 1. type: 5 (`provide_funding`) 2. data: * [`will_fund`:`will_fund`] diff --git a/07-routing-gossip.md b/07-routing-gossip.md index 8b58e6a13..991360ea7 100644 --- a/07-routing-gossip.md +++ b/07-routing-gossip.md @@ -274,7 +274,7 @@ nodes not associated with an already known channel are ignored. 1. `tlv_stream`: `node_announcement_tlvs` 2. types: - 1. type: 1 (`option_will_fund`) + 1. type: 5 (`option_will_fund`) 2. data: * [`will_fund_rates`:`will_fund_rates`] diff --git a/bolt07/liquidity-ads.json b/bolt07/liquidity-ads.json index 710a88585..742777e94 100644 --- a/bolt07/liquidity-ads.json +++ b/bolt07/liquidity-ads.json @@ -41,8 +41,8 @@ } } }, - "signature": "22ec2e2a6e02f54d949e332cbce571d123ae20dda98d0340ac7e64f60f11d413659a2a9645adea8f886bb5dd40cc589bd3e0f4f8b2ab333d323b74b7762b4ca1", - "encoded": "0101 22ec2e2a6e02f54d949e332cbce571d123ae20dda98d0340ac7e64f60f11d413659a2a9645adea8f886bb5dd40cc589bd3e0f4f8b2ab333d323b74b7762b4ca1 0000 661cebc9 03ca9b880627d2d4e3b33164f66946349f820d26aa9572fe0e525e534850cbd413 2a7557 4c4e2d4c69717569646974790000000000000000000000000000000000000000 0000 012d0002000186a00007a1200226006400001388000003e80007a120004c4b40044c004b00000000000005dc000101" + "signature": "2e6a9b7017d0c6d8c823f6aa5fcaaea266ea5c7ebc88345efc3ec227e71dee38148371cef4ffaf6d37318de42ded99203e89aaf9f697ad211915dc83dc9cfa63", + "encoded": "0101 2e6a9b7017d0c6d8c823f6aa5fcaaea266ea5c7ebc88345efc3ec227e71dee38148371cef4ffaf6d37318de42ded99203e89aaf9f697ad211915dc83dc9cfa63 0000 661cebc9 03ca9b880627d2d4e3b33164f66946349f820d26aa9572fe0e525e534850cbd413 2a7557 4c4e2d4c69717569646974790000000000000000000000000000000000000000 0000 052d0002000186a00007a1200226006400001388000003e80007a120004c4b40044c004b00000000000005dc000101" }, "open_channel2": { "chainHash": "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000", @@ -81,10 +81,10 @@ "type": "from_channel_balance", "encoded": "0000" }, - "encoded": "03 1e 00000000000b71b0 0007a120004c4b40044c004b00000000000005dc 0000" + "encoded": "05 1e 00000000000b71b0 0007a120004c4b40044c004b00000000000005dc 0000" } }, - "encoded": "0040 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 0100000000000000000000000000000000000000000000000000000000000000 00001388 00000fa0 000000000003d090 00000000000001f4 000000000000c350 000000000000000f 0090 01e3 0009eb10 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 01 031e00000000000b71b00007a120004c4b40044c004b00000000000005dc0000" + "encoded": "0040 6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000 0100000000000000000000000000000000000000000000000000000000000000 00001388 00000fa0 000000000003d090 00000000000001f4 000000000000c350 000000000000000f 0090 01e3 0009eb10 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 01 051e00000000000b71b00007a120004c4b40044c004b00000000000005dc0000" }, "accept_channel2": { "temporaryChannelId": "0100000000000000000000000000000000000000000000000000000000000000", @@ -114,9 +114,9 @@ }, "funding_script": "00202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103c", "signature": "c57cf393f6bd534472ec08cbfbbc7268501b32f563a21cdf02a99127c4f25168249acd6509f96b2e93843c3b838ee4808c75d0a15ff71ba886fda980b8ca954f", - "encoded": "03 78 0007a120004c4b40044c004b00000000000005dc 002200202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103c c57cf393f6bd534472ec08cbfbbc7268501b32f563a21cdf02a99127c4f25168249acd6509f96b2e93843c3b838ee4808c75d0a15ff71ba886fda980b8ca954f" + "encoded": "05 78 0007a120004c4b40044c004b00000000000005dc 002200202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103c c57cf393f6bd534472ec08cbfbbc7268501b32f563a21cdf02a99127c4f25168249acd6509f96b2e93843c3b838ee4808c75d0a15ff71ba886fda980b8ca954f" } }, - "encoded": "0041 0100000000000000000000000000000000000000000000000000000000000000 00000000000aae60 00000000000001d9 0000000005f5e100 0000000000000001 00000006 0090 0032 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 03780007a120004c4b40044c004b00000000000005dc002200202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103cc57cf393f6bd534472ec08cbfbbc7268501b32f563a21cdf02a99127c4f25168249acd6509f96b2e93843c3b838ee4808c75d0a15ff71ba886fda980b8ca954f" + "encoded": "0041 0100000000000000000000000000000000000000000000000000000000000000 00000000000aae60 00000000000001d9 0000000005f5e100 0000000000000001 00000006 0090 0032 031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f 024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d0766 02531fe6068134503d2723133227c867ac8fa6c83c537e9a44c3c5bdbdcb1fe337 03462779ad4aad39514614751a71085f2f10e1c7a593e4e030efb5b8721ce55b0b 0362c0a046dacce86ddd0343c6d3c7c79c2208ba0d9c9cf24a6d046d21d21f90f7 03f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a 02989c0b76cb563971fdc9bef31ec06c3560f3249d6ee9e5d83c57625596e05f6f 05780007a120004c4b40044c004b00000000000005dc002200202ec38203f4cf37a3b377d9a55c7ae0153c643046dbdbe2ffccfb11b74420103cc57cf393f6bd534472ec08cbfbbc7268501b32f563a21cdf02a99127c4f25168249acd6509f96b2e93843c3b838ee4808c75d0a15ff71ba886fda980b8ca954f" } } \ No newline at end of file