From 2b3990694dc9d515a98fc13bff7844fea3e0af65 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 6 Jan 2017 09:24:51 +1030 Subject: [PATCH 1/2] BOLT 2: allow more leniancy with forks during channel establishment. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Christoper points out that two nodes with aggressive minimum-depth settings may see different blocks and the protocol requires they close the channel since their funding_locked messages will disagree. This can also happen when only one side has an aggressive minimum-depth setting: if it sends funding_locked referring to a block which is orphaned, it can't update it. There are three changes here, two optional. - Allow sending of an updated funding_locked. This fixes this case where one side is on an orphan and uses a v. low minimum-depth. - Require accepting of an updated funding_locked. - Allow waiting instead of immediate failure if funding_lock disagrees. eg. you might wait another block or two to see if one side reorgs. Reported-by: Christopher Jämthagen Closes: #73 Signed-off-by: Rusty Russell --- 02-peer-protocol.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 972dc5e14..8f56b7a80 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -263,14 +263,20 @@ The sender MUST wait until the funding transaction has reached `minimum-depth` before sending this message. The sender MUST encode the block position of the funding transaction into `channel-id`. If the sender has already received `funding_locked` from the other node, -it MUST fail the channel if its own `channel-id` does not match the -received. The sender MUST set `next-per-commitment-point` to the +it MAY fail the channel if its own `channel-id` does not match the +received: otherwise it MUST ignore the `funding_locked` message. +The sender MAY re-transmit `funding_locked` if the `channel-id` changes. + +The sender MUST set `next-per-commitment-point` to the per-commitment point to be used for the following commitment transaction, derived as specified in [BOLT #3](03-transactions.md#per-commitment-secret-requirements). -If the recipient has already sent `funding_locked` it MUST fail the -channel if `channel-id` does not match the `channel-id` it sent. +If the recipient has already sent `funding_locked` it MAY fail the +channel if `channel-id` does not match the `channel-id` it sent, +otherwise it SHOULD ignore the `funding_locked` message. If the +recipient has received previous `funding_locked` message, it MUST +ignore it in favor of the new `funding_locked`. The sender MUST set `announcement-node-signature` and `announcement-bitcoin-signature` to the signatures for the `channel_announcement` message, or all zeroes if it does not want the @@ -280,6 +286,18 @@ The recipient SHOULD fail the channel if the `announcement-node-signature` and ` The recipient SHOULD queue the `channel_announcement` message for its peers if it has sent and received a non-zero `announcement-node-signature` and `announcement-bitcoin-signature`. +#### Rationale + +If the `minimum-depth` is very low (such as 1), it's possible that +both nodes see different blocks containing the transaction: current +evidence suggests that this would happen once every three days. Thus +we allow implementations to retransmit in this case, and even wait for +such retransmissions in the case where both `minimum-depth` were too +low for a canonical answer. + +Such waiting is optional, as it is extremely unlikely for +`minimum-depth` values of 2 or more. + #### Future We could add an SPV proof, and route block hashes in separate From 83e04bf1cf718fe2732adecf6717f31594a65cab Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 9 Jan 2017 10:28:30 +1030 Subject: [PATCH 2/2] FIX: require retransmission if we're allowing timeouts. Otherwise we'd deadlock until one side timed out. Reported-by: Christian Decker Signed-off-by: Rusty Russell --- 02-peer-protocol.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 8f56b7a80..03585fc86 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -263,20 +263,25 @@ The sender MUST wait until the funding transaction has reached `minimum-depth` before sending this message. The sender MUST encode the block position of the funding transaction into `channel-id`. If the sender has already received `funding_locked` from the other node, -it MAY fail the channel if its own `channel-id` does not match the -received: otherwise it MUST ignore the `funding_locked` message. -The sender MAY re-transmit `funding_locked` if the `channel-id` changes. +and its own `channel-id` does not match that received, it MUST either +fail the channel or ignore the `funding_locked` message. If it +ignores the `funding_locked` message it MUST re-transmit +`funding_locked` if the `channel-id` changes, otherwise it MAY +re-transmit `funding_locked` if the `channel-id` changes. The sender MUST set `next-per-commitment-point` to the per-commitment point to be used for the following commitment transaction, derived as specified in [BOLT #3](03-transactions.md#per-commitment-secret-requirements). -If the recipient has already sent `funding_locked` it MAY fail the -channel if `channel-id` does not match the `channel-id` it sent, -otherwise it SHOULD ignore the `funding_locked` message. If the -recipient has received previous `funding_locked` message, it MUST -ignore it in favor of the new `funding_locked`. +If the recipient has already sent `funding_locked` with `channel-id` +which does not match the `channel-id` it sent, it MUST either fail the +channel or ignore the `funding_locked` message. If it +ignores the `funding_locked` message it MUST re-transmit +`funding_locked` if the `channel-id` changes, otherwise it MAY +re-transmit `funding_locked` if the `channel-id` changes. +If the recipient has received previous `funding_locked` message, it +MUST ignore it in favor of the new `funding_locked`. The sender MUST set `announcement-node-signature` and `announcement-bitcoin-signature` to the signatures for the `channel_announcement` message, or all zeroes if it does not want the @@ -291,9 +296,10 @@ peers if it has sent and received a non-zero `announcement-node-signature` and ` If the `minimum-depth` is very low (such as 1), it's possible that both nodes see different blocks containing the transaction: current evidence suggests that this would happen once every three days. Thus -we allow implementations to retransmit in this case, and even wait for -such retransmissions in the case where both `minimum-depth` were too -low for a canonical answer. +there are two modes: one in which we simply fail, should that happen, +and a more flexible mode in which nodes wait for updated +`funding_locked` if there's disagreement. In this mode, we require +that they send updates to avoid relying on timeouts. Such waiting is optional, as it is extremely unlikely for `minimum-depth` values of 2 or more.