From 439c635abb023c675592c5d9c3383a689d09541d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 9 May 2021 14:47:21 +0930 Subject: [PATCH 01/11] BOLT 2: quiescence protocol. Signed-off-by: Rusty Russell --- .aspell.en.pws | 3 +++ 02-peer-protocol.md | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/.aspell.en.pws b/.aspell.en.pws index c9e3a0206..7f3e47e42 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -386,3 +386,6 @@ csv CHECKSIGVERIFY IFDUP sats +quiesce +quiescing +SomeThing diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 974e51e9a..e592e0a33 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -13,6 +13,7 @@ operation, and closing. * [The `funding_created` Message](#the-funding_created-message) * [The `funding_signed` Message](#the-funding_signed-message) * [The `funding_locked` Message](#the-funding_locked-message) + * [Channel Quiescence](#channel-quiescence) * [Channel Close](#channel-close) * [Closing Initiation: `shutdown`](#closing-initiation-shutdown) * [Closing Negotiation: `closing_signed`](#closing-negotiation-closing_signed) @@ -445,6 +446,46 @@ to broadcast the commitment transaction to get his funds back and open a new channel. To avoid this, the funder should ensure the funding transaction confirms in the next 2016 blocks. +## Channel Quiescence + +Various fundamental changes, in particular protocol upgrades, are +easiest on channels where both commitment transactions match, and no +pending updates are in flight. We define a protocol to quiesce the +channel by indicating that "SomeThing Fundamental is Underway". + +### `stfu` + +1. type: 2 (`stfu`) +2. data: + * [`channel_id`:`channel_id`] + +### Requirements + +The sender of `stfu`: + - MUST NOT send `stfu` if any of the sender's htlc additions, htlc removals + or fee updates are pending for either peer. + - MUST NOT send `stfu` twice. + - MUST set `channel_id` to the id of the channel to quiesce. + - MUST now consider the channel to be quiescing. + - MUST NOT send an update message after `stfu`. + +The receiver of `stfu`: + - if it has sent `stfu` then: + - MUST now consider the channel to be quiescent + - otherwise: + - SHOULD NOT send any more update messages. + - MUST reply with `stfu` once it can do so. + +Upon disconnection: + - the channel is no longer considered quiescent. + +### Rationale + +The normal use would be to cease sending updates, then wait for all +the current updates to be acknowledged by both peers, then start +quiescence. If both sides send `stfu` simultaneously, the result is +exactly the same as if one had replied to the other. + ## Channel Close Nodes can negotiate a mutual close of the connection, which unlike a From b96218b06b68cf349457b282f05d48ebd89c7273 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 24 May 2021 14:23:39 +0930 Subject: [PATCH 02/11] BOLT #2: Set an initiator in quiescence. This is especially useful for protocols such as splicing; for simplified commitment transactions, there is already an implied initiator at each point, so having the negotiation at splicing time would be redundant. Signed-off-by: Rusty Russell --- 02-peer-protocol.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index e592e0a33..dca1cd5ee 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -458,6 +458,7 @@ channel by indicating that "SomeThing Fundamental is Underway". 1. type: 2 (`stfu`) 2. data: * [`channel_id`:`channel_id`] + * [`u8`:`initiator`] ### Requirements @@ -465,6 +466,10 @@ The sender of `stfu`: - MUST NOT send `stfu` if any of the sender's htlc additions, htlc removals or fee updates are pending for either peer. - MUST NOT send `stfu` twice. + - if it is replying to an `stfu`: + - MUST set `initiator` to 0 + - otherwise: + - MUST set `initiator` to 1 - MUST set `channel_id` to the id of the channel to quiesce. - MUST now consider the channel to be quiescing. - MUST NOT send an update message after `stfu`. @@ -483,8 +488,14 @@ Upon disconnection: The normal use would be to cease sending updates, then wait for all the current updates to be acknowledged by both peers, then start -quiescence. If both sides send `stfu` simultaneously, the result is -exactly the same as if one had replied to the other. +quiescence. For some protocols, choosing the initiator matters, +so this flag is sent. + +If both sides send `stfu` simultaneously, they will both set +`initiator` to `1`, in which case the "initiator" is arbitrarily +considered to be the channel funder (the sender of `open_channel`). +The quiescence effect is exactly the same as if one had replied to the +other. ## Channel Close From f3a800699a8cd54d425238bc8b685a1636a1012b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 24 May 2021 14:51:28 +0930 Subject: [PATCH 03/11] splicing: use the generic negotiation mechanism to splice in/out of a channel. The initiator (in the case of simultaneity, the higher feepayer) pays for the input and output, and sets the feerate. We freeze the channel while this construction is going on: it should be quick. Signed-off-by: Rusty Russell Header from folded patch 'fixup3.patch': fixup! splicing: use the generic negotiation mechanism to splice in/out of a channel. - Remove 1 per minute restriction: 25% growth limits us a lot (@niftynei) - Nomenclature: initiator, splice transaction, channel funding output. - Weaken reserve check to only cover iff they extract funds. --- 02-peer-protocol.md | 108 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index dca1cd5ee..062c79360 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -497,6 +497,114 @@ considered to be the channel funder (the sender of `open_channel`). The quiescence effect is exactly the same as if one had replied to the other. +## Splicing + +Splicing is the term given for replacing the funding transaction with +a new one. For simplicity, no other changes can be made while the new +transaction is being negotiated, but operation returns to normal once +negotiation is done (while waiting for the splice transaction(s) to +confirm). + +### The `splice` Message + +1. type: 74 (`splice`) +2. data: + * [`chain_hash`:`chain_hash`] + * [`channel_id`:`channel_id`] + * [`u32`:`funding_feerate_perkw`] + * [`u64`:`generation`] + * [`point`:`payment_basepoint`] + * [`point`:`first_per_commitment_point`] + * [`point`:`next_per_commitment_point`] + +#### Requirements + +The sender: +- MUST NOT send `splice` before sending and receiving `funding_locked`. +- MUST NOT send another splice message while a splice is being negotiated. +- MUST NOT send a splice message after sending uncommitted changes. +- If a splice is in progress: + - MUST NOT send a splice message with `funding_feerate_perkw` which is less than 1.25 the previous `funding_feerate_perkw` (rounded down). +- MUST NOT send other channel updates until splice negotiation has completed. + +The receiver: +- SHOULD fail the splice if there is an ongoing splice, and the `funding_feerate_perkw` is not at least 1.25 the previous `funding_feerate_perkw` (rounded down). +- MUST respond with a `splice` message of its own if it has not already. +- MUST NOT reply with `splice` until all commitment updates are resolved by bother peers. +- MAY set `funding_feerate_perkw` below the received value. +- MUST use the higher of the two `funding_feerate_perkw` as the feerate for + the splice. +- MUST NOT send other channel updates until splice negotiation has completed. + + +#### Rationale + +Both sides agree to a splice: there is no harm in agreeing to a splice +with a high feerate (presumably the recipient will not contribute to +the splice which they consider to be overpaying). + +Any pending updates are flushed before sending, but the reply must +wait until all changes are resolved.. So in the case where the A +sends `splice` while B has just added an HTLC, then B will have to +send `commitment_signed`, then A will have to reply with +`revoke_and_ack` then `commitment_signed`, the B will have to also +reply with `revoke_and_ack` before it can finally reply with `splice`. + +## Splice Negotiation + +The splice negotiation is very similar to the `init_rbf` negotiation: +both sides alternate sending `tx_add_input` and `tx_add_output` until +they both send consecutive `tx_complete`. + +### Requirements + +(Note that many of these messages have their own, additional +requirements detailed elsewhere). + +The initiator is defined as the side which offered the higher +`funding_feerate_perkw`, or if both sides are equal, the lower +SEC1-encoded node_id. + +The initiator: +- MUST `tx_add_input` an input which spends the current funding transaction output. +- MUST `tx_add_output` a zero-value output which pays to the two funding keys using the higher of the two `generation` fields. +- MUST pay for the common fields. + +Upon receipt of consecutive `tx_complete`s, each node: +- MUST fail negotiation if there is not exactly one input spending the current funding transaction. +- MUST fail negotiation if there is not exactly one output with zero value paying to the two funding keys (a.k.a. the new channel funding output) +- MUST calculate the channel capacity for each side: + - Start with the previous balance + - Add that side's new inputs (excluding the one spending the current funding transaction) + - Subtracting each sides new outputs (except the zero-value one paying to the funding keys) + - Subtract the total fee that side is paying for the splice transaction. +- MUST replace the zero-value funding output amount with the total channel capacity. +- MUST calculate the channel balance for each side: + - Subtract any outstanding HTLCs offered by that side. +- if either side has added an output other than the new channel funding output: + - MUST fail the negotiation if the balance for that side is less than 1% of the total channel capacity. +- SHOULD NOT fail if the splice transaction is nonstandard. +- MUST increment the commitment number and send `commitment_signed`, including the signatures for the splice transaction. + +- Upon receipt of `revoke_and_ack` for the previous commitment: + - MUST send `tx_signatures` for the splice transaction. + +- Upon receipt of `tx_signatures` for the splice transaction: + - MUST consider splice negotiation complete. + +On reconnection: +- MUST retransmit the last splice `tx_signatures` (if any). +- MUST ignore any redundant `tx_signatures` it receives. + +### Rationale + +If a side does not meet the reserve requirements, that's OK: but if +they take funds out of the channel, they must ensure that they do meet +them. If your peer adds a massive amount to the channel, then you +only have to add more reserve if you want to contribute to the splice +(and you can use `tx_remove_output` and/or `tx_remove_input` part-way +through if this happens). + ## Channel Close Nodes can negotiate a mutual close of the connection, which unlike a From 41a128b45cc848f483d6b204092968466da63670 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 24 May 2021 14:51:28 +0930 Subject: [PATCH 04/11] Splicing: rewrite it to work on top of quiescence. This is much simpler. Signed-off-by: Rusty Russell --- 02-peer-protocol.md | 62 ++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 35 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 062c79360..0f4c2f1fb 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -500,10 +500,11 @@ other. ## Splicing Splicing is the term given for replacing the funding transaction with -a new one. For simplicity, no other changes can be made while the new -transaction is being negotiated, but operation returns to normal once -negotiation is done (while waiting for the splice transaction(s) to -confirm). +a new one. For simplicity, splicing takes place once a channel is +[quiescent](#channel-quiescence). + +Operation returns to normal once negotiation is done (while waiting +for the splice transaction(s) to confirm). ### The `splice` Message @@ -512,43 +513,37 @@ confirm). * [`chain_hash`:`chain_hash`] * [`channel_id`:`channel_id`] * [`u32`:`funding_feerate_perkw`] - * [`u64`:`generation`] - * [`point`:`payment_basepoint`] - * [`point`:`first_per_commitment_point`] - * [`point`:`next_per_commitment_point`] + * [`point`:`funding_pubkey`] + +1. type: 76 (`splice_ack`) +2. data: + * [`chain_hash`:`chain_hash`] + * [`channel_id`:`channel_id`] + * [`point`:`funding_pubkey`] #### Requirements -The sender: +The sender of `splice`: +- MUST have successfully initiated quiescence. - MUST NOT send `splice` before sending and receiving `funding_locked`. -- MUST NOT send another splice message while a splice is being negotiated. -- MUST NOT send a splice message after sending uncommitted changes. -- If a splice is in progress: +- MUST NOT send `splice` while a splice is being negotiated. +- If any splice is in progress: - MUST NOT send a splice message with `funding_feerate_perkw` which is less than 1.25 the previous `funding_feerate_perkw` (rounded down). -- MUST NOT send other channel updates until splice negotiation has completed. -The receiver: -- SHOULD fail the splice if there is an ongoing splice, and the `funding_feerate_perkw` is not at least 1.25 the previous `funding_feerate_perkw` (rounded down). -- MUST respond with a `splice` message of its own if it has not already. -- MUST NOT reply with `splice` until all commitment updates are resolved by bother peers. -- MAY set `funding_feerate_perkw` below the received value. -- MUST use the higher of the two `funding_feerate_perkw` as the feerate for - the splice. -- MUST NOT send other channel updates until splice negotiation has completed. +The receiver of `splice`: +- SHOULD fail the connection if there is an ongoing splice, and the `funding_feerate_perkw` is not at least 1.25 the previous `funding_feerate_perkw` (rounded down). +- MUST respond with `splice_ack` containing its own `funding_pubkey`. +- MUST begin splice negotiation. +The receiver of `splice_ack`: +- MUST begin splice negotiation. -#### Rationale -Both sides agree to a splice: there is no harm in agreeing to a splice -with a high feerate (presumably the recipient will not contribute to -the splice which they consider to be overpaying). +#### Rationale -Any pending updates are flushed before sending, but the reply must -wait until all changes are resolved.. So in the case where the A -sends `splice` while B has just added an HTLC, then B will have to -send `commitment_signed`, then A will have to reply with -`revoke_and_ack` then `commitment_signed`, the B will have to also -reply with `revoke_and_ack` before it can finally reply with `splice`. +There is no harm in agreeing to a splice with a high feerate +(presumably the recipient will not contribute to the splice which they +consider to be overpaying). ## Splice Negotiation @@ -561,10 +556,6 @@ they both send consecutive `tx_complete`. (Note that many of these messages have their own, additional requirements detailed elsewhere). -The initiator is defined as the side which offered the higher -`funding_feerate_perkw`, or if both sides are equal, the lower -SEC1-encoded node_id. - The initiator: - MUST `tx_add_input` an input which spends the current funding transaction output. - MUST `tx_add_output` a zero-value output which pays to the two funding keys using the higher of the two `generation` fields. @@ -591,6 +582,7 @@ Upon receipt of consecutive `tx_complete`s, each node: - Upon receipt of `tx_signatures` for the splice transaction: - MUST consider splice negotiation complete. + - MUST consider the connection no longer quiescent. On reconnection: - MUST retransmit the last splice `tx_signatures` (if any). From dc9acdba7d6773cf90d4b00e87fbf3b6217b3a23 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 24 May 2021 14:51:28 +0930 Subject: [PATCH 05/11] commitment_signed: add tlvs for splice sigs. Signed-off-by: Rusty Russell --- .aspell.en.pws | 1 + 02-peer-protocol.md | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/.aspell.en.pws b/.aspell.en.pws index 7f3e47e42..99b58b6f8 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -389,3 +389,4 @@ sats quiesce quiescing SomeThing +commitsigs diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 0f4c2f1fb..90229dcb9 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -1158,12 +1158,26 @@ sign the resulting transaction (as defined in [BOLT #3](03-transactions.md)), an * [`signature`:`signature`] * [`u16`:`num_htlcs`] * [`num_htlcs*signature`:`htlc_signature`] + * [`commitment_signed_tlvs`:`tlvs`] + +1. `tlv_stream`: `commitment_signed_tlvs` +2. types: + 1. type: 0 (`splice_commitsigs`) + 2. data: + * [`...*commitsigs`:`sigs`] + +1. subtype: `commitsigs` +2. data: + * [`signature`:`commit_signature`] + * [`u16`:`num_htlcs`] + * [`num_htlcs*signature`:`htlc_signature`] + #### Requirements A sending node: - MUST NOT send a `commitment_signed` message that does not include any -updates. +updates, or add or remove splices. - MAY send a `commitment_signed` message that only alters the fee. - MAY send a `commitment_signed` message that doesn't @@ -1174,6 +1188,7 @@ fee changes). to the ordering of the commitment transaction (see [BOLT #3](03-transactions.md#transaction-input-and-output-ordering)). - if it has not recently received a message from the remote node: - SHOULD use `ping` and await the reply `pong` before sending `commitment_signed`. + - MUST send a `commitsigs` for each splice in progress, in increasing feerate order. A receiving node: - once all pending updates are applied: @@ -1184,6 +1199,10 @@ A receiving node: - MUST fail the channel. - if any `htlc_signature` is not valid for the corresponding HTLC transaction OR non-compliant with LOW-S-standard rule [LOWS](https://github.com/bitcoin/bitcoin/pull/6769): - MUST fail the channel. + - if there is not exactly one `commitsigs` for each splice in progress: + - MUST fail the channel. + - if `commit_signature`, `num_htlcs` or `htlc_signature` is not correct as specified above for each splice: + - MUST fail the channel. - MUST respond with a `revoke_and_ack` message. #### Rationale @@ -1203,6 +1222,11 @@ Note that the `htlc_signature` implicitly enforces the time-lock mechanism in th The `option_anchor_outputs` allows HTLC transactions to "bring their own fees" by attaching other inputs and outputs, hence the modified signature flags. +Splicing requires us to send and receive redundant signatures, as we +don't know which (if any) of the splice transactions will end up being +the new channel. Increasing feerate order is also the order in which +splices were negotiated (since each must increase the feerate). + ### Completing the Transition to the Updated State: `revoke_and_ack` Once the recipient of `commitment_signed` checks the signature and knows From deb03f350c34e2e6c8321d43676e939d0d5f099c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 24 May 2021 14:51:28 +0930 Subject: [PATCH 06/11] splice_locked: terminate this splice once one reaches agreed depths. Signed-off-by: Rusty Russell Header from folded patch 'fixup2.patch': fixup! splice_locked: terminate this splice once one reaches agreed depths. Use 6; we need to start announcing then anyway, so keep it simple. --- 02-peer-protocol.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 90229dcb9..1b0d0de57 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -506,6 +506,10 @@ a new one. For simplicity, splicing takes place once a channel is Operation returns to normal once negotiation is done (while waiting for the splice transaction(s) to confirm). +The splice is finally terminated when both sides send +`splice_complete` to indicate that one of the splice transactions +reached acceptable depth. + ### The `splice` Message 1. type: 74 (`splice`) @@ -597,6 +601,22 @@ only have to add more reserve if you want to contribute to the splice (and you can use `tx_remove_output` and/or `tx_remove_input` part-way through if this happens). +## Splice Completion + +Each node: +- if any splice transaction reaches depth 6: + - MUST send `splice_locked`. + +Once a node has received and sent `splice_locked`: + - MUST consider the successful splice to be the new funding + transaction for all future `commitment_signed` and splice operations. + - MUST discard the previous funding transaction and other splice operations. + - MUST send a new `commitment_signed` (with no `splice_commitsigs`). + +On reconnection: + - MUST retransmit the last `splice_locked` if the peer did not + acknowledge the `commitment_signed`. + ## Channel Close Nodes can negotiate a mutual close of the connection, which unlike a From f3a9f7f4e9e7a5a2997f3129e13d94090091846a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 24 May 2021 14:51:28 +0930 Subject: [PATCH 07/11] gossip: add a bit to indicate "splicing". This was Matt Corallo's idea; a simple flag means you should keep using the channel as it's being replaced. Signed-off-by: Rusty Russell --- 07-routing-gossip.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/07-routing-gossip.md b/07-routing-gossip.md index b89c3d222..52db5933a 100644 --- a/07-routing-gossip.md +++ b/07-routing-gossip.md @@ -418,6 +418,7 @@ individual bits: | ------------- | ----------- | -------------------------------- | | 0 | `direction` | Direction this update refers to. | | 1 | `disable` | Disable the channel. | +| 2 | `splicing` | Temporarily ignore channel spend.| The `message_flags` bitfield is used to indicate the presence of optional fields in the `channel_update` message: @@ -485,6 +486,7 @@ The origin node: - MUST set `fee_proportional_millionths` to the amount (in millionths of a satoshi) it will charge per transferred satoshi. - SHOULD NOT create redundant `channel_update`s + - SHOULD set `splicing` in all `channel_update` once splicing has been negotiated for a channel. The receiving node: - if the `short_channel_id` does NOT match a previous `channel_announcement`, @@ -559,6 +561,11 @@ the channel when the peer reestablishes contact. Because gossip messages are batched and replace previous ones, the result may be a single seemingly-redundant update. +The simple `splicing` flag warns nodes that this channel will be +replaced; it tells them to give a grace period for the new channel to +appear (it can't be announced until it's 6 blocks deep) during which +it can use the old channel id. + ## Query Messages Negotiating the `gossip_queries` option via `init` enables a number @@ -967,6 +974,8 @@ A node: - SHOULD monitor the funding transactions in the blockchain, to identify channels that are being closed. - if the funding output of a channel is being spent: + - if a `channel_update` had `splicing` in the `channel_flags`: + - SHOULD delay 10 blocks considering the output spent. - SHOULD be removed from the local network view AND be considered closed. - if the announced node no longer has any associated open channels: - MAY prune nodes added through `node_announcement` messages from their From 8fb50a48ec289b350b599bae02f8a3ebbec43144 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 24 May 2021 14:51:28 +0930 Subject: [PATCH 08/11] gossip: make sure to send new announcement_signatures post-splice. Signed-off-by: Rusty Russell Header from folded patch 'fixup.patch': fixup! gossip: make sure to send new announcement_signatures post-splice. It's called `splice_locked` and it's always sent 6 blocks. --- 07-routing-gossip.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/07-routing-gossip.md b/07-routing-gossip.md index 52db5933a..b11816aed 100644 --- a/07-routing-gossip.md +++ b/07-routing-gossip.md @@ -87,6 +87,8 @@ A node: - MUST send the `announcement_signatures` message. - MUST NOT send `announcement_signatures` messages until `funding_locked` has been sent and received AND the funding transaction has at least six confirmations. + - MUST send `announcement_signatures` message after `splice_locked` + has been sent and received. - otherwise: - MUST NOT send the `announcement_signatures` message. - upon reconnection (once the above timing requirements have been met): From a20bc6d306059841b2d63bc73883e9aa8cb624ab Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 24 May 2021 15:08:11 +0930 Subject: [PATCH 09/11] BOLT 2: note splice requirements in the checks for adding HTLCs and setting fees. Any changes must be valid for all possible commitment transactions. A minor change, but for implementations which quote the spec and check those quotes this will highlight the changes needed. Signed-off-by: Rusty Russell --- 02-peer-protocol.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 1b0d0de57..2718b750f 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -1006,7 +1006,7 @@ A sending node: between implementations. - if it is _not responsible_ for paying the Bitcoin fee: - SHOULD NOT offer `amount_msat` if, once the remote node adds that HTLC to - its commitment transaction, it cannot pay the fee for the updated local or + any of its commitment transactions, it cannot pay the fee for the updated local or remote transaction at the current `feerate_per_kw` while maintaining its channel reserve. - MUST offer `amount_msat` greater than 0. @@ -1083,6 +1083,9 @@ maintaining its channel reserve (because of the increased weight of the commitment transaction), resulting in a degraded channel. See [#728](https://github.com/lightningnetwork/lightning-rfc/issues/728) for more details. +If splicing is supported, there can be more than one commitment transaction +at a time: proposed changes must be valid for all of them. + ### Removing an HTLC: `update_fulfill_htlc`, `update_fail_htlc`, and `update_fail_malformed_htlc` For simplicity, a node can only remove HTLCs added by the other node. @@ -1315,6 +1318,8 @@ given in [BOLT #3](03-transactions.md#fee-calculation). The node _responsible_ for paying the Bitcoin fee: - SHOULD send `update_fee` to ensure the current fee rate is sufficient (by a significant margin) for timely processing of the commitment transaction. + - MUST NOT set `feerate_per_kw` in excess of what it can afford on any of the receiving node's + current commitment transactions. The node _not responsible_ for paying the Bitcoin fee: - MUST NOT send `update_fee`. @@ -1325,7 +1330,7 @@ A receiving node: - if the sender is not responsible for paying the Bitcoin fee: - MUST fail the channel. - if the sender cannot afford the new fee rate on the receiving node's - current commitment transaction: + current commitment transactions: - SHOULD fail the channel, - but MAY delay this check until the `update_fee` is committed. @@ -1351,6 +1356,9 @@ it's simplest to only allow it to set fee levels; however, as the same fee rate applies to HTLC transactions, the receiving node must also care about the reasonableness of the fee. +If splicing is supported, there can be more than one commitment transaction +at a time: proposed changes must be valid for all of them. + ## Message Retransmission Because communication transports are unreliable, and may need to be From 596fe0be69896be68b852065cc6f384d0f1c15e7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 4 Jun 2021 15:06:22 +0930 Subject: [PATCH 10/11] BOLT 2: can't complete shutdown while splicing --- 02-peer-protocol.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 2718b750f..fff91b954 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -660,10 +660,13 @@ A sending node: - MAY send a `shutdown` before a `funding_locked`, i.e. before the funding transaction has reached `minimum_depth`. - if there are updates pending on the receiving node's commitment transaction: - MUST NOT send a `shutdown`. + - if there is an ongoing splice: + - MUST NOT send a `shutdown`. - MUST NOT send an `update_add_htlc` after a `shutdown`. - if no HTLCs remain in either commitment transaction: - MUST NOT send any `update` message after a `shutdown`. - SHOULD fail to route any HTLC added after it has sent `shutdown`. + - MUST NOT initiate a new splice if none are already in progress after a `shutdown`. - if it sent a non-zero-length `shutdown_scriptpubkey` in `open_channel` or `accept_channel`: - MUST send the same value in `scriptpubkey`. - MUST set `scriptpubkey` in one of the following forms: @@ -681,8 +684,9 @@ A receiving node: - SHOULD fail the connection. - if it hasn't sent a `funding_locked` yet: - MAY reply to a `shutdown` message with a `shutdown` - - once there are no outstanding updates on the peer, UNLESS it has already sent a `shutdown`: + - once there are no outstanding updates on the peer and no ongoing splice, UNLESS it has already sent a `shutdown`: - MUST reply to a `shutdown` message with a `shutdown` + - MUST NOT initiate a new splice if none are already in progress. - if both nodes advertised the `option_upfront_shutdown_script` feature, and the receiving node received a non-zero-length `shutdown_scriptpubkey` in `open_channel` or `accept_channel`, and that `shutdown_scriptpubkey` is not equal to `scriptpubkey`: - MUST fail the connection. @@ -711,6 +715,12 @@ of the receiving node to change the `scriptpubkey`. The `shutdown` response requirement implies that the node sends `commitment_signed` to commit any outstanding changes before replying; however, it could theoretically reconnect instead, which would simply erase all outstanding uncommitted changes. +`shutdown` requires that there be no splice in progress, but if there +is already a splice in progress, it might require another splice to +"unstick" it (if the first splice was invalid, double-spent, or simply +had too low a fee), so in this case initiating another splice is legal +even after sending a shutdown. + ### Closing Negotiation: `closing_signed` Once shutdown is complete and the channel is empty of HTLCs, the final From e63233216760713828e2287862104acc1b3060e3 Mon Sep 17 00:00:00 2001 From: Dustin Dettmer Date: Thu, 28 Apr 2022 15:45:03 -0500 Subject: [PATCH 11/11] Explicitly add a way for the splice receiving node to reject a splice they don't like. --- 02-peer-protocol.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index fff91b954..ce9f4785b 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -588,6 +588,11 @@ Upon receipt of consecutive `tx_complete`s, each node: - MUST consider splice negotiation complete. - MUST consider the connection no longer quiescent. +- Upon receipt of `tx_abort` for the splice transaction: + - MUST NOT have sent `tx_signatures`. + - MUST consider the connection no longer quiescent. + - MUST forget the in progress splice transaction. + On reconnection: - MUST retransmit the last splice `tx_signatures` (if any). - MUST ignore any redundant `tx_signatures` it receives.