diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 27b01fe04..205772803 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) @@ -1507,19 +1508,85 @@ Closing happens in two stages: 1. one side indicates it wants to clear the channel (and thus will accept no new HTLCs) 2. once all HTLCs are resolved, the final channel close negotiation begins. - +-------+ +-------+ - | |--(1)----- shutdown ------->| | - | |<-(2)----- shutdown --------| | - | | | | - | | | | - | A | ... | B | - | | | | - | |--(3)-- closing_signed F1--->| | - | |<-(4)-- closing_signed F2----| | - | | ... | | - | |--(?)-- closing_signed Fn--->| | - | |<-(?)-- closing_signed Fn----| | - +-------+ +-------+ + +-------+ +-------+ + | | shutdown(scriptA1) | | + | |--------------------------------------------------------->| | + | | shutdown(scriptB1) | | + | |<---------------------------------------------------------| | + | | | | + | | | | + | A | .... | B | + | | | | + | | closing_complete(scriptA1, scriptB1, 1000 sat) | | + | |--------------------------------------------------------->| | + | | closing_complete(scriptB1, scriptA1, 750 sat) | | + | |<---------------------------------------------------------| | + | | closing_sig(scriptA1, scriptB1, 1000 sat) | | + | |<---------------------------------------------------------| | + | | closing_sig(scriptB1, scriptA1, 750 sat) | | + | |--------------------------------------------------------->| | + | | | | + | | | | + | | | | + | | closing_complete(scriptA2, scriptB1, 1100 sat) | | + | |--------------------------------------------------------->| | + | | closing_sig(scriptA2, scriptB1, 1100 sat) | | + | |<---------------------------------------------------------| | + | | | | + | | .... | | + | | | | + | | | | + | | | | + | | closing_complete(scriptB1, scriptA2, 850 sat) | | + | |<---------------------------------------------------------| | + | | closing_sig(scriptB1, scriptA2, 850 sat) | | + | |--------------------------------------------------------->| | + | | | | + | | .... | | + | | | | + | | | | (*) Note that this is a very rare race condition + | | | | + | | closing_complete(scriptA3, scriptB1, 1250 sat) | | + | |-----------------------------> | | + | | closing_complete(scriptB2, scriptA2, 900 sat) | | + | | <--------------------------------------| | + | | closing_complete | | + | | --------------------------->| | + | | warning | | (*) B sends a warning because A is not using scriptB2 + | | <--------------------------------------| | + | | closing_complete | | + | |<------------------ | | + | | warning | | (*) A sends a warning because B is not using scriptA3 + | |--------------------------------------------------------->| | + | | warning | | + | |<------------------ | | + | | | | + | | | | (*) A and B reconnect to resolve the race condition + | | | | + | | channel_reestablish | | + | |--------------------------------------------------------->| | + | | channel_reestablish | | + | |<---------------------------------------------------------| | + | | shutdown(scriptA3) | | + | |--------------------------------------------------------->| | + | | shutdown(scriptB2) | | + | |<---------------------------------------------------------| | + | | | | + | | | | + | | | | + | | closing_complete(scriptA3, scriptB2, 1250 sat) | | + | |--------------------------------------------------------->| | + | | closing_sig(scriptA3, scriptB2, 1250 sat) | | + | |<---------------------------------------------------------| | + | | | | + | | | | + | | | | + | | closing_complete(scriptB2, scriptA3, 900 sat) | | + | |<---------------------------------------------------------| | + | | closing_sig(scriptB2, scriptA3, 900 sat) | | + | |--------------------------------------------------------->| | + | | | | + +-------+ +-------+ ### Closing Initiation: `shutdown` @@ -1555,6 +1622,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 +1784,190 @@ 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 creates their own closing transaction where they pay the fee, and sends +`closing_complete` to the other peer with the transaction details. The other peer +simply signs that transaction and sends back `closing_sig`. Each peer will thus +independently send `closing_complete` and receive `closing_sig`, resulting in two +independent (but conflicting) closing transactions being created. + +The lesser-paid peer (if either is) can opt to omit their own output from the +closing transaction. + +This process can be repeated multiple times by sending `closing_complete` again, +which allows increasing the fees and changing the output script. + +1. type: 40 (`closing_complete`) +2. data: + * [`channel_id`:`channel_id`] + * [`u16`:`closer_scriptpubkey_len`] + * [`closer_scriptpubkey_len*byte`:`closer_scriptpubkey`] + * [`u16`:`closee_scriptpubkey_len`] + * [`closee_scriptpubkey_len*byte`:`closee_scriptpubkey`] + * [`u64`:`fee_satoshis`] + * [`u32`:`locktime`] + * [`closing_tlvs`:`tlvs`] + +1. type: 41 (`closing_sig`) +2. data: + * [`channel_id`:`channel_id`] + * [`u16`:`closer_scriptpubkey_len`] + * [`closer_scriptpubkey_len*byte`:`closer_scriptpubkey`] + * [`u16`:`closee_scriptpubkey_len`] + * [`closee_scriptpubkey_len*byte`:`closee_scriptpubkey`] + * [`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`] + +#### 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. + +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 set `closer_scriptpubkey` to its desired output script. + - MUST set `closee_scriptpubkey` to the last script it received from its peer (from `closing_complete` or from the initial `shutdown`). + - MUST set `locktime` to the desired `nLockTime` of the closing transaction. + - 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 `closer_scriptpubkey` is not `OP_RETURN`. + - Otherwise (not lesser amount, cannot remove its own output): + - MUST NOT set `closee_output_only`. + - If it considers the local output amount uneconomical: + - MAY send a `closer_scriptpubkey` that is a valid `OP_RETURN` script. + - If it does, the output value MUST be set to zero so that all funds go to fees, as specified in [BOLT #3](03-transactions.md#closing-transaction). + - If the closee's output amount is dust: + - MUST set `closer_output_only`. + - MUST NOT set `closer_and_closee_outputs`. + - Otherwise: + - MUST set both `closer_output_only` and `closer_and_closee_outputs`. + - MUST generate its closing transaction as specified in [BOLT #3](03-transactions.md#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 it wants to send another `closing_complete` (e.g. with a different `fee_satoshis` or `closer_scriptpubkey`): + - MUST wait until it has received `closing_sig` first. + - SHOULD close the connection if it doesn't receive `closing_sig`. + +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. + - If `closee_scriptpubkey` does not match the last script it sent (from `closing_complete` or from the initial `shutdown`): + - SHOULD ignore `closing_complete`. + - SHOULD send a `warning`. + - SHOULD close the connection. + - If `closer_scriptpubkey` is invalid (as detailed in the [`shutdown` requirements](#closing-initiation-shutdown)): + - SHOULD ignore `closing_complete`. + - SHOULD send a `warning`. + - SHOULD close the connection. + - If `closer_scriptpubkey` is a valid `OP_RETURN` script: + - MUST set the closer's output amount to zero so that all funds go to fees, as specified in [BOLT #3](03-transactions.md#closing-transaction). + - MUST generate the remote closing transaction as specified in [BOLT #3](03-transactions.md#closing-transaction). + - 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 `closee_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 either send a `warning` and close the connection, or send an `error` and fail the channel. + - 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`. + - MUST use `closer_scriptpubkey` for its own future `closing_complete` messages. + +The receiver of `closing_sig`: + - If `closer_scriptpubkey`, `closee_scriptpubkey`, `fee_satoshis` or `locktime` don't match what was sent in `closing_complete`: + - MUST either send a `warning` and close the connection, or send an `error` and fail the channel. + - 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 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 either send a `warning` and close the connection, or send an `error` and fail the channel. + - 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 broadcast the corresponding closing transaction. + - MAY send another `closing_complete` (e.g. with a different `fee_satoshis` or `closer_scriptpubkey`). + +### 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 `closing_complete` +again. + +Sending a new `closing_complete` message overrides previous ones, so you can negotiate again (even +changing the output address if `upfront_shutdown_script` was not negotiated). This creates a rare +race condition if both nodes send `closing_complete` to change their `closer_scriptpubkey` at the +same time: when that happens, the `closing_complete` they receive will be using their previous +output script, so they shouldn't sign the corresponding transaction. When that happens, we simply +reconnect, which provides the opportunity for both nodes to send their latest output script in +`shutdown` and restart the signing flow. We include the closer and closee scripts in `closing_sig` +to allow our peer to detect a script mismatch and correctly ignore the signatures, which also +helps debugging race conditions. + +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..7052acd1e 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 `closer_scriptpubkey` from the `closing_complete` 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 `closee_scriptpubkey` from the `closing_complete` 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 e1679a6c9..5aa651b55 100644 --- a/09-features.md +++ b/09-features.md @@ -30,29 +30,29 @@ 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) | -| 42/43 | `option_provide_storage` | Can store other nodes' encrypted backup data | IN | | [BOLT #1](01-messaging.md#peer-storage) | -| 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) | +| 42/43 | `option_provide_storage` | Can store other nodes' encrypted backup data | IN | | [BOLT #1](01-messaging.md#peer-storage) | +| 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 @@ -97,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-quiescence]: 02-peer-protocol.md#channel-quiescence