Skip to content

Commit

Permalink
BOLT 2, 3: Remove older-style closes.
Browse files Browse the repository at this point in the history
They're in the git history if you need them.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
rustyrussell committed Jul 19, 2023
1 parent aa6deb8 commit 84c4487
Show file tree
Hide file tree
Showing 2 changed files with 0 additions and 174 deletions.
129 changes: 0 additions & 129 deletions 02-peer-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ operation, and closing.
* [The `channel_ready` Message](#the-channel_ready-message)
* [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)
Expand Down Expand Up @@ -571,20 +570,6 @@ 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 --------| |
| | | |
| | <complete all pending HTLCs> | |
| A | ... | B |
| | | |
| |--(3)-- closing_signed F1--->| |
| |<-(4)-- closing_signed F2----| |
| | ... | |
| |--(?)-- closing_signed Fn--->| |
| |<-(?)-- closing_signed Fn----| |
+-------+ +-------+

+-------+ +-------+
| |--(1)----- shutdown ------->| |
| |<-(2)----- shutdown --------| |
Expand Down Expand Up @@ -673,120 +658,6 @@ 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.

### Closing Negotiation: `closing_signed`

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, and closing fee
negotiation begins. The funder chooses a fee it thinks is fair, and
signs the closing transaction with the `scriptpubkey` fields from the
`shutdown` messages (along with its chosen fee) and sends the signature;
the other node then replies similarly, using a fee it thinks is fair. This
exchange continues until both agree on the same fee or when one side fails
the channel.

In the modern method, the funder sends its permissible fee range, and the
non-funder has to pick a fee in this range. If the non-funder chooses the same
value, negotiation is complete after two messages, otherwise the funder will
reply with the same value (completing after three messages).

1. type: 39 (`closing_signed`)
2. data:
* [`channel_id`:`channel_id`]
* [`u64`:`fee_satoshis`]
* [`signature`:`signature`]
* [`closing_signed_tlvs`:`tlvs`]

1. `tlv_stream`: `closing_signed_tlvs`
2. types:
1. type: 1 (`fee_range`)
2. data:
* [`u64`:`min_fee_satoshis`]
* [`u64`:`max_fee_satoshis`]

#### Requirements

The funding node:
- after `shutdown` has been received, AND no HTLCs remain in either commitment transaction:
- SHOULD send a `closing_signed` message.

The sending node:
- SHOULD set the initial `fee_satoshis` according to its estimate of cost of
inclusion in a block.
- SHOULD set `fee_range` according to the minimum and maximum fees it is
prepared to pay for a close transaction.
- if it doesn't receive a `closing_signed` response after a reasonable amount of time:
- MUST fail the channel
- if it is not the funder:
- SHOULD set `max_fee_satoshis` to at least the `max_fee_satoshis` received
- SHOULD set `min_fee_satoshis` to a fairly low value
- MUST set `signature` to the Bitcoin signature of the close transaction,
as specified in [BOLT #3](03-transactions.md#closing-transaction).

The receiving node:
- if the `signature` is not valid for either variant of closing transaction
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>:
- MUST send a `warning` and close the connection, or send an
`error` and fail the channel.
- if `fee_satoshis` is equal to its previously sent `fee_satoshis`:
- SHOULD sign and broadcast the final closing transaction.
- MAY close the connection.
- if `fee_satoshis` matches its previously sent `fee_range`:
- SHOULD use `fee_satoshis` to sign and broadcast the final closing transaction
- SHOULD reply with a `closing_signed` with the same `fee_satoshis` value if it is different from its previously sent `fee_satoshis`
- MAY close the connection.
- if the message contains a `fee_range`:
- if there is no overlap between that and its own `fee_range`:
- SHOULD send a warning
- MUST fail the channel if it doesn't receive a satisfying `fee_range` after a reasonable amount of time
- otherwise:
- if it is the funder:
- if `fee_satoshis` is not in the overlap between the sent and received `fee_range`:
- MUST fail the channel
- otherwise:
- MUST reply with the same `fee_satoshis`.
- otherwise (it is not the funder):
- if it has already sent a `closing_signed`:
- if `fee_satoshis` is not the same as the value it sent:
- MUST fail the channel
- otherwise:
- MUST propose a `fee_satoshis` in the overlap between received and (about-to-be) sent `fee_range`.
- otherwise, if `fee_satoshis` is not strictly between its last-sent `fee_satoshis`
and its previously-received `fee_satoshis`, UNLESS it has since reconnected:
- SHOULD send a `warning` and close the connection, or send an
`error` and fail the channel.
- otherwise, if the receiver agrees with the fee:
- SHOULD reply with a `closing_signed` with the same `fee_satoshis` value.
- otherwise:
- MUST propose a value "strictly between" the received `fee_satoshis`
and its previously-sent `fee_satoshis`.

The receiving node:
- if one of the outputs in the closing transaction is below the dust limit for its `scriptpubkey` (see [BOLT 3](03-transactions.md#dust-limits)):
- MUST fail the channel

#### Rationale

When `fee_range` is not provided, the "strictly between" requirement ensures
that forward progress is made, even if only by a single satoshi at a time.
To avoid keeping state and to handle the corner case, where fees have shifted
between disconnection and reconnection, negotiation restarts on reconnection.

Note there is limited risk if the closing transaction is
delayed, but it will be broadcast very soon; so there is usually no
reason to pay a premium for rapid processing.

Note that the non-funder is not paying the fee, so there is no reason for it
to have a maximum feerate. It may want a minimum feerate, however, to ensure
that the transaction propagates. It can always use CPFP later to speed up
confirmation if necessary, so that minimum should be low.

It may happen that the closing transaction doesn't meet bitcoin's default relay
policies (e.g. when using a non-segwit shutdown script for an output below 546
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
Expand Down
45 changes: 0 additions & 45 deletions 03-transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,53 +347,8 @@ 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`.

## 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.

* version: 2
* locktime: 0
* txin count: 1
* `txin[0]` outpoint: `txid` and `output_index` from `funding_created` message
* `txin[0]` sequence: 0xFFFFFFFF
* `txin[0]` script bytes: 0
* `txin[0]` witness: `0 <signature_for_pubkey1> <signature_for_pubkey2>`
* txout count: 0, 1 or 2
* `txout` amount: final balance to be paid to one node (minus `fee_satoshis` from `closing_signed`, if this peer funded the channel)
* `txout` script: as specified in that node'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 output to the funder.
- MUST remove any output below its own `dust_limit_satoshis`.
- MAY eliminate its own output.

### Rationale

There is a possibility of irreparable differences on closing if one
node considers the other's output too small to allow propagation on
the Bitcoin network (a.k.a. "dust"), and that other node instead
considers that output too valuable to discard. This is why each
side uses its own `dust_limit_satoshis`, and the result can be a
signature validation failure, if they disagree on what the closing
transaction should look like.

However, if one side chooses to eliminate its own output, there's no
reason for the other side to fail the closing protocol; so this is
explicitly allowed. The signature indicates which variant
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.
Expand Down

0 comments on commit 84c4487

Please sign in to comment.