diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 27b01fe04..6ba527e61 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -36,6 +36,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) @@ -1508,23 +1509,68 @@ Closing happens in two stages: 2. once all HTLCs are resolved, the final channel close negotiation begins. +-------+ +-------+ - | |--(1)----- shutdown ------->| | - | |<-(2)----- shutdown --------| | + | | shutdown(scriptA1) | | + | |----------------------------->| | + | | shutdown(scriptB1) | | + | |<-----------------------------| | | | | | | | | | - | A | ... | B | + | A | .... | B | | | | | - | |--(3)-- closing_signed F1--->| | - | |<-(4)-- closing_signed F2----| | - | | ... | | - | |--(?)-- closing_signed Fn--->| | - | |<-(?)-- closing_signed Fn----| | + | | closing_complete | | + | |----------------------------->| | + | | closing_complete | | + | |<-----------------------------| | + | | closing_sig | | + | |<-----------------------------| | + | | closing_sig | | + | |----------------------------->| | + | | | | + | | | | + | | | | + | | shutdown(scriptA2) | | + | |----------------------------->| | + | | shutdown(scriptB1) | | (*) Bob doesn't update his script + | |<-----------------------------| | + | | closing_complete | | + | |----------------------------->| | + | | closing_sig | | + | |<-----------------------------| | + | | | | + | | | | + | | | | + | | shutdown(scriptB2) | | + | |<-----------------------------| | + | | shutdown(scriptA2) | | + | |----------------------------->| | + | | closing_complete | | + | | <-------------------| | + | | | | + | | | | (*) This is a concurrent update while Bob is sending closing_complete + | | | | + | | shutdown(scriptA3) | | + | |-------------------> | | + | | closing_complete | | + | |<------------------- | | (*) A doesn't answer with closing_sig because B's sig doesn't use scriptA3 + | | shutdown(scriptA3) | | + | | ------------------->| | + | | shutdown(scriptB2) | | (*) B answers A's shutdown with his own shutdown, without any changes + | |<-----------------------------| | + | | closing_complete | | + | |----------------------------->| | (*) A now uses scriptB2 and scriptA3 for closing_complete + | | closing_complete | | + | |<-----------------------------| | (*) B now uses scriptB2 and scriptA3 for closing_complete + | | closing_sig | | + | |----------------------------->| | + | | closing_sig | | + | |<-----------------------------| | +-------+ +-------+ ### Closing Initiation: `shutdown` Either node (or both) can send a `shutdown` message to initiate closing, -along with the `scriptpubkey` it wants to be paid to. +along with the `scriptpubkey` it wants to be paid to. This can be +sent multiple times. 1. type: 38 (`shutdown`) 2. data: @@ -1540,7 +1586,6 @@ A sending node: - MAY send a `shutdown` before a `channel_ready`, 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`. - - MUST NOT send multiple `shutdown` messages. - MUST NOT send an `update_add_htlc` after a `shutdown`. - if no HTLCs remain in either commitment transaction (including dust HTLCs) and neither side has a pending `revoke_and_ack` to send: @@ -1555,6 +1600,10 @@ A sending node: 3. if (and only if) `option_shutdown_anysegwit` is negotiated: * `OP_1` through `OP_16` inclusive, followed by a single push of 2 to 40 bytes (witness program versions 1 through 16) + 4. if (and only if) `option_simple_close` is negotiated: + * `OP_RETURN` followed by one of: + * `6` to `75` inclusive followed by exactly that many bytes + * `76` followed by `76` to `80` followed by exactly that many bytes A receiving node: - if it hasn't received a `funding_signed` (if it is a funder) or a `funding_created` (if it is a fundee): @@ -1713,6 +1762,161 @@ 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. +`OP_RETURN` is only standard if followed by PUSH opcodes, and the total script +is 83 bytes or less. We are slightly stricter, to only allow a single PUSH, but +there are two forms in script: one which pushes up to 75 bytes, and a longer +one (`OP_PUSHDATA1`) which is needed for 76-80 bytes. + +### 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 lesser-paid peer (if either is) can opt to omit their own output from the closing tx. + +This process will be repeated every time a `shutdown` message is received, which allows re-negotiation (and RBF). + +1. type: 40 (`closing_complete`) +2. data: + * [`channel_id`:`channel_id`] + * [`u64`:`fee_satoshis`] + * [`u32`:`locktime`] + * [`closing_tlvs`:`tlvs`] + +1. `tlv_stream`: `closing_tlvs` +2. types: + 1. type: 1 (`closer_output_only`) + 2. data: + * [`signature`:`sig`] + 1. type: 2 (`closee_output_only`) + 2. data: + * [`signature`:`sig`] + 1. type: 3 (`closer_and_closee_outputs`) + 2. data: + * [`signature`:`sig`] + +1. type: 41 (`closing_sig`) +2. data: + * [`channel_id`:`channel_id`] + * [`closing_tlvs`:`tlvs`] + +#### Requirements + +Note: the details and requirements for the transaction being signed are in [BOLT 3](03-transactions.md#closing-transaction). + +An output is *dust* if the amount is less than the [Bitcoin Core Dust Thresholds](03-transactions.md#dust-limits). + +Both nodes: + - After a `shutdown` has been sent and received, AND no HTLCs remain in either commitment transaction: + - SHOULD send a `closing_complete` message. + - When receiving `shutdown` again, if it did not send `shutdown` first: + - MUST respond with `shutdown`. + - MAY send `closing_complete` afterwards. + +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. + - MUST set `fee_satoshis` so that at least one output is not dust. + - MUST use the last sent and received `shutdown.scriptpubkey` to generate the closing transaction specified in [BOLT #3](03-transactions.md#closing-transaction). + - MUST set `locktime` to the desired `nLockTime` of the closing transaction. + - MUST set `signature` fields as valid signature using its `funding_pubkey` of: + - `closer_output_only`: closing transaction with only the local ("closer") output. + - `closee_output_only`: closing transaction with only the remote ("closee") output. + - `closer_and_closee_outputs`: closing transaction with both the closer and closee outputs. + - If the local outstanding balance (in millisatoshi) is less than the remote outstanding balance: + - MUST NOT set `closer_output_only`. + - MUST set `closee_output_only` if the local output amount is dust. + - MAY set `closee_output_only` if it considers the local output amount uneconomical AND its `scriptpubkey` is not `OP_RETURN`. + - Otherwise (not lesser amount, cannot remove own output): + - MUST NOT set `closee_output_only`. + - If the closee's output amount is dust: + - MUST set `closer_output_only`. + - SHOULD NOT set `closer_and_closee_outputs`. + - Otherwise: + - MUST set both `closer_output_only` and `closer_and_closee_outputs`. + - If it wants to send another `closing_complete` (e.g. with a different `fee_satoshis`): + - MUST send `shutdown` first. + - MUST receive `shutdown` from the remote node in response. + - MUST use the `scriptpubkey`s from those `shutdown` messages. + +The receiver of `closing_complete` (aka. "the closee"): + - If `fee_satoshis` is greater than the closer's outstanding balance: + - MUST either send a `warning` and close the connection, or send an `error` and fail the channel. + - Select a signature for validation: + - if the local output amount is dust: + - MUST use `closer_output_only`. + - otherwise, if it considers the local output amount uneconomical AND its `scriptpubkey` is not `OP_RETURN`: + - MUST use `closer_output_only`. + - otherwise, if `closer_and_closee_outputs` is present: + - MUST use `closer_and_closee_outputs`. + - otherwise: + - MUST use `closee_output_only`. + - If the selected signature field does not exist: + - MUST either send a `warning` and close the connection, or send an `error` and fail the channel. + - If the signature field is not valid for the corresponding closing transaction specified in [BOLT #3](03-transactions.md#closing-transaction): + - MUST ignore `closing_complete`. + - If the signature field is non-compliant with LOW-S-standard rule[LOWS](https://github.com/bitcoin/bitcoin/pull/6769): + - MUST either send a `warning` and close the connection, or send an `error` and fail the channel. + - MUST sign and broadcast the corresponding closing transaction. + - MUST send `closing_sig` with a single valid signature in the same TLV field as the `closing_complete`. + +The receiver of `closing_sig`: + - if `tlvs` does not contain exactly one signature: + - MUST either send a `warning` and close the connection, or send an `error` and fail the channel. + - if `tlvs` does not contain one of the TLV fields sent in `closing_complete`: + - MUST ignore `closing_sig`. + - if the signature field is not valid for the corresponding closing transaction specified in [BOLT #3](03-transactions.md#closing-transaction): + - MUST ignore `closing_sig`. + - if the signature field is non-compliant with LOW-S-standard rule[LOWS](https://github.com/bitcoin/bitcoin/pull/6769): + - MUST either send a `warning` and close the connection, or send an `error` and fail the channel. + - otherwise: + - MUST sign and broadcast the corresponding closing transaction. + +### 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. + +If one side has less funds than the other, it may choose to omit its own output, and in this case +dust MUST be omitted, to ensure that the resulting transaction can be broadcast. + +The corner case where fees are so high that both outputs are dust is addressed in two ways: paying +a low fee to avoid the problem, or using an `OP_RETURN` (which is never "dust"). If one side +chooses to use an `OP_RETURN` output, its amount must be 0 to ensure that the resulting transaction +can be broadcast. + +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 rapid processing is desired and CPFP is +not an option, the closer can RBF its previous closing transactions by sending `shutdown` again. + +Sending a new `shutdown` message overrides previous ones, so you can negotiate again (even changing +the output address when `upfront_shutdown_script` was not negotiated) if you want: in this case +there's a race where you could receive `closing_complete` for the previous output address, and the +signature won't validate. In this case, ignoring the `closing_complete` is the correct behaviour, +as the new `shutdown` will trigger a new `closing_complete` with the correct signature. This +assumption that we only remember the last-sent of any message is why so many cases of bad +signatures are simply ignored. + +When sending a new `shutdown`, we must receive a new `shutdown` from the remote node before +sending `closing_complete`. This is necessary to be compatible with future taproot channels +that use musig2 and need to exchange random nonces every time a transaction spending the channel +output is signed. Note that the remote `shutdown` doesn't need to be an explicit response to the +local `shutdown` that was sent: if both nodes concurrently send `shutdown`, they can exchange +`closing_complete` immediately after receiving the remote `shutdown`. + +If the closer proposes a transaction which will not relay (an 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 0fcdf5cdb..ddc687638 100644 --- a/03-transactions.md +++ b/03-transactions.md @@ -17,6 +17,7 @@ This details the exact format of on-chain transactions, which both sides need to * [Received HTLC Outputs](#received-htlc-outputs) * [Trimmed Outputs](#trimmed-outputs) * [HTLC-timeout and HTLC-success Transactions](#htlc-timeout-and-htlc-success-transactions) + * [Legacy Closing Transaction](#legacy-closing-transaction) * [Closing Transaction](#closing-transaction) * [Fees](#fees) * [Fee Calculation](#fee-calculation) @@ -349,7 +350,9 @@ The witness script for the output is: To spend this via penalty, the remote node uses a witness stack ` 1`, and to collect the output, the local node uses an input with nSequence `to_self_delay` and a witness stack ` 0`. -## Closing Transaction +## Legacy 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. @@ -390,6 +393,41 @@ 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. +The outputs are ordered as detailed in [Transaction Output Ordering](#transaction-output-ordering). + +The side with lesser funds can opt to omit their own output. + +* version: 2 +* locktime: `locktime` from the `closing_complete` message +* txin count: 1 + * `txin[0]` outpoint: `txid` and `output_index` of the channel output + * `txin[0]` sequence: 0xFFFFFFFD + * `txin[0]` script bytes: 0 + * `txin[0]` witness: `0 ` +* txout count: 1 or 2 + * The closer output: + * `txout` amount: + * 0 if the `scriptpubkey` starts with `OP_RETURN` + * otherwise 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: + * 0 if the `scriptpubkey` starts with `OP_RETURN` + * otherwise the final balance for the closee, rounded down to whole satoshis + * `txout` script: as specified in that closee's `scriptpubkey` in its `shutdown` message + +### 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. + - MUST set the output amount to 0 if the `scriptpubkey` is `OP_RETURN`. + ## Fees ### Fee Calculation @@ -513,6 +551,7 @@ Bitcoin Core defines the following dust thresholds: - pay to witness pubkey hash (p2wpkh): 294 satoshis - pay to witness script hash (p2wsh): 330 satoshis - unknown segwit versions: 354 satoshis +- `OP_RETURN` outputs: these are never dust The rationale of this calculation (implemented [here](https://github.com/bitcoin/bitcoin/blob/2aff9a36c352640a263e8b5de469710f7e80eb54/src/policy/policy.cpp#L28)) is explained in the following sections. diff --git a/09-features.md b/09-features.md index 45be48465..132f0c74a 100644 --- a/09-features.md +++ b/09-features.md @@ -30,28 +30,28 @@ The Context column decodes as follows: * `9`: presented in [BOLT 11](11-payment-encoding.md) invoices. * `B`: presented in the `allowed_features` field of a blinded path. -| Bits | Name | Description | Context | Dependencies | Link | -|-------|-----------------------------------|-----------------------------------------------------------|----------|---------------------------|-----------------------------------------------------------------------| -| 0/1 | `option_data_loss_protect` | ASSUMED | | | | -| 4/5 | `option_upfront_shutdown_script` | Commits to a shutdown scriptpubkey when opening channel | IN | | [BOLT #2][bolt02-open] | -| 6/7 | `gossip_queries` | Peer has useful gossip to share | | | | -| 8/9 | `var_onion_optin` | ASSUMED | | | | -| 10/11 | `gossip_queries_ex` | Gossip queries can include additional information | IN | | [BOLT #7][bolt07-query] | -| 12/13 | `option_static_remotekey` | ASSUMED | | | | -| 14/15 | `payment_secret` | Node supports `payment_secret` field | IN9 | | [Routing Onion Specification][bolt04] | -| 16/17 | `basic_mpp` | Node can receive basic multi-part payments | IN9 | `payment_secret` | [BOLT #4][bolt04-mpp] | -| 18/19 | `option_support_large_channel` | Can create large channels | IN | | [BOLT #2](02-peer-protocol.md#the-open_channel-message) | -| 22/23 | `option_anchors` | Anchor commitment type with zero fee HTLC transactions | IN | | [BOLT #3][bolt03-htlc-tx], [lightning-dev][ml-sighash-single-harmful] | -| 24/25 | `option_route_blinding` | Node supports blinded paths | IN9 | | [BOLT #4][bolt04-route-blinding] | -| 26/27 | `option_shutdown_anysegwit` | Future segwit versions allowed in `shutdown` | IN | | [BOLT #2][bolt02-shutdown] | -| 28/29 | `option_dual_fund` | Use v2 of channel open, enables dual funding | IN | | [BOLT #2](02-peer-protocol.md) | -| 34/35 | `option_quiesce` | Support for `stfu` message | IN | | [BOLT #2][bolt02-quiescence] | -| 38/39 | `option_onion_messages` | Can forward onion messages | IN | | [BOLT #7](04-onion-routing.md#onion-messages) | -| 44/45 | `option_channel_type` | Node supports the `channel_type` field in open/accept | IN | | [BOLT #2](02-peer-protocol.md#the-open_channel-message) | -| 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] | - +| Bits | Name | Description | Context | Dependencies | Link | +|-------|-----------------------------------|-----------------------------------------------------------|----------|-----------------------------|-----------------------------------------------------------------------| +| 0/1 | `option_data_loss_protect` | ASSUMED | | | | +| 4/5 | `option_upfront_shutdown_script` | Commits to a shutdown scriptpubkey when opening channel | IN | | [BOLT #2][bolt02-open] | +| 6/7 | `gossip_queries` | Peer has useful gossip to share | | | | +| 8/9 | `var_onion_optin` | ASSUMED | | | | +| 10/11 | `gossip_queries_ex` | Gossip queries can include additional information | IN | | [BOLT #7][bolt07-query] | +| 12/13 | `option_static_remotekey` | ASSUMED | | | | +| 14/15 | `payment_secret` | Node supports `payment_secret` field | IN9 | | [Routing Onion Specification][bolt04] | +| 16/17 | `basic_mpp` | Node can receive basic multi-part payments | IN9 | `payment_secret` | [BOLT #4][bolt04-mpp] | +| 18/19 | `option_support_large_channel` | Can create large channels | IN | | [BOLT #2](02-peer-protocol.md#the-open_channel-message) | +| 22/23 | `option_anchors` | Anchor commitment type with zero fee HTLC transactions | IN | | [BOLT #3][bolt03-htlc-tx], [lightning-dev][ml-sighash-single-harmful] | +| 24/25 | `option_route_blinding` | Node supports blinded paths | IN9 | | [BOLT #4][bolt04-route-blinding] | +| 26/27 | `option_shutdown_anysegwit` | Future segwit versions allowed in `shutdown` | IN | | [BOLT #2][bolt02-shutdown] | +| 28/29 | `option_dual_fund` | Use v2 of channel open, enables dual funding | IN | | [BOLT #2](02-peer-protocol.md) | +| 34/35 | `option_quiesce` | Support for `stfu` message | IN | | [BOLT #2][bolt02-quiescence] | +| 38/39 | `option_onion_messages` | Can forward onion messages | IN | | [BOLT #7](04-onion-routing.md#onion-messages) | +| 44/45 | `option_channel_type` | Node supports the `channel_type` field in open/accept | IN | | [BOLT #2](02-peer-protocol.md#the-open_channel-message) | +| 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] | ## Requirements @@ -96,6 +96,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-quiescence]: 02-peer-protocol.md#channel-quiescence