📅 Original date posted:2023-07-17
🗒️ Summary of this message: This is a proposal for a close protocol in the Lightning Network, allowing each side to indicate whether they want to omit their own output.
📝 Original message:
https://github.com/lightning/bolts/pull/1096
This is a "can't fail!" close protocol, as discussed at the NY Summit, and on @Roasbeef's wishlist. It's about as simple as I could make it: the only complexity comes from allowing each side to indicate whether they want to omit their own output.
It's "taproot ready"(TM) in the sense that shutdown is always sent to trigger it, so that can contain the nonces without any persistence requirement.
I split it into three commits for cleanliness:
1 Introduce the new protocol
2. Remove the requirement that shutdown not be sent multiple times (which was already nonsensical)
3. Remove the older protocols
The first commit is inline here, for easy review:
diff --git a/02-peer-protocol.md b/02-peer-protocol.md
index f43c686..ce859f2 100644
--- a/02-peer-protocol.md
+++ b/02-peer-protocol.md
@@ -16,6 +16,7 @@ operation, and closing.
* [Channel Close](#channel-close)
* [Closing Initiation: `shutdown`](#closing-initiation-shutdown)
* [Closing Negotiation: `closing_signed`](#closing-negotiation-closing_signed)
+ * [Closing Negotiation: `closing_complete` and `closing_sig`](#closing-negotiation-closing_complete-and-closing_sig)
* [Normal Operation](#normal-operation)
* [Forwarding HTLCs](#forwarding-htlcs)
* [`cltv_expiry_delta` Selection](#cltv_expiry_delta-selection)
@@ -584,6 +585,17 @@ Closing happens in two stages:
| |<-(?)-- closing_signed Fn----| |
+-------+ +-------+
+ +-------+ +-------+
+ | |--(1)----- shutdown ------->| |
+ | |<-(2)----- shutdown --------| |
+ | | | |
+ | | <complete all pending HTLCs> | |
+ | A | ... | B |
+ | | | |
+ | |--(3)-- closing_complete Fee->| |
+ | |<-(4)-- closing_sig ----------| |
+ +-------+ +-------+
+
### Closing Initiation: `shutdown`
Either node (or both) can send a `shutdown` message to initiate closing,
@@ -776,6 +788,83 @@ satoshis, which is possible if `dust_limit_satoshis` is below 546 satoshis).
No funds are at risk when that happens, but the channel must be force-closed as
the closing transaction will likely never reach miners.
+### Closing Negotiation: `closing_complete` and `closing_sig`
+
+Once shutdown is complete, the channel is empty of HTLCs, there are no commitments
+for which a revocation is owed, and all updates are included on both commitments,
+the final current commitment transactions will have no HTLCs.
+
+Each peer says what fee it will pay, and the other side simply signs that transaction. The only complexity comes from allowing each side to omit its own output should it be uneconomic.
+
+This process will be repeated every time a `shutdown` message is received, which allows re-negotiation.
+
+1. type: 40 (`closing_complete`)
+2. data:
+ * [`channel_id`:`channel_id`]
+ * [`u64`:`fee_satoshis`]
+ * [`u8`: `has_closer_output`]
+ * [`signature`:`signature_with_closee_output`]
+ * [`signature`:`signature_without_closee_output`]
+
+1. type: 41 (`closing_sig`)
+2. data:
+ * [`channel_id`:`channel_id`]
+ * [`u8`: `closee_output`]
+ * [`signature`:`signature`]
+
+#### Requirements
+
+Note: the details and requirements for the transaction being signed are in [BOLT 3](03-transactions.md#closing-transaction)).
+
+Both nodes:
+ - After a `shutdown` has been received, AND no HTLCs remain in either commitment transaction:
+ - SHOULD send a `closing_complete` message.
+
+The sender of `closing_complete` (aka. "the closer"):
+ - MUST set `fee_satoshis` to a fee less than or equal to its outstanding balance, rounded down to whole satoshis.
+ - SHOULD set `has_closer_output` to 0 if it considers its own remaining balance to be uneconomic.
+ - Otherwise MUST set `has_closer_output` to 1.
+ - If it sets `has_closer_output` to 1:
+ - MUST set `signature_with_closee_output` to a valid signature of a transaction with both closer and closee outputs.
+ - MUST set `signature_without_closee_output` to a valid signature of a transaction with only a closer output.
+ - Otherwise: (`has_closer_output` is 0):
+ - MUST set `signature_with_closee_output` to a valid signature of a transaction with only the closee output.
+ - MUST set `signature_without_closee_output` to a valid signature of a transaction with only the null output.
+
+The receiver of `closing_complete` (aka. "the closee"):
+ - if either `signature_with_closee_output` or `signature_without_closee_output` is not valid for the closing transactions specified in [BOLT #3](03-transactions.md#closing-transaction) OR non-compliant with LOW-S-standard rule<sup>[LOWS](https://github.com/bitcoin/bitcoin/pull/6769)</sup>:
+ - SHOULD send a `warning` and close the connection, or send an
+ `error` and fail the channel.
+ - Otherwise:
+ - MUST select one of the signatures (and thus, transactions) to respond to.
+ - SHOULD sign and broadcast that transaction.
+ - SHOULD send `closing_sig`.
+
+The sender of `closing_sig`:
+ - if it selected `signature_with_closee_output` to broadcast:
+ - MUST set `closee_output` to 1.
+ - MUST set `signature` to a valid signature on that transaction.
+ - otherwise (it selected `signature_without_closee_output`):
+ - MUST set `closee_output` to 0.
+ - MUST set `signature` to a valid signature on that transaction.
+
+The receiver of `closing_sig`:
+ - SHOULD broadcast the transaction indicated by `closee_output`.
+
+### Rationale
+
+The close protocol is designed to avoid any failure scenarios caused by fee disagreement, since each side offers to pay its own desired fee.
+
+Multiple signatures are given, so each side can choose whether it wants to include its own output. In the case of large fees and tiny channels, where neither side wants its output, the use of an OP_RETURN simply cleans up the dangling unspent transaction output. This is expected to be extremely rare.
+
+Note that there is usually no reason to pay a high fee for rapid processing, since an urgent child could pay the fee on the closing transactions' behalf.
+
+If the closer proposes a transaction which will not relay (either its own output is dust, or the fee rate it proposes is too low), it doesn't harm the closee to sign the transaction.
+
+Similarly, if the closer proposes a high fee, it doesn't harm the closee to sign the transaction, as the closer is paying.
+
+There's a slight game where each side would prefer the other side pay the fee, and proposes a minimal fee. If neither side proposes a fee which will relay, the negotiation can occur again, or the final commitment transaction can be spent. In practice, the opener has an incentive to offer a reasonable closing fee, as they would pay the fee for the commitment transaction, which also costs more to spend.
+
## Normal Operation
Once both nodes have exchanged `channel_ready` (and optionally [`announcement_signatures`](07-routing-gossip.md#the-announcement_signatures-message)), the channel can be used to make payments via Hashed Time Locked Contracts.
diff --git a/03-transactions.md b/03-transactions.md
index a8e843f..d9d194e 100644
--- a/03-transactions.md
+++ b/03-transactions.md
@@ -347,7 +347,9 @@ The witness script for the output is:
To spend this via penalty, the remote node uses a witness stack `<revocationsig> 1`, and to collect the output, the local node uses an input with nSequence `to_self_delay` and a witness stack `<local_delayedsig> 0`.
-## Closing Transaction
+## Classic Closing Transaction
+
+This variant is used for `closing_signed` messages (i.e. where `option_simple_close` is not negotiated).
Note that there are two possible variants for each node.
@@ -388,6 +390,40 @@ has been used.
There will be at least one output, if the funding amount is greater
than twice `dust_limit_satoshis`.
+## Closing Transaction
+
+This variant is used for `closing_complete` and `closing_sig` messages (i.e. where `option_simple_close` is negotiated).
+
+In this case, the node sending `closing_complete` ("the closer") pays the fees, and the sequence is set to 0xFFFFFFFD to allow RBF. The outputs are ordered as detailed in [Transaction Output Ordering](#transaction-output-ordering).
+
+Two closing transactions are always produced: one `with_closee_output` one `without_closee_output` (the non-closer chooses which to accept). `closing_complete` contains `has_closer_output` to indicate whether the closer's output is in the transactions.
+
+* version: 2
+* locktime: 0
+* txin count: 1
+ * `txin[0]` outpoint: `txid` and `output_index` from `funding_created` message
+ * `txin[0]` sequence: 0xFFFFFFFD
+ * `txin[0]` script bytes: 0
+ * `txin[0]` witness: `0 <signature_for_pubkey1> <signature_for_pubkey2>`
+
+* txout count: 1 or 2 of the following
+ * The closer output:
+ * `txout` amount: the final balance for the closer, minus `closing_complete` `fee_satoshis`, rounded down to whole satoshis.
+ * `txout` script: as specified in that closer's `scriptpubkey` in its `shutdown` message
+ * The closee output:
+ * `txout` amount: the final balance for the closer, rounded down to whole satoshis.
+ * `txout` script: as specified in that closee's `scriptpubkey` in its `shutdown` message
+ * The null output:
+ * `txout` amount: 0
+ * `txout` script: `OP_RETURN` (106).
+
+### Requirements
+
+Each node offering a signature:
+ - MUST round each output down to whole satoshis.
+ - MUST subtract the fee given by `fee_satoshis` from the closer output.
+
+
## Fees
### Fee Calculation
diff --git a/09-features.md b/09-features.md
index ba0a0c5..a4fe9c3 100644
--- a/09-features.md
+++ b/09-features.md
@@ -48,6 +48,7 @@ The Context column decodes as follows:
| 46/47 | `option_scid_alias` | Supply channel aliases for routing | IN | | [BOLT #2][bolt02-channel-ready] |
| 48/49 | `option_payment_metadata` | Payment metadata in tlv record | 9 | | [BOLT #11](11-payment-encoding.md#tagged-fields) |
| 50/51 | `option_zeroconf` | Understands zeroconf channel types | IN | `option_scid_alias` | [BOLT #2][bolt02-channel-ready] |
+| 60/61 | `option_simple_close` | Simplified closing negotiation | IN | `option_shutdown_anysegwit` | [BOLT #2][bolt02-simple-close] |
## Definitions
@@ -96,6 +97,7 @@ This work is licensed under a [Creative Commons Attribution 4.0 International Li
[bolt02-retransmit]: 02-peer-protocol.md#message-retransmission
[bolt02-open]: 02-peer-protocol.md#the-open_channel-message
+[bolt02-simple-close]: 02-peer-protocol.md#closing-negotiation-closing_complete-and-closing_sig
[bolt03-htlc-tx]: 03-transactions.md#htlc-timeout-and-htlc-success-transactions
[bolt02-shutdown]: 02-peer-protocol.md#closing-initiation-shutdown
[bolt02-channel-ready]: 02-peer-protocol.md#the-channel_ready-message