From fbf2b5e0c40f05a3d198bbada05a0f6996ac647e 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 | 65 ++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 529597d88..e1ad20888 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -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 @@ -980,7 +977,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 +989,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 +1008,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 acknowledgement, so must be transmitted again +on reconnect (though negotation 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 +1023,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