From 094a86ecdbb3d8bc4a52c19cfc11ba86c43ef1c9 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 3 Jul 2017 12:16:37 +0930 Subject: [PATCH] BOLT 2: rework and specify exact shutdown retransmission semantics. 1. Change descriptions of closing tx construction to references to BOLT 3. 2. Recipient *should* check the fee offer has improved in closing_signed. 3. Therefore, sender *must* improve closing offer. 4. Offers do not persist across reconnection, so no state req'd, and also helps if fee has changed. 5. You don't need to re-send `shutdown` if you received `closing_signed` (implicit acknowledgement). 6. You don't have to accept a `channel_reestablish` which requests the last revoke_and_ack be retransmitted if you've already received `closing_signed` (which is an implicit acknowledgement). Closes: #201 Closes: #199 Signed-off-by: Rusty Russell --- 02-peer-protocol.md | 64 ++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 529597d..ee6a79d 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -414,38 +414,34 @@ 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 sign and broadcast the final closing transaction and MAY close the connection. + +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 disconnection and reconnection, 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 @@ -980,7 +976,7 @@ last `commitment_signed` message the receiving node has sent, it SHOULD fail the channel. If `next_remote_revocation_number` is equal to the commitment number of -the last `revoke_and_ack` the receiving node has sent, it MUST re-send +the last `revoke_and_ack` the receiving node has sent and the receiving node has not already received a `closing_signed`, it MUST re-send the `revoke_and_ack`, otherwise if `next_remote_revocation_number` is not equal to one greater than the commitment number of the last `revoke_and_ack` the receiving node has sent (or equal to zero if none have been sent), it SHOULD fail the channel. @@ -992,9 +988,9 @@ transaction is broadcast by the other side at any time. This is particularly important if a node does not simply retransmit the exact 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`. +On reconnection if the node has sent a previous `closing_signed` it +MUST send another `closing_signed`, otherwise if the node +has sent a previous `shutdown` it MUST retransmit it. ### Rationale @@ -1011,8 +1007,11 @@ polite to retransmit before disconnecting again, but it's not a MUST 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. +`closing_signed` has no acknowledgment, so must be transmitted again +on reconnect (though negotiation restarts on reconnection, so it need +not be an exact retransmission). The only acknowledgment for +`shutdown` is `closing_signed`, so that needs to always be retransmitted +unless `closing_signed` is. The handling of updates is similarly atomic: if the commit is not acknowledged (or wasn't sent) the updates are re-sent. However, we @@ -1023,6 +1022,11 @@ write to disk by the sender upon each transmission, whereas the scheme here encourages a single persistent write to disk for each `commitment_signed` sent or received. +We should never be asked to retransmit `revoke_and_ack` if we've +received a `closing_signed`, since that implies we've completed +shutdown which can only happen once the `revoke_and_ack` was received +by the remote node. + Note that the `next_local_commitment_number` starts at 1 since commitment number 0 is created during opening. `next_remote_revocation_number` will be 0 until the