Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closing tx detailed specification #201

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 25 additions & 26 deletions 02-peer-protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,38 +414,35 @@ The sender SHOULD set the initial `fee_satoshis` according to its
estimate of cost of inclusion in a block.

The sender MUST set `signature` to the Bitcoin signature of the close
transaction with the node responsible for paying the bitcoin fee
paying `fee_satoshis`, then removing any output which is below
its own `dust_limit_satoshis`. The sender MAY then also eliminate its own
output from the mutual close transaction.
transaction as specified in [BOLT #3](03-transactions.md#closing-transaction).

The receiver MUST check `signature` is valid for either the close
transaction with the given `fee_satoshis` as detailed above and its
own `dust_limit_satoshis` OR that same transaction with the sender's
output eliminated, and MUST fail the connection if it is not.
The receiver MUST check `signature` is valid for either variant of close
transaction specified in [BOLT #3](03-transactions.md#closing-transaction),
and MUST fail the connection if it is not.

If `fee_satoshis` is equal to its previously sent `fee_satoshis`, the receiver
SHOULD close the connection and SHOULD sign and broadcast the final closing
transaction.

Otherwise, the
recipient MUST fail the connection if `fee_satoshis` is greater than
the base fee of the final commitment transaction as calculated in
[BOLT #3](03-transactions.md#fee-calculation), and the
recipient SHOULD fail the connection if `fee_satoshis` is not strictly
between its last-sent `fee_satoshis` and its previously-received
`fee_satoshis`, unless it has reconnected since then.

If the receiver agrees with the fee, it SHOULD reply with a
`closing_signed` with the same `fee_satoshis` value, otherwise it
SHOULD propose a value strictly between the received `fee_satoshis`
MUST propose a value strictly between the received `fee_satoshis`
and its previously-sent `fee_satoshis`.

Once a node has sent or received a `closing_signed` with matching
`fee_satoshis` it SHOULD close the connection and SHOULD sign and
broadcast the final closing transaction.

#### 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 (aka "dust"), and that other node instead
considers that output to be 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 "strictly between" requirements ensure that we make forward
progress, even if only by a single satoshi at a time. To avoid
keeping state and handle the corner case where fees have shifted
between reconnections, negotiation restarts on reconnection.

Note that there is limited risk if the closing transaction is
delayed, and it will be broadcast very soon, so there is usually no
Expand Down Expand Up @@ -994,7 +991,7 @@ same `update_` messages as previously sent.

On reconnection if the node has sent a previous `shutdown` it MUST
retransmit it, and if the node has sent a previous `closing_signed` it
MUST then retransmit the last `closing_signed`.
MUST send another `closing_signed`.

### Rationale

Expand All @@ -1012,7 +1009,9 @@ because there are also occasions where a node can simply forget the
channel altogether.

There is similarly no acknowledgment for `closing_signed`, or
`shutdown`, so they are also retransmitted on reconnection.
`shutdown`, so they are also retransmitted on reconnection. In the
case of `closing_signed`, negotation restarts on reconnection, so it
need not be an exact retransmission.

The handling of updates is similarly atomic: if the commit is not
acknowledged (or wasn't sent) the updates are re-sent. However, we
Expand Down
39 changes: 39 additions & 0 deletions 03-transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,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)
* [Closing Transaction](#closing-transaction)
* [Fees](#fees)
* [Fee Calculation](#fee-calculation)
* [Fee Payment](#fee-payment)
Expand Down Expand Up @@ -234,6 +235,44 @@ 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

Note that there are two possible variants for each node.

* version: 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that version 2?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Roasbeef said version 1, since version 2 only needed for CLTV, which we don't need here. I don't really mind...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using version 1 here allow us to blend in a bit more with regular (non contract) traffic (assuming an eventual saturation of transactions spending segwit inputs).

* 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_key1> <signature_for_key2>`
* txout count: 0, 1 or 2
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In what case would having no transaction outputs be warranted or valid?

* `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.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BIP 69 should be used here as well. I'm assuming y'all already do so?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

### Requirements

Each node offering a signature MUST subtract the fee given by `fee_satoshis` from
the output to the funder; it MUST then remove any output below its own `dust_limit_satoshis`, and MAY also 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 (aka "dust"), and that other node instead
considers that output to be 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 will indicate which variant
has been used.

There will be at least one output if `dust_limit_satoshis` is greater
than twice the funding amount.

## Fees

### Fee Calculation
Expand Down