From 4af8e1841151f0c6e8151979d6c89d11839b2f65 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 2 Mar 2017 14:50:13 +1030 Subject: [PATCH] BOLT 0,1,2,7: use txout not channel-id for demuxing. (#119) At cost of a few extra bytes between peers, this avoids the whole "oops, we were on a chain fork" problem, and simplifies generation of temporary channel-ids (just pick a random one). Now we move the announcement_signature exchange to at least 6 confirms, which makes re-xmit tricky; I resolved that by insisting on reconnect that we send if we haven't received, and reply to the first one. The term "channel shortid" wasn't used anywhere, so I removed it; it's now a gossip-only thing anyway. One subtle change: pkt_error on unknown channels is now "MUST ignore"; this section was reworked anyway, and we'll want this if the #120 goes through, where one side might have forgotten unformed channels). Closes: #114 Suggested-by: Olaoluwa Osuntokun Signed-off-by: Rusty Russell * FIXUP! Two bytes for funding-output-index. Signed-off-by: Rusty Russell * FIXUP! Channel-id rework, temp ids, 32 bits only. Re-add the idea of temporary channel ids: far simpler since they're now big enough we can just fill with noise. Remove the alignment issues by combining txid and outnum using XOR; we could reduce to 128 bit if we really wanted to, but we don't. Error handling is now simple again, but while editing I changed the behaviour for unknown channels to MUST ignore (this is important for Change the 8-byte gossip channel id to `short-channel-id`. Signed-off-by: Rusty Russell * FIXUP! Minor text tweaks from Pierre-Marie and Christian Signed-off-by: Rusty Russell --- 00-introduction.md | 4 -- 01-messaging.md | 13 ++++--- 02-peer-protocol.md | 90 ++++++++++++++------------------------------ 07-routing-gossip.md | 34 ++++++++++++----- 4 files changed, 59 insertions(+), 82 deletions(-) diff --git a/00-introduction.md b/00-introduction.md index f1b2fa0..5648089 100644 --- a/00-introduction.md +++ b/00-introduction.md @@ -103,10 +103,6 @@ This is version 0. are independent for each peer in the channel, and start at 0. -* *Channel shortid*: - * An 8 byte globally unique identifier for the *funding transaction* - (and thus for the channel). - * *It's ok to be odd*: * A rule applied to some numeric fields that indicates optional and compulsory support for features. Even numbers indicate that both endpoints diff --git a/01-messaging.md b/01-messaging.md index 5134117..150740d 100644 --- a/01-messaging.md +++ b/01-messaging.md @@ -119,7 +119,7 @@ For simplicity of diagnosis, it is often useful to tell the peer that something 1. type: 17 (`error`) 2. data: - * [8:channel-id] + * [32:channel-id] * [2:len] * [len:data] @@ -127,16 +127,17 @@ The 2-byte `len` field indicates the number of bytes in the immediately followin #### Requirements +The channel is referred to by `channel-id` unless `channel-id` is zero (ie. all bytes zero), in which case it refers to all channels. + A node SHOULD send `error` for protocol violations or internal errors which make channels unusable or further communication unusable. A node MAY send an empty [data] field. A node sending `error` MUST -fail the channel referred to by the `channel-id`, or if `channel-id` -is `0xFFFFFFFFFFFFFFFF` it MUST fail all channels and MUST close the connection. +fail the channel referred to by the error message, or if `channel-id` is zero, it MUST +fail all channels and MUST close the connection. A node MUST set `len` equal to the length of `data`. A node SHOULD include the raw, hex-encoded transaction in reply to a `funding_created`, `funding_signed`, `closing_signed` or `commitment_signed` message when failure was caused by an invalid signature check. -A node receiving `error` MUST fail the channel referred to by -`channel-id`, or if `channel-id` is `0xFFFFFFFFFFFFFFFF` it MUST fail -all channels and MUST close the connection. A receiving node MUST truncate +A node receiving `error` MUST fail the channel referred to by the message, +or if `channel-id` is zero, it MUST fail all channels and MUST close the connection. If no existing channel is referred to by the message, the receiver MUST ignore the message. A receiving node MUST truncate `len` to the remainder of the packet if it is larger. A receiving node SHOULD only print out `data` verbatim if the string is composed solely of printable ASCII characters. diff --git a/02-peer-protocol.md b/02-peer-protocol.md index ccdcb36..7dcad78 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -70,6 +70,10 @@ If this fails at any stage, or a node decides that the channel terms offered by the other node are not suitable, the channel establishment fails. +Note that multiple channels can operate in parallel, as all channel +messages are identified by either a `temporary-channel-id` (before the +funding transaction is created) or `channel-id` derived from the +funding transaction. ### The `open_channel` message @@ -79,7 +83,7 @@ desire to set up a new channel. 1. type: 32 (`open_channel`) 2. data: - * [8:temporary-channel-id] + * [32:temporary-channel-id] * [8:funding-satoshis] * [8:push-msat] * [8:dust-limit-satoshis] @@ -96,7 +100,7 @@ desire to set up a new channel. * [33:first-per-commitment-point] -The `temporary-channel-id` is used to identify this channel until the funding transaction is established. `funding-satoshis` is the amount the sender is putting into the channel. `dust-limit-satoshis` is the threshold below which output should be generated for this node's commitment or HTLC transaction; ie. HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain. This reflects the reality that tiny outputs are not considered standard transactions and will not propagate through the Bitcoin network. +The `temporary-channel-id` is used to identify this channel until the funding transaction is established. `funding-satoshis` is the amount the sender is putting into the channel. `dust-limit-satoshis` is the threshold below which output should be generated for this node's commitment or HTLC transaction; ie. HTLCs below this amount plus HTLC transaction fees are not enforceable on-chain. This reflects the reality that tiny outputs are not considered standard transactions and will not propagate through the Bitcoin network. `max-htlc-value-in-inflight-msat` is a cap on total value of outstanding HTLCs, which allows a node to limit its exposure to HTLCs; similarly `max-accepted-htlcs` limits the number of outstanding HTLCs the other node can offer. `channel-reserve-satoshis` is the minimum amount that the other node is to keep as a direct payment. `htlc-minimum-msat` indicates the smallest value HTLC this node will accept. @@ -110,8 +114,7 @@ FIXME: Describe Dangerous feature bit for larger channel amounts. #### Requirements -A sending node MUST set the most significant bit in -`temporary-channel-id`, and MUST ensure it is unique from any other +A sending node MUST ensure `temporary-channel-id` is unique from any other channel id with the same peer. The sender MUST set `funding-satoshis` to less than 2^24 satoshi. The sender MUST set `push-msat` to equal or less than to 1000 * `funding-satoshis`. The sender SHOULD set `to-self-delay` sufficient to ensure the sender @@ -178,7 +181,7 @@ acceptance of the new channel. 1. type: 33 (`accept_channel`) 2. data: - * [8:temporary-channel-id] + * [32:temporary-channel-id] * [8:dust-limit-satoshis] * [8:max-htlc-value-in-flight-msat] * [8:channel-reserve-satoshis] @@ -209,20 +212,20 @@ signature, it will broadcast the funding transaction. 1. type: 34 (`funding_created`) 2. data: - * [8:temporary-channel-id] - * [32:txid] - * [1:output-index] + * [32:temporary-channel-id] + * [32:funding-txid] + * [2:funding-output-index] * [64:signature] #### Requirements -The sender MUST set `temporary-channel-id` the same as the `temporary-channel-id` in the `open_channel` message. The sender MUST set `txid` to the transaction ID of a non-malleable transaction, which it MUST NOT broadcast, and MUST set `output-index` to the output number of that transaction which corresponds the funding transaction output as defined in [BOLT #3](03-transactions.md#funding-transaction-output), and MUST set `signature` to the valid signature using its `funding-pubkey` for the initial commitment transaction as defined in [BOLT #3](03-transactions.md#commitment-transaction). +The sender MUST set `temporary-channel-id` the same as the `temporary-channel-id` in the `open_channel` message. The sender MUST set `funding-txid` to the transaction ID of a non-malleable transaction, which it MUST NOT broadcast, and MUST set `funding-output-index` to the output number of that transaction which corresponds the funding transaction output as defined in [BOLT #3](03-transactions.md#funding-transaction-output), and MUST set `signature` to the valid signature using its `funding-pubkey` for the initial commitment transaction as defined in [BOLT #3](03-transactions.md#commitment-transaction). The recipient MUST fail the channel if `signature` is incorrect. #### Rationale -The `output-index` can only be 1 byte, since that's how we'll pack it into the channel-id used throughout the protocol. The limit of 255 outputs should not be overly burdensome. +The `funding-output-index` can only be 2 bytes, since that's how we'll pack it into the channel-id used throughout the gossip protocol. The limit of 65535 outputs should not be overly burdensome. ### The `funding_signed` message @@ -230,14 +233,16 @@ This message gives the funder the signature they need for the first commitment transaction, so they can broadcast it knowing they can redeem their funds if they need to. +This message introduces the `channel-id` which identifies , which is derived from the funding transaction by combining the `funding-txid` and the `funding-output-index` using big-endian exclusive-OR (ie. `funding-output-index` alters the last two bytes). + 1. type: 35 (`funding_signed`) 2. data: - * [8:temporary-channel-id] + * [32:channel-id] * [64:signature] #### Requirements -The sender MUST set `temporary-channel-id` the same as the `temporary-channel-id` in the `open_channel` message, and MUST set `signature` to the valid signature using its `funding-pubkey` for the initial commitment transaction as defined in [BOLT #3](03-transactions.md#commitment-transaction). +The sender MUST set `channel-id` by exclusive-OR of the `funding-txid` and the `funding-output-index` from the `funding_created` message, and MUST set `signature` to the valid signature using its `funding-pubkey` for the initial commitment transaction as defined in [BOLT #3](03-transactions.md#commitment-transaction). The recipient MUST fail the channel if `signature` is incorrect. @@ -247,58 +252,19 @@ This message indicates that the funding transaction has reached the `minimum-dep 1. type: 36 (`funding_locked`) 2. data: - * [8:temporary-channel-id] - * [8:channel-id] + * [32:channel-id] * [33:next-per-commitment-point] -The `channel-id` is the unique description of the funding transaction. -It is constructed with the most significant 3 bytes as the block -height, the next 3 bytes indicating the transaction index within the -block, and the least significant two bytes indicating the output -index which pays to the channel. - -This `channel-id` is used in all messages referring to the channel -from this point onwards. - #### Requirements 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, -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. +`minimum-depth` before sending this message. 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` 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`. - -#### 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 -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. - #### Future We could add an SPV proof, and route block hashes in separate @@ -338,7 +304,7 @@ and indicating the scriptpubkey it wants to be paid to. 1. type: 38 (`shutdown`) 2. data: - * [8:channel-id] + * [32:channel-id] * [2:len] * [len:scriptpubkey] @@ -391,7 +357,7 @@ the channel. 1. type: 39 (`closing_signed`) 2. data: - * [8:channel-id] + * [32:channel-id] * [8:fee-satoshis] * [64:signature] @@ -563,7 +529,7 @@ is destined, is described in [BOLT #4](04-onion-routing.md). 1. type: 128 (`update_add_htlc`) 2. data: - * [8:channel-id] + * [32:channel-id] * [8:id] * [4:amount-msat] * [4:cltv-expiry] @@ -642,7 +608,7 @@ it into a `update_fail_htlc` for relaying. 1. type: 130 (`update_fulfill_htlc`) 2. data: - * [8:channel-id] + * [32:channel-id] * [8:id] * [32:payment-preimage] @@ -650,7 +616,7 @@ For a timed out or route-failed HTLC: 1. type: 131 (`update_fail_htlc`) 2. data: - * [8:channel-id] + * [32:channel-id] * [8:id] * [2:len] * [len:reason] @@ -659,7 +625,7 @@ For a unparsable HTLC: 1. type: 135 (`update_fail_malformed_htlc`) 2. data: - * [8:channel-id] + * [32:channel-id] * [8:id] * [32:sha256-of-onion] * [2:failure-code] @@ -721,7 +687,7 @@ sign the resulting transaction as defined in [BOLT #3](03-transactions.md) and s 1. type: 132 (`commit_sig`) 2. data: - * [8:channel-id] + * [32:channel-id] * [64:signature] * [2:num-htlcs] * [num-htlcs*64:htlc-signature] @@ -782,7 +748,7 @@ The description of key derivation is in [BOLT #3](03-transactions.md#key-derivat 1. type: 133 (`revoke_and_ack`) 2. data: - * [8:channel-id] + * [32:channel-id] * [32:per-commitment-secret] * [33:next-per-commitment-point] * [1:padding] @@ -833,7 +799,7 @@ given in [BOLT #3](03-transactions.md#fee-calculation). 1. type: 134 (`update_fee`) 2. data: - * [8:channel-id] + * [32:channel-id] * [4:feerate-per-kw] #### Requirements diff --git a/07-routing-gossip.md b/07-routing-gossip.md index e45469f..9dbdca0 100644 --- a/07-routing-gossip.md +++ b/07-routing-gossip.md @@ -19,16 +19,30 @@ It contains the necessary signatures by the sender to construct the `channel_ann 1. type: 259 (`announcement_signatures`) 2. data: - * [8:channel-id] + * [32:channel-id] + * [8:short-channel-id] * [64:node-signature] * [64:bitcoin-signature] The willingness of the endpoints to announce the channel is signaled during the connection setup by setting a `channels_public` bit in the `localfeatures` field. -Should both endpoints have signaled that they'd like to publish the channel then the `announcement_signatures` message MUST directly sent following the `funding_locked` message that established the corresponding channel. + +### Requirements + +If both endpoints have signaled that they'd like to publish the channel then the `announcement_signatures` message MUST be sent, otherwise they MUST NOT be sent. + +If sent, `announcement_signatures` messages MUST NOT be sent until `funding_locked` has been sent, and the funding transaction is has at least 6 confirmations. + +The `short-channel-id` is the unique description of the funding transaction. +It is constructed with the most significant 3 bytes as the block +height, the next 3 bytes indicating the transaction index within the +block, and the least significant two bytes indicating the output +index which pays to the channel. + The `announcement_signatures` message is created by constructing a `channel_announcement` message corresponding to the newly established channel, and sign it with the secrets matching their `node-id` and `bitcoin-key`, and send them using an `announcement_signatures`. The recipient MAY fail the channel if the `node-signature` or `bitcoin-signature` is incorrect. The recipient SHOULD queue the `channel_announcement` message for its peers if it has sent and received a valid `announcement_signatures` message. -If either endpoints does not signal `channels_public` then `announcement_signatures` MUST NOT be sent. + +On reconnection, a node SHOULD retransmit the `announcement_signatures` message if it has not received an `announcement_signatures` message, and MUST respond to the first `announcement_signatures` message after reconnection with its own `announcement_signatures` message. ## The `channel_announcement` message @@ -47,7 +61,7 @@ In order to prove the existence of channel between `node-1` and The first one is done by assuming that all nodes know the unspent transaction outputs, and thus can find the output given by -`channel-id` and validate that it is indeed a P2WSH funding +`short-channel-id` and validate that it is indeed a P2WSH funding transaction output as to those keys specified in [BOLT #3](03-transactions.md#funding-transaction-output). @@ -66,7 +80,7 @@ announcement message; that is done by having a signature from each * [64:node-signature-2] * [64:bitcoin-signature-1] * [64:bitcoin-signature-2] - * [8:channel-id] + * [8:short-channel-id] * [33:node-id-1] * [33:node-id-2] * [33:bitcoin-key-1] @@ -76,7 +90,7 @@ announcement message; that is done by having a signature from each ### Requirements -The creating node MUST set `channel-id` to refer to the confirmed +The creating node MUST set `short-channel-id` to refer to the confirmed funding transaction as specified in [BOLT #2](02-peer-protocol.md#the-funding_locked-message). The corresponding output MUST be a P2WSH as described in [BOLT #3](03-transactions.md#funding-transaction-output). @@ -96,7 +110,7 @@ The creating node SHOULD set `len` to the minimum length required to hold the `features` bits it sets. The receiving node MUST ignore the message if the output specified -by `channel-id` does not +by `short-channel-id` does not correspond to a P2WSH using `bitcoin-key-1` and `bitcoin-key-2` as specified in [BOLT #3](03-transactions.md#funding-transaction-output). The receiving node MUST ignore the message if this output is spent. @@ -254,7 +268,7 @@ it wants to change fees. 1. type: 258 (`channel_update`) 2. data: * [64:signature] - * [8:channel-id] + * [8:short-channel-id] * [4:timestamp] * [2:flags] * [2:cltv-expiry-delta] @@ -267,7 +281,7 @@ it wants to change fees. The creating node MUST set `signature` to the signature of the double-SHA256 of the entire remaining packet after `signature` using its own `node-id`. -The creating node MUST set `channel-id` to +The creating node MUST set `short-channel-id` to match those in the already-sent `channel_announcement` message, and MUST set the least-significant bit of `flags` to 0 if the creating node is `node-id-1` in that message, otherwise 1. It MUST set other bits of `flags` to zero. The creating node MUST set `timestamp` to greater than zero, and MUST set it to greater than any previously-sent `channel_update` for this channel. @@ -276,7 +290,7 @@ It MUST set `cltv-expiry-delta` to the number of blocks it will subtract from an The receiving node MUST ignore `flags` other than the least significant bit. The receiving node SHOULD ignore `ipv6` -if `port` is zero. It SHOULD ignore the message if `channel-id`does +if `port` is zero. It SHOULD ignore the message if `short-channel-id` does not correspond to a previously known, unspent channel from `channel_announcement`, otherwise the node-id is taken from the `channel_announcement` `node-id-1` if least-significant bit of flags is 0 or `node-id-2` otherwise.