From 998b789fbea845545e308198d446aa5c3ddfcacc Mon Sep 17 00:00:00 2001 From: niftynei Date: Thu, 2 Nov 2023 14:16:53 -0500 Subject: [PATCH 01/21] spelling: fix spelling mistakes + add new words to ignore spelling --- .aspell.en.pws | 9 +++++++++ 01-messaging.md | 2 +- 04-onion-routing.md | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.aspell.en.pws b/.aspell.en.pws index 8265be213..8b6e9dc05 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -286,6 +286,13 @@ pico mainnet testnet icecream +extractable +de +anonymize +Punycode +rck +sck +zeroconf swiss lollypop UTC @@ -394,3 +401,5 @@ pkh kB unblind unblinded +accepter +kiloweight diff --git a/01-messaging.md b/01-messaging.md index 5bf740c4e..a602d40b5 100644 --- a/01-messaging.md +++ b/01-messaging.md @@ -7,7 +7,7 @@ This protocol assumes an underlying authenticated and ordered transport mechanis The default TCP port depends on the network used. The most common networks are: -- Bitcoin mainet with port number 9735 or the corresponding hexadecimal `0x2607`; +- Bitcoin mainnet with port number 9735 or the corresponding hexadecimal `0x2607`; - Bitcoin testnet with port number 19735 (`0x4D17`); - Bitcoin signet with port number 39735 (`0xF87`). diff --git a/04-onion-routing.md b/04-onion-routing.md index 4f9d50ab6..30e727a27 100644 --- a/04-onion-routing.md +++ b/04-onion-routing.md @@ -1500,7 +1500,7 @@ The writer: - MUST set the `onion_message_packet` `version` to 0. - MUST construct the `onion_message_packet` `onionmsg_payloads` as detailed above using Sphinx. -- MUST NOT use any `associated_data` in the Sphinx construcion. +- MUST NOT use any `associated_data` in the Sphinx construction. - SHOULD set `onion_message_packet` `len` to 1366 or 32834. - SHOULD retry via a different path if it expects a response and doesn't receive one after a reasonable period. - For the non-final nodes' `onionmsg_tlv`: From 7f573380b945a2c8a4cfbde80341eeeae1474d32 Mon Sep 17 00:00:00 2001 From: niftynei Date: Tue, 2 Mar 2021 21:10:33 -0600 Subject: [PATCH 02/21] interactive-tx: Add dual-funding flow, using the interactive tx protocol This commit adds the interactive transaction construction protcol, as well as the first practical example of using it, v2 of channel establishment. Note that for v2 we also update the channel_id, which now uses the hash of the revocation_basepoints. We move away from using the funding transaction id, as the introduction of RBF* makes it such that a single channel may have many funding transaction id's over the course of its lifetime. *Later, also splicing --- .aspell.en.pws | 25 +- 01-messaging.md | 12 +- 02-peer-protocol.md | 758 +++++++++++++++++++++++++++++++++++++++++++- 03-transactions.md | 364 ++++++++++++++++++++- 09-features.md | 1 + tools/spellcheck.sh | 3 +- 6 files changed, 1155 insertions(+), 8 deletions(-) diff --git a/.aspell.en.pws b/.aspell.en.pws index 8b6e9dc05..a4d459d96 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -23,6 +23,7 @@ nhops retransmitted dev tradeoff +kiloweight mixHeader uint hopsData @@ -115,6 +116,17 @@ delayedsig hopDataSize I'th segwit +RBF +accepter +accepter's +subtype +redeemScript +scriptSig +utxo +scriptPubKey +scriptPubKeys +scriptlen +sats htlc htlcs ChaCha @@ -401,5 +413,14 @@ pkh kB unblind unblinded -accepter -kiloweight +workflow +PUSHDATA +prev +vout +rbf +standardness +perkw +prevtx +ints +replaceability +disincentivize diff --git a/01-messaging.md b/01-messaging.md index a602d40b5..f7e38f758 100644 --- a/01-messaging.md +++ b/01-messaging.md @@ -344,14 +344,22 @@ For simplicity of diagnosis, it's often useful to tell a peer that something is The channel is referred to by `channel_id`, unless `channel_id` is 0 (i.e. all bytes are 0), in which case it refers to all channels. -The funding node: +The funding node using channel establishment v1 (`open_channel`): - for all error messages sent before (and including) the `funding_created` message: - MUST use `temporary_channel_id` in lieu of `channel_id`. -The fundee node: +The fundee node using channel establishment v1 (`accept_channel`): - for all error messages sent before (and not including) the `funding_signed` message: - MUST use `temporary_channel_id` in lieu of `channel_id`. +The opener node using channel establishment v2 (`open_channel2`): + - for all error messages sent before the `accept_channel2` message is received: + - MUST use `temporary_channel_id` in lieu of `channel_id`. + +The accepter node using channel establishment v2 (`open_channel2`): + - for all error messages sent before (and including) the `accept_channel2` message: + - MUST use `temporary_channel_id` in lieu of `channel_id`. + A sending node: - SHOULD send `error` for protocol violations or internal errors that make channels unusable or that make further communication unusable. - SHOULD send `error` with the unknown `channel_id` in reply to messages of type `32`-`255` related to unknown channels. diff --git a/02-peer-protocol.md b/02-peer-protocol.md index d484b4891..4141665af 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -7,12 +7,31 @@ operation, and closing. * [Channel](#channel) * [Definition of `channel_id`](#definition-of-channel_id) - * [Channel Establishment](#channel-establishment) + * [Interactive Transaction Construction](#interactive-transaction-construction) + * [Set-Up and Vocabulary](#set-up-and-vocabulary) + * [Fee Responsibility](#fee-responsibility) + * [Overview](#overview) + * [The `tx_add_input` Message](#the-tx_add_input-message) + * [The `tx_add_output` Message](#the-tx_add_output-message) + * [The `tx_remove_input` and `tx_remove_output` Messages](#the-tx_remove_input-and-tx_remove_output-messages) + * [The `tx_complete` Message](#the-tx_complete-message) + * [The `tx_signatures` Message](#the-tx_signatures-message) + * [The `tx_init_rbf` Message](#the-tx_init_rbf-message) + * [The `tx_ack_rbf` Message](#the-tx_ack_rbf-message) + * [The `tx_abort` Message](#the-tx_abort-message) + * [Channel Establishment v1](#channel-establishment-v1) * [The `open_channel` Message](#the-open_channel-message) * [The `accept_channel` Message](#the-accept_channel-message) * [The `funding_created` Message](#the-funding_created-message) * [The `funding_signed` Message](#the-funding_signed-message) * [The `channel_ready` Message](#the-channel_ready-message) + * [Channel Establishment v2](#channel-establishment-v2) + * [The `open_channel2` Message](#the-open_channel2-message) + * [The `accept_channel2` Message](#the-accept_channel2-message) + * [Funding Composition](#funding-composition) + * [The `commitment_signed` Message](#the-commitment_signed-message) + * [Sharing funding signatures: `tx_signatures`](#sharing-funding-signatures-tx_signatures) + * [Fee bumping: `tx_init_rbf` and `tx_ack_rbf`](#fee-bumping-tx_init_rbf-and-tx_ack_rbf) * [Channel Close](#channel-close) * [Closing Initiation: `shutdown`](#closing-initiation-shutdown) * [Closing Negotiation: `closing_signed`](#closing-negotiation-closing_signed) @@ -49,11 +68,439 @@ transaction is confirmed are also not persistent - until you know the script pubkey corresponding to the funding output nothing prevents duplicative channel ids. +### `channel_id`, v2 -## Channel Establishment +For channels established using the v2 protocol, the `channel_id` is the +`SHA256(lesser-revocation-basepoint || greater-revocation-basepoint)`, +where the lesser and greater is based off the order of the basepoint. + +When sending `open_channel2`, the peer's revocation basepoint is unknown. +A `temporary_channel_id` must be computed by using a zeroed out basepoint +for the non-initiator. + +When sending `accept_channel2`, the `temporary_channel_id` from `open_channel2` +must be used, to allow the initiator to match the response to its request. + +#### Rationale + +The revocation basepoints must be remembered by both peers for correct +operation anyway. They're known after the first exchange of messages, +obviating the need for a `temporary_channel_id` in subsequent messages. +By mixing information from both sides, they avoid `channel_id` collisions, +and they remove the dependency on the funding txid. + +## Interactive Transaction Construction + +Interactive transaction construction allows two peers to collaboratively +build a transaction for broadcast. This protocol is the foundation +for dual-funded channels establishment (v2). + +### Set-Up and Vocabulary + +There are two parties to a transaction construction: an *initiator* +and a *non-initiator*. +The *initiator* is the peer which initiates the protocol, e.g. +for channel establishment v2 the *initiator* would be the peer which +sends `open_channel2`. + +The protocol makes the following assumptions: + +- The `feerate` for the transaction is known. +- The `dust_limit` for the transaction is known. +- The `nLocktime` for the transaction is known. +- The `nVersion` for the transaction is known. + +### Fee Responsibility + +The *initiator* is responsible for paying the fees for the following fields, +to be referred to as the `common fields`. + + - version + - segwit marker + flag + - input count + - output count + - locktime + +The rest of the transaction bytes' fees are the responsibility of +the peer who contributed that input or output via `tx_add_input` or +`tx_add_output`, at the agreed upon `feerate`. + +### Overview + +The *initiator* initiates the interactive transaction construction +protocol with `tx_add_input`. The *non-initiator* responds with any +of `tx_add_input`, `tx_add_output`, `tx_remove_input`, `tx_remove_output`, or +`tx_complete`. The protocol continues with the synchronous exchange +of interactive transaction protocol messages until both nodes have sent +and received a consecutive `tx_complete`. This is a turn-based protocol. + +Once peers have exchanged consecutive `tx_complete`s, the +interactive transaction construction protocol is considered concluded. +Both peers should construct the transaction and fail the negotiation +if an error is discovered. + +This protocol is expressly designed to allow for parallel, multi-party +sessions to collectively construct a single transaction. This preserves +the ability to open multiple channels in a single transaction. While +`serial_id`s are generally chosen randomly, to maintain consistent transaction +ordering across all peer sessions, it is simplest to reuse received +`serial_id`s when forwarding them to other peers, inverting the bottom bit as +necessary to satisfy the parity requirement. + +Here are a few example exchanges. + +#### *initiator* only + +A, the *initiator*, has two inputs and an output (the funding output). +B, the *non-initiator* has nothing to contribute. + + +-------+ +-------+ + | |--(1)- tx_add_input -->| | + | |<-(2)- tx_complete ----| | + | |--(3)- tx_add_input -->| | + | A |<-(4)- tx_complete ----| B | + | |--(5)- tx_add_output ->| | + | |<-(6)- tx_complete ----| | + | |--(7)- tx_complete --->| | + +-------+ +-------+ + +#### *initiator* and *non-initiator* + +A, the *initiator*, contributes 2 inputs and an output that they +then remove. B, the *non-initiator*, contributes 1 input and an output, +but waits until A adds a second input before contributing. + +Note that if A does not send a second input, the negotiation will end without +B's contributions. + + +-------+ +-------+ + | |--(1)- tx_add_input ---->| | + | |<-(2)- tx_complete ------| | + | |--(3)- tx_add_output --->| | + | |<-(4)- tx_complete ------| | + | |--(5)- tx_add_input ---->| | + | A |<-(6)- tx_add_input -----| B | + | |--(7)- tx_remove_output >| | + | |<-(8)- tx_add_output ----| | + | |--(9)- tx_complete ----->| | + | |<-(10) tx_complete ------| | + +-------+ +-------+ + +### The `tx_add_input` Message + +This message contains a transaction input. + +1. type: 66 (`tx_add_input`) +2. data: + * [`channel_id`:`channel_id`] + * [`u64`:`serial_id`] + * [`u16`:`prevtx_len`] + * [`prevtx_len*byte`:`prevtx`] + * [`u32`:`prevtx_vout`] + * [`u32`:`sequence`] + +#### Requirements + +The sending node: + - MUST add all sent inputs to the transaction + - MUST use a unique `serial_id` for each input currently added to the + transaction + - MUST set `sequence` to be less than or equal to 4294967293 (`0xFFFFFFFD`) + - MUST NOT re-transmit inputs it has received from the peer + - if is the *initiator*: + - MUST send even `serial_id`s + - if is the *non-initiator*: + - MUST send odd `serial_id`s + +The receiving node: + - MUST add all received inputs to the transaction + - MUST fail the negotiation if: + - `sequence` is set to `0xFFFFFFFE` or `0xFFFFFFFF` + - the `prevtx` and `prevtx_vout` are identical to a previously added + (and not removed) input's + - `prevtx` is not a valid transaction + - `prevtx_vout` is greater or equal to the number of outputs on `prevtx` + - the `scriptPubKey` of the `prevtx_vout` output of `prevtx` is not exactly a 1-byte push opcode (for the numeric values `0` to `16`) followed by a data push between 2 and 40 bytes + - the `serial_id` is already included in the transaction + - the `serial_id` has the wrong parity + - if has received 4096 `tx_add_input` messages during this negotiation + +#### Rationale + +Each node must know the set of the transaction inputs. The *non-initiator* +MAY omit this message. + +`serial_id` is a randomly chosen number which uniquely identifies this input. +Inputs in the constructed transaction are sorted by `serial_id`. + +`prevtx` is the serialized transaction that contains the output +this input spends. Used to verify that the input is non-malleable. + +`prevtx_vout` is the index of the output being spent. + +`sequence` is the sequence number of this input: it must signal +replaceability, and the same value should be used across implementations +to avoid on-chain fingerprinting. + +### The `tx_add_output` Message + +This message adds a transaction output. + +1. type: 67 (`tx_add_output`) +2. data: + * [`channel_id`:`channel_id`] + * [`u64`:`serial_id`] + * [`u64`:`sats`] + * [`u16`:`scriptlen`] + * [`scriptlen*byte`:`script`] + +#### Requirements + +Either node: + - MAY omit this message + +The sending node: + - MUST add all sent outputs to the transaction + - if is the *initiator*: + - MUST send even `serial_id`s + - if is the *non-initiator*: + - MUST send odd `serial_id`s + +The receiving node: + - MUST add all received outputs to the transaction + - MUST accept P2WSH, P2WPKH, P2TR `script`s + - MAY fail the negotiation if `script` is non-standard + - MUST fail the negotiation if: + - the `serial_id` is already included in the transaction + - the `serial_id` has the wrong parity + - it has received 4096 `tx_add_output` messages during this negotiation + - the `sats` amount is less than the `dust_limit` + - the `sats` amount is greater than 2,100,000,000,000,000 (`MAX_MONEY`) + +#### Rationale + +Each node must know the set of the transaction outputs. + +`serial_id` is a randomly chosen number which uniquely identifies this output. +Outputs in the constructed transaction are sorted by `serial_id`. + +`sats` is the satoshi value of the output. + +`script` is the scriptPubKey for the output (with its length omitted). +`script`s are not required to follow standardness rules: non-standard +scripts such as `OP_RETURN` may be accepted, but the corresponding +transaction may fail to relay across the network. + +### The `tx_remove_input` and `tx_remove_output` Messages + +This message removes an input from the transaction. + +1. type: 68 (`tx_remove_input`) +2. data: + * [`channel_id`:`channel_id`] + * [`u64`:`serial_id`] + +This message removes an output from the transaction. + +1. type: 69 (`tx_remove_output`) +2. data: + * [`channel_id`:`channel_id`] + * [`u64`:`serial_id`] + +#### Requirements + +The sending node: + - MUST NOT send a `tx_remove` with a `serial_id` it did not add + to the transaction or has already been removed + +The receiving node: + - MUST remove the indicated input or output from the transaction + - MUST fail the negotiation if: + - the input or output identified by the `serial_id` was not added by the + sender + - the `serial_id` does not correspond to a currently added input (or output) + +### The `tx_complete` Message + +This message signals the conclusion of a peer's transaction +contributions. + +1. type: 70 (`tx_complete`) +2. data: + * [`channel_id`:`channel_id`] + +#### Requirements + +The nodes: + - MUST send this message in succession to conclude this protocol + +The receiving node: + - MUST use the negotiated inputs and outputs to construct a transaction + - MUST fail the negotiation if: + - the peer's total input satoshis is less than their outputs + - the peer's paid feerate does not meet or exceed the agreed `feerate` + (based on the `minimum fee`). + - if is the *non-initiator*: + - the *initiator*'s fees do not cover the `common` fields + - there are more than 252 inputs + - there are more than 252 outputs + - the estimated weight of the tx is greater than 400,000 (`MAX_STANDARD_TX_WEIGHT`) + +#### Rationale + +To signal the conclusion of exchange of transaction inputs and outputs. + +Upon successful exchange of `tx_complete` messages, both nodes +should construct the transaction and proceed to the next portion of the +protocol. For channel establishment v2, exchanging commitment transactions. + +For the `minimum fee` calculation see [BOLT #3](03-transactions.md#calculating-fees-for-collaborative-transaction-construction). + +The maximum inputs and outputs are capped at 252. This effectively fixes +the byte size of the input and output counts on the transaction to one (1). + +### The `tx_signatures` Message + +1. type: 71 (`tx_signatures`) +2. data: + * [`channel_id`:`channel_id`] + * [`sha256`:`txid`] + * [`u16`:`num_witnesses`] + * [`num_witnesses*witness_stack`:`witnesses`] + +1. subtype: `witness_stack` +2. data: + * [`u16`:`num_witness_elements`] + * [`num_witness_elements*witness_element`:`witness_elements`] + +1. subtype: `witness_element` +2. data: + * [`u16`:`len`] + * [`len*byte`:`witness_data`] + +#### Requirements + +The sending node: + - if it has the lowest total satoshis contributed, as defined by total + `tx_add_input` values, or both peers have contributed equal amounts + but it has the lowest `node_id` (sorted lexicographically): + - MUST transmit their `tx_signatures` first + - MUST order the `witnesses` by the `serial_id` of the input they + correspond to + - `num_witnesses`s MUST equal the number of inputs they added + +The receiving node: + - MUST fail the negotiation if: + - the message contains an empty `witness_stack` + - the number of `witnesses` does not equal the number of inputs + added by the sending node + - the `txid` does not match the txid of the transaction + - the witnesses are non-standard + - SHOULD apply the `witnesses` to the transaction and broadcast it + - MUST reply with their `tx_signatures` if not already transmitted + +#### Rationale + +A strict ordering is used to decide which peer sends `tx_signatures` first. +This prevents deadlocks where each peer is waiting for the other peer to +send `tx_signatures`, and enables multiparty tx collaboration. + +`witness_data` is the data for a witness element in a witness stack, not +prefixed with its length (since it is already specified in the `len` field). + +While the `minimum fee` is calculated and verified at `tx_complete` conclusion, +it is possible for the fee for the exchanged witness data to be underpaid. +It is the responsibility of the sending peer to correctly account for the +required fee, e.g. a multisig witness stack whose weight exceeds 107. + +### The `tx_init_rbf` Message + +This message initiates a replacement of the transaction after it's been +completed. + +1. type: 72 (`tx_init_rbf`) +2. data: + * [`channel_id`:`channel_id`] + * [`u32`:`locktime`] + * [`u32`:`feerate`] + * [`tx_init_rbf_tlvs`:`tlvs`] + +1. `tlv_stream`: `tx_init_rbf_tlvs` +2. types: + 1. type: 0 (`funding_output_contribution`) + 2. data: + * [`tu64`:`satoshis`] + +#### Requirements + +The sender: + - MUST set `feerate` greater than or equal to 25/24 times the `feerate` + of the previously constructed transaction, rounded down. + +The recipient: + - MUST respond either by failing the negotiation or with `tx_ack_rbf`. + - MUST fail the negotiation if: + - the `feerate` is not greater than 25/24 times `feerate` of the last + successfully constructed transaction + - MAY fail the negotiation for any reason + +#### Rationale + +`feerate` is the feerate this transaction will pay. It must be at least +1/24 greater than the last used `feerate`, rounded down to the nearest +satoshi to ensure there is progress. + +E.g. if the last `feerate` was 520, the next sent `feerate` must be 541 +(520 * 25 / 24 = 541.667, rounded down to 541). + +If the previous transaction confirms in the middle of an RBF attempt, +the attempt MUST be abandoned. + +`funding_output_contribution` is the amount of satoshis that this peer +will contribute to the funding output of the transaction, when there is +such an output. Note that it may be different from the contribution +made in the previously completed transaction. + +### The `tx_ack_rbf` Message + +1. type: 73 (`tx_ack_rbf`) +2. data: + * [`channel_id`:`channel_id`] + * [`tx_ack_rbf_tlvs`:`tlvs`] + +1. `tlv_stream`: `tx_ack_rbf_tlvs` +2. types: + 1. type: 0 (`funding_output_contribution`) + 2. data: + * [`tu64`:`satoshis`] + +#### Requirements + +The recipient: + - MUST either fail the negotiation or transmit a `tx_add_input` message, + restarting the interactive tx collaboration protocol. + +#### Rationale + +`funding_output_contribution` is the amount of satoshis that this peer +will contribute to the funding output of the transaction, when there is +such an output. Note that it may be different from the contribution +made in the previously completed transaction. + +It's recommended that a peer, rather than fail the RBF negotiation due to +a large feerate change, instead sets their `funding_output_contribution` to +zero, and decline to participate further in the transaction (by not +contributing, they may obtain incoming liquidity at no cost). + +## Channel Establishment v1 After authenticating and initializing a connection ([BOLT #8](08-transport.md) and [BOLT #1](01-messaging.md#the-init-message), respectively), channel establishment may begin. + +There are two pathways for establishing a channel, a legacy version presented here, +and a second version ([below](#channel-establishment-v2)). Which channel +establishment protocols are available for use is negotiated in the `init` message. + This consists of the funding node (funder) sending an `open_channel` message, followed by the responding node (fundee) sending `accept_channel`. With the channel parameters locked in, the funder is able to create the funding @@ -258,6 +705,8 @@ The receiving node MUST: `open_channel`, BUT before receiving a `funding_created` message: - accept a new `open_channel` message. - discard the previous `open_channel` message. + - if `option_dual_fund` has been negotiated: + - fail the channel. The receiving node MAY fail the channel if: - `option_channel_type` was negotiated but the message doesn't include a `channel_type` @@ -560,6 +1009,309 @@ ones it has sent so it can use them should they be requested by incoming HTLCs. The recipient only need remember one, for use in `r` route hints in BOLT 11 invoices. +If an RBF negotiation is in progress when a `channel_ready` message is +exchanged, the negotiation must be abandoned. + +## Channel Establishment v2 + +This is a revision of the channel establishment protocol. +It changes the previous protocol to allow the `accept_channel2` peer +(the *accepter*/*non-initiator*) to contribute inputs to the funding +transaction, via the interactive transaction construction protocol. + + +-------+ +-------+ + | |--(1)--- open_channel2 ----->| | + | |<-(2)--- accept_channel2 -----| | + | | | | + --->| | | | + | | | | | + | | |--(3)-- commitment_signed -->| | + | | |<-(4)-- commitment_signed ---| | + | | A | | B | + | | |<-(5)-- tx_signatures -------| | + | | |--(6)-- tx_signatures ------>| | + | | | | | + | | |--(a)--- tx_init_rbf -------->| | + ----| |<-(b)--- tx_ack_rbf ----------| | + | | | | + | | | | + | | | | + | |--(c)-- commitment_signed -->| | + | |<-(d)-- commitment_signed ---| | + | | | | + | |<-(e)-- tx_signatures -------| | + | |--(f)-- tx_signatures ------>| | + | | | | + | |--(7)--- channel_ready ----->| | + | |<-(8)--- channel_ready ------| | + +-------+ +-------+ + + - where node A is *opener*/*initiator* and node B is + *accepter*/*non-initiator* + +### The `open_channel2` Message + +This message initiates the v2 channel establishment workflow. + +1. type: 64 (`open_channel2`) +2. data: + * [`chain_hash`:`chain_hash`] + * [`channel_id`:`temporary_channel_id`] + * [`u32`:`funding_feerate_perkw`] + * [`u32`:`commitment_feerate_perkw`] + * [`u64`:`funding_satoshis`] + * [`u64`:`dust_limit_satoshis`] + * [`u64`:`max_htlc_value_in_flight_msat`] + * [`u64`:`htlc_minimum_msat`] + * [`u16`:`to_self_delay`] + * [`u16`:`max_accepted_htlcs`] + * [`u32`:`locktime`] + * [`point`:`funding_pubkey`] + * [`point`:`revocation_basepoint`] + * [`point`:`payment_basepoint`] + * [`point`:`delayed_payment_basepoint`] + * [`point`:`htlc_basepoint`] + * [`point`:`first_per_commitment_point`] + * [`byte`:`channel_flags`] + * [`opening_tlvs`:`tlvs`] + +1. `tlv_stream`: `opening_tlvs` +2. types: + 1. type: 0 (`upfront_shutdown_script`) + 2. data: + * [`...*byte`:`shutdown_scriptpubkey`] + 1. type: 1 (`channel_type`) + 2. data: + * [`...*byte`:`type`] + +Rationale and Requirements are the same as for [`open_channel`](#the-open_channel-message), +with the following additions. + +#### Requirements + +If nodes have negotiated `option_dual_fund`: + - the opening node: + - MUST NOT send `open_channel` + +The sending node: + - MUST set `funding_feerate_perkw` to the feerate for this transaction + +The receiving node: + - MAY fail the negotiation if: + - the `locktime` is unacceptable + - the `funding_feerate_perkw` is unacceptable + +#### Rationale + +`temporary_channel_id` MUST be derived using a zeroed out basepoint for the +peer's revocation basepoint. This allows the peer to return channel-assignable +errors before the *accepter*'s revocation basepoint is known. + +`funding_feerate_perkw` indicates the fee rate that the opening node will +pay for the funding transaction in satoshi per 1000-weight, as described +in [BOLT-3, Appendix F](03-transactions.md#appendix-f-dual-funded-transaction-test-vectors). + +`locktime` is the locktime for the funding transaction. + +The receiving node, if the `locktime` or `funding_feerate_perkw` is considered +out of an acceptable range, may fail the negotiation. However, it is +recommended that the *accepter* permits the channel open to proceed +without their participation in the channel's funding. + +Note that `open_channel`'s `channel_reserve_satoshi` has been omitted. +Instead, the channel reserve is fixed at 1% of the total channel balance +(`open_channel2`.`funding_satoshis` + `accept_channel2`.`funding_satoshis`) +rounded down to the nearest whole satoshi or the `dust_limit_satoshis`, +whichever is greater. + +Note that `push_msat` has been omitted. + +### The `accept_channel2` Message + +This message contains information about a node and indicates its +acceptance of the new channel. + +1. type: 65 (`accept_channel2`) +2. data: + * [`channel_id`:`temporary_channel_id`] + * [`u64`:`funding_satoshis`] + * [`u64`:`dust_limit_satoshis`] + * [`u64`:`max_htlc_value_in_flight_msat`] + * [`u64`:`htlc_minimum_msat`] + * [`u32`:`minimum_depth`] + * [`u16`:`to_self_delay`] + * [`u16`:`max_accepted_htlcs`] + * [`point`:`funding_pubkey`] + * [`point`:`revocation_basepoint`] + * [`point`:`payment_basepoint`] + * [`point`:`delayed_payment_basepoint`] + * [`point`:`htlc_basepoint`] + * [`point`:`first_per_commitment_point`] + * [`accept_tlvs`:`tlvs`] + +1. `tlv_stream`: `accept_tlvs` +2. types: + 1. type: 0 (`upfront_shutdown_script`) + 2. data: + * [`...*byte`:`shutdown_scriptpubkey`] + 1. type: 1 (`channel_type`) + 2. data: + * [`...*byte`:`type`] + +Rationale and Requirements are the same as listed above, +for [`accept_channel`](#the-accept_channel-message) with the following +additions. + +#### Requirements + +The accepting node: + - MUST use the `temporary_channel_id` of the `open_channel2` message + - MAY respond with a `funding_satoshis` value of zero. + +#### Rationale + +The `funding_satoshis` is the amount of bitcoin in satoshis +the *accepter* will be contributing to the channel's funding transaction. + +Note that `accept_channel`'s `channel_reserve_satoshi` has been omitted. +Instead, the channel reserve is fixed at 1% of the total channel balance +(`open_channel2`.`funding_satoshis` + `accept_channel2`.`funding_satoshis`) +rounded down to the nearest whole satoshi or the `dust_limit_satoshis`, +whichever is greater. + +### Funding Composition + +Funding composition for channel establishment v2 makes use of the +[Interactive Transaction Construction](#interactive-transaction-construction) +protocol, with the following additional caveats. + +#### The `tx_add_input` Message + +No additional caveats or requirements. + +#### The `tx_add_output` Message + +##### Requirements + +The sending node: + - if is the *opener*: + - MUST send at least one `tx_add_output`, which contains the + channel's funding output + +##### Rationale + +The channel funding output must be added by the *opener*, who pays its fees. + +#### The `tx_complete` Message + +Upon receipt of consecutive `tx_complete`s, the receiving node: + - if is the *accepter*: + - MUST fail the negotiation if: + - no funding output was received + - the value of the funding output is not equal to the sum of + `open_channel2`.`funding_satoshis` and `accept_channel2`. + `funding_satoshis` + - the value of the funding output is less than the `dust_limit` + - if it is an RBF attempt: + - MUST fail the negotiation if: + - the transaction's total fees is less than the last + successfully negotiated transaction's fees + - the transaction does not share a common input with all previous + funding transactions + +### The `commitment_signed` Message + +This message is exchanged by both peers. It contains the signatures for +the first commitment transaction. + +Rationale and Requirements are the same as listed below, +for [`commitment_signed`](#commiting-updates-so-far-commitment_signed) with the following additions. + +#### Requirements + +The sending node: + - MUST send zero HTLCs. + +The receiving node: + - if the message has one or more HTLCs: + - MUST fail the negotiation + - if it has not already transmitted its `commitment_signed`: + - MUST send `commitment_signed` + - Otherwise: + - MUST send `tx_signatures` if it should sign first, as specified + in the [`tx_signatures` requirements](#the-tx_signatures-message) + +#### Rationale + +The first commitment transaction has no HTLCs. + +### Sharing funding signatures: `tx_signatures` + +After a valid `commitment_signed` has been received +from the peer and a `commitment_signed` has been sent, a peer: + - MUST transmit `tx_signatures` with their signatures for the funding + transaction, following the order specified in the + [`tx_signatures` requirements](#the-tx_signatures-message) + +#### Requirements + +The sending node: + - MUST verify it has received a valid commitment signature from its peer + - MUST remember the details of this funding transaction + - if it has NOT received a valid `commitment_signed` message: + - MUST NOT send a `tx_signatures` message + +The receiving node: + - if the `witness_stack` weight lowers the effective `feerate` + below the the *opener*'s feerate for the funding transaction: + - SHOULD broadcast their commitment transaction, closing the channel. + - SHOULD apply `witnesses` to the funding transaction and broadcast it + - if has already sent or received a `channel_ready` message for this + channel: + - MUST ignore this message + +#### Rationale + +A peer sends their `tx_signatures` after receiving a valid `commitment_signed` +message, following the order specified in the [`tx_signatures` section](#the-tx_signatures-message). + +In the case where a peer provides valid witness data that causes their paid +feerate to fall beneath the `open_channel2.funding_feerate_perkw`, the protocol +should be aborted and the channel should be double-spent when there is a +productive opportunity to do so. This should disincentivize peers from +underpaying fees. + +### Fee bumping: `tx_init_rbf` and `tx_ack_rbf` + +After the funding transaction has been broadcast, it can be replaced by +a transaction paying more fees to make the channel confirm faster. + +#### Requirements + +The sender of `tx_init_rbf`: + - MUST be the *initiator* + - MUST NOT have sent or received a `channel_ready` message. + +The recipient: + - MUST fail the negotiation if they have already sent or received + `channel_ready` + - MAY fail the negotiation for any reason + +#### Rationale + +If a valid `channel_ready` message is received in the middle of an +RBF attempt, the attempt MUST be abandoned. + +Peers can use different values in `tx_init_rbf.funding_output_contribution` +and `tx_ack_rbf.funding_output_contribution` from the amounts transmitted +in `open_channel2` and `accept_channel2`: they are allowed to change how +much they wish to commit to the funding output. + +It's recommended that a peer, rather than fail the RBF negotiation due to +a large feerate change, instead sets their `sats` to zero, and decline to +participate further in the channel funding: by not contributing, they +may obtain incoming liquidity at no cost. + ## Channel Close Nodes can negotiate a mutual close of the connection, which unlike a @@ -1526,11 +2278,13 @@ A node: - if `next_commitment_number` is 1 in both the `channel_reestablish` it sent and received: - MUST retransmit `channel_ready`. + - MUST retransmit `tx_signatures` if it is using channel establishment v2. - otherwise: - MUST NOT retransmit `channel_ready`, but MAY send `channel_ready` with a different `short_channel_id` `alias` field. - upon reconnection: - MUST ignore any redundant `channel_ready` it receives. + - MUST ignore any redundant `tx_signatures` it receives. - if `next_commitment_number` is equal to the commitment number of the last `commitment_signed` message the receiving node has sent: - MUST reuse the same commitment number for its next `commitment_signed`. diff --git a/03-transactions.md b/03-transactions.md index a8e843ff9..4ebd028b8 100644 --- a/03-transactions.md +++ b/03-transactions.md @@ -21,6 +21,7 @@ This details the exact format of on-chain transactions, which both sides need to * [Fees](#fees) * [Fee Calculation](#fee-calculation) * [Fee Payment](#fee-payment) + * [Calculating Fees for Collaborative Transactions](#calculating-fees-for-collaborative-transactions) * [Dust Limits](#dust-limits) * [Commitment Transaction Construction](#commitment-transaction-construction) * [Keys](#keys) @@ -30,6 +31,7 @@ This details the exact format of on-chain transactions, which both sides need to * [Per-commitment Secret Requirements](#per-commitment-secret-requirements) * [Efficient Per-commitment Secret Storage](#efficient-per-commitment-secret-storage) * [Appendix A: Expected Weights](#appendix-a-expected-weights) + * [Expected Weight of the Funding Transaction (v2 Channel Establishment)](#expected-weight-of-the-funding-transaction-v2-channel-establishment) * [Expected Weight of the Commitment Transaction](#expected-weight-of-the-commitment-transaction) * [Expected Weight of HTLC-timeout and HTLC-success Transactions](#expected-weight-of-htlc-timeout-and-htlc-success-transactions) * [Appendix B: Funding Transaction Test Vectors](#appendix-b-funding-transaction-test-vectors) @@ -40,6 +42,7 @@ This details the exact format of on-chain transactions, which both sides need to * [Appendix E: Key Derivation Test Vectors](#appendix-e-key-derivation-test-vectors) * [Appendix F: Commitment and HTLC Transaction Test Vectors (anchors)](#appendix-f-commitment-and-htlc-transaction-test-vectors-anchors) * [Appendix G: Commitment and HTLC Transaction Test Vectors (anchors-zero-fee-htlc-tx)](#appendix-g-commitment-and-htlc-transaction-test-vectors-anchors_zero_fee_htlc_tx) + * [Appendix H: Dual Funded Transaction Test Vectors](#appendix-h-dual-funded-transaction-test-vectors) * [References](#references) * [Authors](#authors) @@ -489,6 +492,12 @@ A node: - MAY send a `warning` and close the connection, or send an `error` and fail the channel. +### Calculating Fees for Collaborative Transactions + +For transactions constructed using the [interactive protocol](02-peer-protocol.md#interactive-transaction-construction), +fees are paid by each party to the transaction, at a `feerate` determined during the +initiation, with the initiator covering the fees for the common transaction fields. + ## Dust Limits The `dust_limit_satoshis` parameter is used to configure the threshold below @@ -828,6 +837,101 @@ at each bucket is a prefix of the desired index. # Appendix A: Expected Weights +## Expected Weight of the Funding Transaction (v2 Channel Establishment) + +The *expected weight* of a funding transaction is calculated as follows: + + inputs: 41 bytes + - previous_out_point: 36 bytes + - hash: 32 bytes + - index: 4 bytes + - var_int: 1 byte + - script_sig: 0 bytes + - witness <---- Cost for "witness" data calculated separately. + - sequence: 4 bytes + + non_funding_outputs: 9 bytes + `scriptlen` + - value: 8 bytes + - var_int: 1 byte <---- assuming a standard output script + - script: `scriptlen` + + funding_output: 43 bytes + - value: 8 bytes + - var_int: 1 byte + - script: 34 bytes + - OP_0: 1 byte + - PUSHDATA(32-byte-hash): 33 bytes + +Multiplying non-witness data by 4 results in a weight of: + + // transaction_fields = 10 (version, input count, output count, locktime) + // segwit_fields = 2 (marker + flag) + // funding_transaction = 43 + num_inputs * 41 + num_outputs * 9 + sum(scriptlen) + funding_transaction_weight = 4 * (funding_transaction + transaction_fields) + segwit_fields + + witness_weight = sum(witness_len) + + overall_weight = funding_transaction_weight + witness_weight + +### Calculating Fees for Collaborative Transaction Construction + +Every participant in a collaborative transaction covers the fees for +their own inputs and outputs. The initiator also provides funds to +cover for the common transaction fields. + +Upon successful exchange of `tx_complete` messages, each peer must at +least cover a minimum estimated fee. Here is how to calculate the minimum +fee for each participant. + +The minimum witness weight for an input is 107. + +In the following, the initiator has provided one input (P2WPKH), one change output +(P2WPKH), and the funding output. The contributor has provided two +inputs (P2WPKH) and two change outputs (P2WPKH). + +Assuming a `feerate` of 253 per kiloweight, the initiator's minimum fee is +calculated as follows. Note that the feerate is rounded up to the nearest satoshi. + + initiator_weight = transaction_fields * 4 + + segwit_fields + + p2wpkh_input * 4 + + funding_output * 4 + + p2wpkh_output * 4 + + input_count * 107 (minimum witness weight) + + initiator_weight = 10 * 4 + + 2 + + 41 * 4 + + 43 * 4 + + 31 * 4 + + 107 + + initiator_weight = 609 + + initiator_fees = initiator_weight * feerate + initiator_fees = 609 * 253 / 1000 + initiator_fees = 155 sats + +The contributor's minimum fee is calculated as follows. + + contributor_weight = 2 * p2wpkh_input * 4 + + 2 * p2wpkh_output * 4 + + input_count * 107 (minimum witness weight) + + contributor_weight = 2 * 41 * 4 + + 2 * 31 * 4 + + 2 * 107 + + contributor_weight = 790 + + contributor_fees = contributor_weight * feerate + contributor_fees = 790 * 253 / 1000 + contributor_fees = 200 sats + +This is an estimated fee. The peer MUST at least contribute the estimated fee, +and MUST exceed the minimum fee in the case that their witness weight is greater +than the estimated weight of 107 per input. + ## Expected Weight of the Commitment Transaction The *expected weight* of a commitment transaction is calculated as follows: @@ -1124,7 +1228,7 @@ The resulting funding transaction is: In the following: - *local* transactions are considered, which implies that all payments to *local* are delayed. - - It's assumed that *local* is the funder. + - It's assumed that *local* is the opener. - Private keys are displayed as 32 bytes plus a trailing 1 (Bitcoin's convention for "compressed" private keys, i.e. keys for which the public key is compressed). - Transaction signatures are all deterministic, using RFC6979 (using HMAC-SHA256). @@ -2679,6 +2783,264 @@ before subtraction of: ] ``` +# Appendix H: Dual Funded Transaction Test Vectors + +## Funding Transaction Construction +### Preliminaries: + +``` +Genesis block 0: +0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f20020000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000 + +Block 1:0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910ff86fd1d0db3ac5a72df968622f31e6b5e6566a09e29206d7c7a55df90e181de8be86815cffff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a0100000017a914113ca7e584fe1575b6fc39abae991529f66eda58870000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000 +Coinbase address pubkey: 2MtpN8zCxTp8AWSg7VBjBX7vU6x73bVCKP8 +Coinbase address privkey: cPxFtfE1w3ptFnsZvvFeWji21kTArYa9GXwMkYsoQHdaJKrjUTek + +Parent transaction (spends coinbase of block 1): +02000000000101f86fd1d0db3ac5a72df968622f31e6b5e6566a09e29206d7c7a55df90e181de800000000171600141fb9623ffd0d422eacc450fd1e967efc477b83ccffffffff0580b2e60e00000000220020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b94680b2e60e0000000017a9146a235d064786b49e7043e4a042d4cc429f7eb6948780b2e60e00000000160014fbb4db9d85fba5e301f4399e3038928e44e37d3280b2e60e0000000017a9147ecd1b519326bc13b0ec716e469b58ed02b112a087f0006bee0000000017a914f856a70093da3a5b5c4302ade033d4c2171705d387024730440220696f6cee2929f1feb3fd6adf024ca0f9aa2f4920ed6d35fb9ec5b78c8408475302201641afae11242160101c6f9932aeb4fcd1f13a9c6df5d1386def000ea259a35001210381d7d5b1bc0d7600565d827242576d9cb793bfe0754334af82289ee8b65d137600000000 +``` + +### Funding transaction (spends parent's outputs): + +Locktime: 120 +Feerate: 253 sat/kiloweight +Opener's `funding_satoshi`: 2 0000 0000 sat +Accepter's `funding_satoshi`: 2 0000 0000 sat + +Inputs: +``` +4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9 0 + witness_data: + preimage: 20 68656c6c6f2074686572652c2074686973206973206120626974636f6e212121 + witness_script: 27 82012088a820add57dfe5277079d069ca4ad4893c96de91f88ffb981fdc6a2a34d5336c66aff87 + scriptPubKey: 0020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b946 + address: bcrt1qlky6eaj5sh0cj7tanwnm573nvf9vg3f0qrdssyrlxsjh6vl9h9rql40v2g + +4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9 2 + pubkey: 034695f5b7864c580bf11f9f8cb1a94eb336f2ce9ef872d2ae1a90ee276c772484 + privkey: cUM8Dr33wK4uFmw3Tz8sbQ7BiBNgX5BthRurU7RkgXVvNUPcWrJf + witness_program: fbb4db9d85fba5e301f4399e3038928e44e37d32 + scriptPubKey: 0014fbb4db9d85fba5e301f4399e3038928e44e37d32 + address: bcrt1qlw6dh8v9lwj7xq058x0rqwyj3ezwxlfjxsy7er + +``` + +### Expected Opener's `tx_add_input` (input 0 above): +``` + num_inputs: 1 + tx_add_input:[ + { + channel_id: "xxx", + serial_id: 20, + prevtx_len: 353, + prevtx: "02000000000101f86fd1d0db3ac5a72df968622f31e6b5e6566a09e29206d7c7a55df90e181de800000000171600141fb9623ffd0d422eacc450fd1e967efc477b83ccffffffff0580b2e60e00000000220020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b94680b2e60e0000000017a9146a235d064786b49e7043e4a042d4cc429f7eb6948780b2e60e00000000160014fbb4db9d85fba5e301f4399e3038928e44e37d3280b2e60e0000000017a9147ecd1b519326bc13b0ec716e469b58ed02b112a087f0006bee0000000017a914f856a70093da3a5b5c4302ade033d4c2171705d387024730440220696f6cee2929f1feb3fd6adf024ca0f9aa2f4920ed6d35fb9ec5b78c8408475302201641afae11242160101c6f9932aeb4fcd1f13a9c6df5d1386def000ea259a35001210381d7d5b1bc0d7600565d827242576d9cb793bfe0754334af82289ee8b65d137600000000", + prev_vout: 0, + sequence: 4294967293 + } + ] +``` + +### Expected Accepter's `tx_add_input` (input 2 above): +``` + num_inputs: 1 + tx_add_input:[ + { + channel_id: "xxx", + serial_id: 11, + prevtx_len: 353, + prevtx: "02000000000101f86fd1d0db3ac5a72df968622f31e6b5e6566a09e29206d7c7a55df90e181de800000000171600141fb9623ffd0d422eacc450fd1e967efc477b83ccffffffff0580b2e60e00000000220020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b94680b2e60e0000000017a9146a235d064786b49e7043e4a042d4cc429f7eb6948780b2e60e00000000160014fbb4db9d85fba5e301f4399e3038928e44e37d3280b2e60e0000000017a9147ecd1b519326bc13b0ec716e469b58ed02b112a087f0006bee0000000017a914f856a70093da3a5b5c4302ade033d4c2171705d387024730440220696f6cee2929f1feb3fd6adf024ca0f9aa2f4920ed6d35fb9ec5b78c8408475302201641afae11242160101c6f9932aeb4fcd1f13a9c6df5d1386def000ea259a35001210381d7d5b1bc0d7600565d827242576d9cb793bfe0754334af82289ee8b65d137600000000", + prev_vout: 2, + sequence: 4294967293 + } + ] +``` + +### Outputs: (scriptPubKeys) +``` +# opener's change address +pubkey: 0206e626a4c6d4392d4030bc78bd93f728d1ba61214a77c63adc17d71e32ded3df +# privkey: cSpC1KYEV1vsUFBwTdcuRkncbwfipY1m5zuQ9CjgAYwiVvbQ4fc1 +scriptPubKey: 00141ca1cca8855bad6bc1ea5436edd8cff10b7e448b +address: bcrt1qrjsue2y9twkkhs022smwmkx07y9hu3ytshgjmj + +# accepter's change address +pubkey: 028f3978c211f4c0bf4d20674f345ae14e08871b25b2c957b4bdbd42e9726278fc +privkey: cQ1HXnbAE4wGhuB2b9rJEydV5ayeEmMqxf1dvHPZmyMTPkwvZJyg +scriptPubKey: 001444cb0c39f93ecc372b5851725bd29d865d333b10 +address: bcrt1qgn9scw0e8mxrw26c29e9h55asewnxwcsdxdp50 + +# the 2-of-2s +pubkey1: 0292edb5f7bbf9e900f7e024be1c1339c6d149c11930e613af3a983d2565f4e41e +pubkey2: 02e16172a41e928cbd78f761bd1c657c4afc7495a1244f7f30166b654fbf7661e3 +script_def: multi(2,0292edb5f7bbf9e900f7e024be1c1339c6d149c11930e613af3a983d2565f4e41e,02e16172a41e928cbd78f761bd1c657c4afc7495a1244f7f30166b654fbf7661e3) +script: 52210292edb5f7bbf9e900f7e024be1c1339c6d149c11930e613af3a983d2565f4e41e2102e16172a41e928cbd78f761bd1c657c4afc7495a1244f7f30166b654fbf7661e352ae +scriptPubKey: 0020297b92c238163e820b82486084634b4846b86a3c658d87b9384192e6bea98ec5 +address: bcrt1q99ae9s3czclgyzuzfpsggc6tfprts63uvkxc0wfcgxfwd04f3mzs3asq6l +``` + +### Expected Opener's `tx_add_output`: + +``` + num_outputs: 2 + tx_add_output[ + { + channel_id:"xxx", + serial_id: 30, + sats: 49999845, + scriptlen: 22, + script: "1600141ca1cca8855bad6bc1ea5436edd8cff10b7e448b" + },{ + channel_id: "xxx", + serial_id: 44, + sats: 400000000, + scriptlen: 34, + script: "220020297b92c238163e820b82486084634b4846b86a3c658d87b9384192e6bea98ec5" + } + ] +``` + +### Expected Accepter's `tx_add_output`: + +``` + num_outputs: 1 + tx_add_output[ + { + channel_id: xxx, + serial_id: 33, + sats: 49999900, + scriptlen: 22, + script: 16001444cb0c39f93ecc372b5851725bd29d865d333b10 + } + ] +``` + +### Expected Fee Calculation: + +Opener's fees and change: +``` + initiator_weight = (input_count, output_count, version, locktime) * 4 + + segwit_fields (marker + flag) + + inputs (txid, vout, scriptSig, sequence) * number initiator inputs * 4 + + funding_output * 4 + + change_output * 4 + + max(number initiator inputs + * minimum witness weight, + actual witness weight of all inputs) + + initiator_weight = (1 + 1 + 4 + 4) * 4 + + 2 + + (32 + 4 + 1 + 4) * 1 * 4 + + 43 * 4 + + 31 * 4 + + max(1 * 107, 71) + + initiator_weight = 609 + + initiator_fees = initiator_weight * feerate + initiator_fees = 609 * 253 / 1000 + initiator_fees = 155 sats + + change = total_funding + - funding_sats + - fees + + change = 2 5000 0000 + - 2 0000 0000 + - 155 + + change = 4999 9845 + + as hex: e5effa0200000000 +``` + +### Accepter's fees and change: +``` + contributor_weight = inputs(txid, vout, scriptSig, sequence) + * number contributor inputs * 4 + + change_output * 4 + + max(number contributor inputs + * minimum witness weight, + actual witness weight of all inputs) + + contributor_weight = (32 + 4 + 1 + 4) * 1 * 4 + + 31 * 4 + + max(1 * 107, 99) + + contributor_weight = 395 + + contributor_fees = contributor_weight * feerate + contributor_fees = 398 * 253 / 1000 + contributor_fees = 100 sats + + change = total_funding + - funding_sats + - fees + + change = 2 5000 0000 + - 2 0000 0000 + - 100 + + change = 4999 9900 + + as hex: 1cf0fa0200000000 +``` + +### Unsigned Funding Transaction: + +``` +0200000002b932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430200000000fdffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430000000000fdffffff03e5effa02000000001600141ca1cca8855bad6bc1ea5436edd8cff10b7e448b1cf0fa020000000016001444cb0c39f93ecc372b5851725bd29d865d333b100084d71700000000220020297b92c238163e820b82486084634b4846b86a3c658d87b9384192e6bea98ec578000000 +``` + +### Expected Opener's `tx_signatures`: + +``` + tx_signatures{ + channel_id: xxx, + txid: "5ca4e657c1aa9d069ea4a5d712045d233a7d7c52738cb02993637289e6386057", + num_witnesses: 1, + witness_stack[{ + num_input_witness: 2, + witness_element:[ + { + len: 32, + witness: "68656c6c6f2074686572652c2074686973206973206120626974636f6e212121" + },{ + len: 39, + witness: "82012088a820add57dfe5277079d069ca4ad4893c96de91f88ffb981fdc6a2a34d5336c66aff87" + }] + }] + } +``` + +### Expected Accepter's `tx_signatures`: + +``` + tx_signatures{ + channel_id: xxx, + txid: "5ca4e657c1aa9d069ea4a5d712045d233a7d7c52738cb02993637289e6386057", + num_witnesses: 1, + witness_stack[{ + num_input_witness: 2, + witness_element:[ + { + len: 71, + witness: "304402207de9ba56bb9f641372e805782575ee840a899e61021c8b1572b3ec1d5b5950e9022069e9ba998915dae193d3c25cb89b5e64370e6a3a7755e7f31cf6d7cbc2a49f6d01", + },{ + len: 33, + witness: "034695f5b7864c580bf11f9f8cb1a94eb336f2ce9ef872d2ae1a90ee276c772484" + }] + }] + } +``` + +#### Signed Funding Transaction: + +Note locktime is set to 120. + +``` +02000000000102b932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430200000000fdffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430000000000fdffffff03e5effa02000000001600141ca1cca8855bad6bc1ea5436edd8cff10b7e448b1cf0fa020000000016001444cb0c39f93ecc372b5851725bd29d865d333b100084d71700000000220020297b92c238163e820b82486084634b4846b86a3c658d87b9384192e6bea98ec50247304402207de9ba56bb9f641372e805782575ee840a899e61021c8b1572b3ec1d5b5950e9022069e9ba998915dae193d3c25cb89b5e64370e6a3a7755e7f31cf6d7cbc2a49f6d0121034695f5b7864c580bf11f9f8cb1a94eb336f2ce9ef872d2ae1a90ee276c772484022068656c6c6f2074686572652c2074686973206973206120626974636f6e2121212782012088a820add57dfe5277079d069ca4ad4893c96de91f88ffb981fdc6a2a34d5336c66aff8778000000 +``` + # References # Authors diff --git a/09-features.md b/09-features.md index 730e6cd72..95c59e93a 100644 --- a/09-features.md +++ b/09-features.md @@ -44,6 +44,7 @@ The Context column decodes as follows: | 22/23 | `option_anchors_zero_fee_htlc_tx` | Anchor commitment type with zero fee HTLC transactions | IN | `option_static_remotekey` | [BOLT #3][bolt03-htlc-tx], [lightning-dev][ml-sighash-single-harmful] | | 24/25 | `option_route_blinding` | Node supports blinded paths | IN9 | `var_onion_optin` | [BOLT #4](bolt04-route-blinding) | | 26/27 | `option_shutdown_anysegwit` | Future segwit versions allowed in `shutdown` | IN | | [BOLT #2][bolt02-shutdown] | +| 28/29 | `option_dual_fund` | Use v2 of channel open, enables dual funding | IN | | [BOLT #2](02-peer-protocol.md) | | 38/39 | `option_onion_messages` | Can forward onion messages | IN | | [BOLT #7](04-onion-routing.md#onion-messages) | | 44/45 | `option_channel_type` | Node supports the `channel_type` field in open/accept | IN | | [BOLT #2](02-peer-protocol.md#the-open_channel-message) | | 46/47 | `option_scid_alias` | Supply channel aliases for routing | IN | | [BOLT #2][bolt02-channel-ready] | diff --git a/tools/spellcheck.sh b/tools/spellcheck.sh index fb309315f..709913db3 100755 --- a/tools/spellcheck.sh +++ b/tools/spellcheck.sh @@ -68,7 +68,8 @@ do -e 's/0x[a-fA-F0-9 ]\+//g' \ -e 's/[a-fA-F0-9]\{20,\}//g' \ -e 's/^ .*_htlcs//g' \ - -e 's/ \(bc\|tb\)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]\+//g' \ + -e 's/ ln\(bc\|tb\)[0-9munp]*1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]\+//g' \ + -e 's/ \(bc\|tb\|bcrt\)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]\+//g' \ -e 's/pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny//' \ -e 's/[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]\{20,\}//g' < $f | tee /tmp/`basename $f`.aspell | aspell -l en_US --home-dir ${homedir} list) if [ -n "$WORDS" ]; then From 6ce7491908f5c66f5e5fc28343544505ae62c018 Mon Sep 17 00:00:00 2001 From: niftynei Date: Mon, 31 Jan 2022 15:32:44 -0600 Subject: [PATCH 03/21] v2 opens: add a `tx_abort` message Requested-by: @t-bast --- 02-peer-protocol.md | 47 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 4141665af..21dcad4af 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -438,11 +438,11 @@ The sender: of the previously constructed transaction, rounded down. The recipient: - - MUST respond either by failing the negotiation or with `tx_ack_rbf`. - - MUST fail the negotiation if: + - MUST respond either with `tx_abort` or with `tx_ack_rbf` + - MUST respond with `tx_abort` if: - the `feerate` is not greater than 25/24 times `feerate` of the last successfully constructed transaction - - MAY fail the negotiation for any reason + - MAY send `tx_abort` for any reason #### Rationale @@ -477,7 +477,7 @@ made in the previously completed transaction. #### Requirements The recipient: - - MUST either fail the negotiation or transmit a `tx_add_input` message, + - MUST respond with `tx_abort` or with a `tx_add_input` message, restarting the interactive tx collaboration protocol. #### Rationale @@ -492,6 +492,45 @@ a large feerate change, instead sets their `funding_output_contribution` to zero, and decline to participate further in the transaction (by not contributing, they may obtain incoming liquidity at no cost). +### The `tx_abort` Message + +1. type: 74 (`tx_abort`) +2. data: + * [`channel_id`:`channel_id`] + * [`u16`:`len`] + * [`len*byte`:`data`] + +#### Requirements + +A sending node: + - MUST NOT have already transmitted `tx_signatures` + - SHOULD forget the current negotiation and reset their state. + +A receiving node: + - if they have already sent `tx_signatures` to the peer: + - MUST NOT forget the channel until any inputs to the negotiated tx + have been spent. + - if they have not sent `tx_signatures`: + - SHOULD forget the current negotiation and reset their state. + - if they have not sent `tx_abort`: + - MUST echo back `tx_abort` + +#### Rationale + +A receiving node, if they've already sent their `tx_signatures` has no guarantee +that the transaction won't be signed and published by their peer. They must remember +the transaction and channel (if appropriate) until the transaction is no longer +eligible to be spent (i.e. any input has been spent in a different transaction). + +The `tx_abort` message allows for the cancellation of an in progress negotiation, +and a return to the initial starting state. It is distinct from the `error` +message, which triggers a channel close. + +Echoing back `tx_abort` allows the peer to ack that they've seen the abort message, +permitting the originating peer to terminate the in-flight process without +worrying about stale messages. + + ## Channel Establishment v1 After authenticating and initializing a connection ([BOLT #8](08-transport.md) From 11b845162a6e2e21fed8f97640b17243308f15d2 Mon Sep 17 00:00:00 2001 From: t-bast Date: Wed, 26 Oct 2022 09:03:49 +0200 Subject: [PATCH 04/21] Clarify RBF funding requirements --- 02-peer-protocol.md | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 21dcad4af..f7ddf2760 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -436,12 +436,14 @@ completed. The sender: - MUST set `feerate` greater than or equal to 25/24 times the `feerate` of the previously constructed transaction, rounded down. + - If it contributes to the transaction's funding output: + - MUST set `funding_output_contribution` The recipient: - MUST respond either with `tx_abort` or with `tx_ack_rbf` - MUST respond with `tx_abort` if: - - the `feerate` is not greater than 25/24 times `feerate` of the last - successfully constructed transaction + - the `feerate` is not greater than or equal to 25/24 times `feerate` + of the last successfully constructed transaction - MAY send `tx_abort` for any reason #### Rationale @@ -459,7 +461,8 @@ the attempt MUST be abandoned. `funding_output_contribution` is the amount of satoshis that this peer will contribute to the funding output of the transaction, when there is such an output. Note that it may be different from the contribution -made in the previously completed transaction. +made in the previously completed transaction. If omitted, the sender is +not contributing to the funding output. ### The `tx_ack_rbf` Message @@ -476,6 +479,10 @@ made in the previously completed transaction. #### Requirements +The sender: + - If it contributes to the transaction's funding output: + - MUST set `funding_output_contribution` + The recipient: - MUST respond with `tx_abort` or with a `tx_add_input` message, restarting the interactive tx collaboration protocol. @@ -485,12 +492,13 @@ The recipient: `funding_output_contribution` is the amount of satoshis that this peer will contribute to the funding output of the transaction, when there is such an output. Note that it may be different from the contribution -made in the previously completed transaction. +made in the previously completed transaction. If omitted, the sender is +not contributing to the funding output. It's recommended that a peer, rather than fail the RBF negotiation due to -a large feerate change, instead sets their `funding_output_contribution` to -zero, and decline to participate further in the transaction (by not -contributing, they may obtain incoming liquidity at no cost). +a large feerate change, instead stop contributing to the funding output, +and decline to participate further in the transaction (by not contributing, +they may obtain incoming liquidity at no cost). ### The `tx_abort` Message From a810c678d0c986074f02c7e6c02cbf1c002ebc35 Mon Sep 17 00:00:00 2001 From: t-bast Date: Tue, 11 Apr 2023 10:42:20 +0200 Subject: [PATCH 05/21] Use signed amounts in RBF messages While dual funding only needs unsigned funding amounts, other protocols that leverage interactive-tx may use signed funding amounts, for example to take funds out of an existing channel (splice-out). It is thus more future-proof to use signed amounts in `tx_init_rbf` and `tx_ack_rbf`. --- 01-messaging.md | 110 ++++++++++++++++++++++++++++++++++++++++++++ 02-peer-protocol.md | 4 +- 2 files changed, 112 insertions(+), 2 deletions(-) diff --git a/01-messaging.md b/01-messaging.md index f7e38f758..94ede859a 100644 --- a/01-messaging.md +++ b/01-messaging.md @@ -29,6 +29,7 @@ All data fields are unsigned big-endian unless otherwise specified. * [Appendix A: BigSize Test Vectors](#appendix-a-bigsize-test-vectors) * [Appendix B: Type-Length-Value Test Vectors](#appendix-b-type-length-value-test-vectors) * [Appendix C: Message Extension](#appendix-c-message-extension) + * [Appendix D: Signed Integers Test Vectors](#appendix-d-signed-integers-test-vectors) * [Acknowledgments](#acknowledgments) * [References](#references) * [Authors](#authors) @@ -220,9 +221,16 @@ receiver to parse individual elements from `value`. Various fundamental types are referred to in the message specifications: * `byte`: an 8-bit byte +* `s8`: an 8-bit signed integer * `u16`: a 2 byte unsigned integer +* `s16`: a 2 byte signed integer * `u32`: a 4 byte unsigned integer +* `s32`: a 4 byte signed integer * `u64`: an 8 byte unsigned integer +* `s64`: an 8 byte signed integer + +Signed integers use standard big-endian two's complement representation +(see test vectors [below](#appendix-d-signed-integers-test-vectors)). For the final value in TLV records, truncated integers may be used. Leading zeros in truncated integers MUST be omitted: @@ -967,6 +975,108 @@ Note that when messages are signed, the _extension_ is part of the signed bytes. Nodes should store the _extension_ bytes even if they don't understand them to be able to correctly verify signatures. +## Appendix D: Signed Integers Test Vectors + +The following test vector show how signed integers (`s8`, `s16`, `s32` +and `s64`) are encoded using big-endian two's complement. + +```json +[ + { + "value": 0, + "bytes": "00" + }, + { + "value": 42, + "bytes": "2a" + }, + { + "value": -42, + "bytes": "d6" + }, + { + "value": 127, + "bytes": "7f" + }, + { + "value": -128, + "bytes": "80" + }, + { + "value": 128, + "bytes": "0080" + }, + { + "value": -129, + "bytes": "ff7f" + }, + { + "value": 15000, + "bytes": "3a98" + }, + { + "value": -15000, + "bytes": "c568" + }, + { + "value": 32767, + "bytes": "7fff" + }, + { + "value": -32768, + "bytes": "8000" + }, + { + "value": 32768, + "bytes": "00008000" + }, + { + "value": -32769, + "bytes": "ffff7fff" + }, + { + "value": 21000000, + "bytes": "01406f40" + }, + { + "value": -21000000, + "bytes": "febf90c0" + }, + { + "value": 2147483647, + "bytes": "7fffffff" + }, + { + "value": -2147483648, + "bytes": "80000000" + }, + { + "value": 2147483648, + "bytes": "0000000080000000" + }, + { + "value": -2147483649, + "bytes": "ffffffff7fffffff" + }, + { + "value": 500000000000, + "bytes": "000000746a528800" + }, + { + "value": -500000000000, + "bytes": "ffffff8b95ad7800" + }, + { + "value": 9223372036854775807, + "bytes": "7fffffffffffffff" + }, + { + "value": -9223372036854775808, + "bytes": "8000000000000000" + } +] +``` + ## Acknowledgments [ TODO: (roasbeef); fin ] diff --git a/02-peer-protocol.md b/02-peer-protocol.md index f7ddf2760..04e338cb5 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -429,7 +429,7 @@ completed. 2. types: 1. type: 0 (`funding_output_contribution`) 2. data: - * [`tu64`:`satoshis`] + * [`s64`:`satoshis`] #### Requirements @@ -475,7 +475,7 @@ not contributing to the funding output. 2. types: 1. type: 0 (`funding_output_contribution`) 2. data: - * [`tu64`:`satoshis`] + * [`s64`:`satoshis`] #### Requirements From 0749591fac6be6c5ca8ea258ee8d70cbb446ac6a Mon Sep 17 00:00:00 2001 From: niftynei Date: Fri, 16 Dec 2022 13:33:09 -0600 Subject: [PATCH 06/21] peer-protocol: send first+second commit point in openchanv2 + accept Repeat the second commit point in the initial openchannel2 + acceptchannel2 messages. Suggested-By: @pm47 --- 02-peer-protocol.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 04e338cb5..4594ac3ba 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -1119,6 +1119,7 @@ This message initiates the v2 channel establishment workflow. * [`point`:`delayed_payment_basepoint`] * [`point`:`htlc_basepoint`] * [`point`:`first_per_commitment_point`] + * [`point`:`second_per_commitment_point`] * [`byte`:`channel_flags`] * [`opening_tlvs`:`tlvs`] @@ -1173,6 +1174,9 @@ whichever is greater. Note that `push_msat` has been omitted. +`second_per_commitment_point` is now sent here (as well as in `channel_ready`) +as a convenience for implementations. + ### The `accept_channel2` Message This message contains information about a node and indicates its @@ -1194,6 +1198,7 @@ acceptance of the new channel. * [`point`:`delayed_payment_basepoint`] * [`point`:`htlc_basepoint`] * [`point`:`first_per_commitment_point`] + * [`point`:`second_per_commitment_point`] * [`accept_tlvs`:`tlvs`] 1. `tlv_stream`: `accept_tlvs` From 4caa100e8370a2a6f825118eefa956d27c4f05f3 Mon Sep 17 00:00:00 2001 From: niftynei Date: Fri, 16 Dec 2022 14:00:57 -0600 Subject: [PATCH 07/21] v2 opens: proposal to get rid of the minimum estimated fee Prior versions of the v2 dual-funding protocol assumed a 'minimum fee' payment for any witness stack of any input, as a way to simplify fee checks. The suggested min feerate didn't make sense for taproot spend paths etc; instead we remove this check entirely. --- 02-peer-protocol.md | 3 ++- 03-transactions.md | 58 --------------------------------------------- 2 files changed, 2 insertions(+), 59 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 4594ac3ba..ddefc8c00 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -211,6 +211,7 @@ The sending node: - MUST send even `serial_id`s - if is the *non-initiator*: - MUST send odd `serial_id`s + - MUST provide a best estimate for the weight of the witness for this input The receiving node: - MUST add all received inputs to the transaction @@ -411,7 +412,7 @@ prefixed with its length (since it is already specified in the `len` field). While the `minimum fee` is calculated and verified at `tx_complete` conclusion, it is possible for the fee for the exchanged witness data to be underpaid. It is the responsibility of the sending peer to correctly account for the -required fee, e.g. a multisig witness stack whose weight exceeds 107. +required fee. ### The `tx_init_rbf` Message diff --git a/03-transactions.md b/03-transactions.md index 4ebd028b8..fd3fa865e 100644 --- a/03-transactions.md +++ b/03-transactions.md @@ -873,64 +873,6 @@ Multiplying non-witness data by 4 results in a weight of: overall_weight = funding_transaction_weight + witness_weight -### Calculating Fees for Collaborative Transaction Construction - -Every participant in a collaborative transaction covers the fees for -their own inputs and outputs. The initiator also provides funds to -cover for the common transaction fields. - -Upon successful exchange of `tx_complete` messages, each peer must at -least cover a minimum estimated fee. Here is how to calculate the minimum -fee for each participant. - -The minimum witness weight for an input is 107. - -In the following, the initiator has provided one input (P2WPKH), one change output -(P2WPKH), and the funding output. The contributor has provided two -inputs (P2WPKH) and two change outputs (P2WPKH). - -Assuming a `feerate` of 253 per kiloweight, the initiator's minimum fee is -calculated as follows. Note that the feerate is rounded up to the nearest satoshi. - - initiator_weight = transaction_fields * 4 - + segwit_fields - + p2wpkh_input * 4 - + funding_output * 4 - + p2wpkh_output * 4 - + input_count * 107 (minimum witness weight) - - initiator_weight = 10 * 4 - + 2 - + 41 * 4 - + 43 * 4 - + 31 * 4 - + 107 - - initiator_weight = 609 - - initiator_fees = initiator_weight * feerate - initiator_fees = 609 * 253 / 1000 - initiator_fees = 155 sats - -The contributor's minimum fee is calculated as follows. - - contributor_weight = 2 * p2wpkh_input * 4 - + 2 * p2wpkh_output * 4 - + input_count * 107 (minimum witness weight) - - contributor_weight = 2 * 41 * 4 - + 2 * 31 * 4 - + 2 * 107 - - contributor_weight = 790 - - contributor_fees = contributor_weight * feerate - contributor_fees = 790 * 253 / 1000 - contributor_fees = 200 sats - -This is an estimated fee. The peer MUST at least contribute the estimated fee, -and MUST exceed the minimum fee in the case that their witness weight is greater -than the estimated weight of 107 per input. ## Expected Weight of the Commitment Transaction From c2ac8a71de05cc16de25d0d7388bf697b87aa55b Mon Sep 17 00:00:00 2001 From: t-bast Date: Mon, 24 Oct 2022 10:35:48 +0200 Subject: [PATCH 08/21] Add `require_confirmed_inputs` TLV This lets any side of the protocol require the other side to use confirmed inputs, to avoid paying the fees of a low feerate unconfirmed ancestor. --- 02-peer-protocol.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index ddefc8c00..697747533 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -1132,6 +1132,7 @@ This message initiates the v2 channel establishment workflow. 1. type: 1 (`channel_type`) 2. data: * [`...*byte`:`type`] + 1. type: 2 (`require_confirmed_inputs`) Rationale and Requirements are the same as for [`open_channel`](#the-open_channel-message), with the following additions. @@ -1144,11 +1145,15 @@ If nodes have negotiated `option_dual_fund`: The sending node: - MUST set `funding_feerate_perkw` to the feerate for this transaction + - If it requires the receiving node to only use confirmed inputs: + - MUST set `require_confirmed_inputs` The receiving node: - MAY fail the negotiation if: - the `locktime` is unacceptable - the `funding_feerate_perkw` is unacceptable + - MUST fail the negotiation if: + - `require_confirmed_inputs` is set but it cannot provide confirmed inputs #### Rationale @@ -1178,6 +1183,10 @@ Note that `push_msat` has been omitted. `second_per_commitment_point` is now sent here (as well as in `channel_ready`) as a convenience for implementations. +The sending node may require the other participant to only use confirmed inputs. +This ensures that the sending node doesn't end up paying the fees of a low +feerate unconfirmed ancestor of one of the other participant's inputs. + ### The `accept_channel2` Message This message contains information about a node and indicates its @@ -1210,6 +1219,7 @@ acceptance of the new channel. 1. type: 1 (`channel_type`) 2. data: * [`...*byte`:`type`] + 1. type: 2 (`require_confirmed_inputs`) Rationale and Requirements are the same as listed above, for [`accept_channel`](#the-accept_channel-message) with the following @@ -1220,6 +1230,12 @@ additions. The accepting node: - MUST use the `temporary_channel_id` of the `open_channel2` message - MAY respond with a `funding_satoshis` value of zero. + - If it requires the opening node to only use confirmed inputs: + - MUST set `require_confirmed_inputs` + +The receiving node: + - MUST fail the negotiation if: + - `require_confirmed_inputs` is set but it cannot provide confirmed inputs #### Rationale @@ -1240,7 +1256,11 @@ protocol, with the following additional caveats. #### The `tx_add_input` Message -No additional caveats or requirements. +##### Requirements + +The sending node: + - if the receiver set `require_confirmed_inputs` in `open_channel2` or `accept_channel2`: + - MUST NOT send a `tx_add_input` that contains an unconfirmed input #### The `tx_add_output` Message @@ -1265,12 +1285,15 @@ Upon receipt of consecutive `tx_complete`s, the receiving node: `open_channel2`.`funding_satoshis` and `accept_channel2`. `funding_satoshis` - the value of the funding output is less than the `dust_limit` - - if it is an RBF attempt: + - if it is an RBF attempt: - MUST fail the negotiation if: - the transaction's total fees is less than the last successfully negotiated transaction's fees - the transaction does not share a common input with all previous funding transactions + - if it has sent `require_confirmed_inputs` in `open_channel2` or `accept_channel2`: + - MUST fail the negotiation if: + - one of the inputs added by the other peer is unconfirmed ### The `commitment_signed` Message From c5f3c75ec3b413af6f8eccaf0b86147cd6105bec Mon Sep 17 00:00:00 2001 From: t-bast Date: Fri, 10 Feb 2023 10:59:02 +0100 Subject: [PATCH 09/21] Add section about liquidity griefing This issue is non-trivial and worth mentioning, otherwise implementations may forget to handle this which would result in an easy way of attacking node's on-chain liquidity, creating a large opportunity cost. --- .aspell.en.pws | 1 + 02-peer-protocol.md | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/.aspell.en.pws b/.aspell.en.pws index a4d459d96..6744cc297 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -424,3 +424,4 @@ prevtx ints replaceability disincentivize +UTXOs diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 697747533..58941b365 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -211,7 +211,6 @@ The sending node: - MUST send even `serial_id`s - if is the *non-initiator*: - MUST send odd `serial_id`s - - MUST provide a best estimate for the weight of the witness for this input The receiving node: - MUST add all received inputs to the transaction @@ -243,6 +242,28 @@ this input spends. Used to verify that the input is non-malleable. replaceability, and the same value should be used across implementations to avoid on-chain fingerprinting. +#### Liquidity griefing + +When sending `tx_add_input`, senders have no guarantee that the remote node +will complete the protocol in a timely manner. Malicious remote nodes could +delay messages or stop responding, which can result in a partially created +transaction that cannot be broadcast by the honest node. If the honest node +is locking the corresponding UTXO exclusively for this remote node, this can +be exploited to lock up the honest node's liquidity. + +It is thus recommended that implementations keep UTXOs unlocked and actively +reuse them in concurrent sessions, which guarantees that transactions created +with honest nodes double-spend pending transactions with malicious nodes at +no additional cost for the honest node. + +Unfortunately, this will also create conflicts between concurrent sessions +with honest nodes. This is a reasonable trade-off though because: + +* on-chain funding attempts are relatively infrequent operations +* honest nodes should complete the protocol quickly, reducing the risk of + conflicts +* failed attempts can simply be retried at no cost + ### The `tx_add_output` Message This message adds a transaction output. @@ -539,7 +560,6 @@ Echoing back `tx_abort` allows the peer to ack that they've seen the abort messa permitting the originating peer to terminate the in-flight process without worrying about stale messages. - ## Channel Establishment v1 After authenticating and initializing a connection ([BOLT #8](08-transport.md) From 36c04c8aca48e04d1fba64d968054eba221e63a1 Mon Sep 17 00:00:00 2001 From: t-bast Date: Tue, 28 Mar 2023 15:08:28 +0200 Subject: [PATCH 10/21] Store state when sending `commitment_signed` If we only store state when sending `tx_signatures`, there are cases where we cannot reconcile states if a disconnection occurs during the signing steps: one side will have sent `tx_signatures` and thus must wait for the transaction to be spent or double-spent, while the other side has already forgotten that channel because they haven't sent `tx_signatures`. This is fixed by storing state when sending `commitment_signed`, and adding a `next_funding_txid` field to `channel_reestablish` to ask our peer to retransmit signatures that we haven't received. --- 02-peer-protocol.md | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 58941b365..aee5cd327 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -1327,6 +1327,7 @@ for [`commitment_signed`](#commiting-updates-so-far-commitment_signed) with the The sending node: - MUST send zero HTLCs. + - MUST remember the details of this funding transaction. The receiving node: - if the message has one or more HTLCs: @@ -1341,6 +1342,10 @@ The receiving node: The first commitment transaction has no HTLCs. +Once peers are ready to exchange commitment signatures, they must remember +the details of the funding transaction to allow resuming the signatures +exchange if a disconnection happens. + ### Sharing funding signatures: `tx_signatures` After a valid `commitment_signed` has been received @@ -2313,6 +2318,12 @@ messages are), they are independent of requirements here. * [`32*byte`:`your_last_per_commitment_secret`] * [`point`:`my_current_per_commitment_point`] +1. `tlv_stream`: `channel_reestablish_tlvs` +2. types: + 1. type: 0 (`next_funding`) + 2. data: + * [`sha256`:`next_funding_txid`] + `next_commitment_number`: A commitment number is a 48-bit incrementing counter for each commitment transaction; counters are independent for each peer in the channel and start at 0. @@ -2369,18 +2380,21 @@ The sending node: - MUST set `your_last_per_commitment_secret` to all zeroes - otherwise: - MUST set `your_last_per_commitment_secret` to the last `per_commitment_secret` it received + - if it has sent `commitment_signed` for an interactive transaction construction but + it has not received `tx_signatures`: + - MUST set `next_funding_txid` to the txid of that interactive transaction. + - otherwise: + - MUST NOT set `next_funding_txid`. A node: - if `next_commitment_number` is 1 in both the `channel_reestablish` it sent and received: - MUST retransmit `channel_ready`. - - MUST retransmit `tx_signatures` if it is using channel establishment v2. - otherwise: - MUST NOT retransmit `channel_ready`, but MAY send `channel_ready` with a different `short_channel_id` `alias` field. - upon reconnection: - MUST ignore any redundant `channel_ready` it receives. - - MUST ignore any redundant `tx_signatures` it receives. - if `next_commitment_number` is equal to the commitment number of the last `commitment_signed` message the receiving node has sent: - MUST reuse the same commitment number for its next `commitment_signed`. @@ -2430,6 +2444,20 @@ A node: do not match the expected values): - SHOULD send an `error` and fail the channel. +A receiving node: + - if `next_funding_txid` is set: + - if `next_funding_txid` matches the latest interactive funding transaction: + - if it has not received `tx_signatures` for that funding transaction: + - MUST retransmit its `commitment_signed` for that funding transaction. + - if it has already received `commitment_signed` and it should sign first, + as specified in the [`tx_signatures` requirements](#the-tx_signatures-message): + - MUST send its `tx_signatures` for that funding transaction. + - if it has already received `tx_signatures` for that funding transaction: + - MUST send its `tx_signatures` for that funding transaction. + - otherwise: + - MUST send `tx_abort` to let the sending node know that they can forget + this funding transaction. + A node: - MUST NOT assume that previously-transmitted messages were lost, - if it has sent a previous `commitment_signed` message: @@ -2521,6 +2549,11 @@ fall-behind detection. An implementation can offer both, however, and fall back to the `option_data_loss_protect` behavior if `option_static_remotekey` is not negotiated. +`next_funding_txid` allows peers to finalize the signing steps of an +interactive transaction construction, or safely abort that transaction +if it was not signed by one of the peers, who has thus already removed +it from its state. + # Authors [ FIXME: Insert Author List ] From c33cdc85d4e6b86d6f17ef93e57072b2ec5d5432 Mon Sep 17 00:00:00 2001 From: Duncan Dean Date: Wed, 29 Mar 2023 22:34:17 +0200 Subject: [PATCH 11/21] Use bitcoin wire encoding for witnesses --- 02-peer-protocol.md | 19 +++++++------------ 03-transactions.md | 30 ++++++++---------------------- 2 files changed, 15 insertions(+), 34 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index aee5cd327..a7efe4494 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -388,14 +388,9 @@ the byte size of the input and output counts on the transaction to one (1). * [`channel_id`:`channel_id`] * [`sha256`:`txid`] * [`u16`:`num_witnesses`] - * [`num_witnesses*witness_stack`:`witnesses`] + * [`num_witnesses*witness`:`witnesses`] -1. subtype: `witness_stack` -2. data: - * [`u16`:`num_witness_elements`] - * [`num_witness_elements*witness_element`:`witness_elements`] - -1. subtype: `witness_element` +1. subtype: `witness` 2. data: * [`u16`:`len`] * [`len*byte`:`witness_data`] @@ -413,11 +408,11 @@ The sending node: The receiving node: - MUST fail the negotiation if: - - the message contains an empty `witness_stack` + - the message contains an empty `witness` - the number of `witnesses` does not equal the number of inputs added by the sending node - the `txid` does not match the txid of the transaction - - the witnesses are non-standard + - the `witnesses` are non-standard - SHOULD apply the `witnesses` to the transaction and broadcast it - MUST reply with their `tx_signatures` if not already transmitted @@ -427,8 +422,8 @@ A strict ordering is used to decide which peer sends `tx_signatures` first. This prevents deadlocks where each peer is waiting for the other peer to send `tx_signatures`, and enables multiparty tx collaboration. -`witness_data` is the data for a witness element in a witness stack, not -prefixed with its length (since it is already specified in the `len` field). +The `witness_data` is encoded as per bitcoin's wire protocol (a CompactSize number +of elements, with each element a CompactSize length and that many bytes following). While the `minimum fee` is calculated and verified at `tx_complete` conclusion, it is possible for the fee for the exchanged witness data to be underpaid. @@ -1363,7 +1358,7 @@ The sending node: - MUST NOT send a `tx_signatures` message The receiving node: - - if the `witness_stack` weight lowers the effective `feerate` + - if the `witness` weight lowers the effective `feerate` below the the *opener*'s feerate for the funding transaction: - SHOULD broadcast their commitment transaction, closing the channel. - SHOULD apply `witnesses` to the funding transaction and broadcast it diff --git a/03-transactions.md b/03-transactions.md index fd3fa865e..1437f8e3f 100644 --- a/03-transactions.md +++ b/03-transactions.md @@ -2940,17 +2940,10 @@ Opener's fees and change: channel_id: xxx, txid: "5ca4e657c1aa9d069ea4a5d712045d233a7d7c52738cb02993637289e6386057", num_witnesses: 1, - witness_stack[{ - num_input_witness: 2, - witness_element:[ - { - len: 32, - witness: "68656c6c6f2074686572652c2074686973206973206120626974636f6e212121" - },{ - len: 39, - witness: "82012088a820add57dfe5277079d069ca4ad4893c96de91f88ffb981fdc6a2a34d5336c66aff87" - }] - }] + witness[{ + len: 74, + witness_data: "022068656c6c6f2074686572652c2074686973206973206120626974636f6e2121212782012088a820add57dfe5277079d069ca4ad4893c96de91f88ffb981fdc6a2a34d5336c66aff87" + }] } ``` @@ -2961,17 +2954,10 @@ Opener's fees and change: channel_id: xxx, txid: "5ca4e657c1aa9d069ea4a5d712045d233a7d7c52738cb02993637289e6386057", num_witnesses: 1, - witness_stack[{ - num_input_witness: 2, - witness_element:[ - { - len: 71, - witness: "304402207de9ba56bb9f641372e805782575ee840a899e61021c8b1572b3ec1d5b5950e9022069e9ba998915dae193d3c25cb89b5e64370e6a3a7755e7f31cf6d7cbc2a49f6d01", - },{ - len: 33, - witness: "034695f5b7864c580bf11f9f8cb1a94eb336f2ce9ef872d2ae1a90ee276c772484" - }] - }] + witness[{ + len: 107, + witness_data: "0247304402207de9ba56bb9f641372e805782575ee840a899e61021c8b1572b3ec1d5b5950e9022069e9ba998915dae193d3c25cb89b5e64370e6a3a7755e7f31cf6d7cbc2a49f6d0121034695f5b7864c580bf11f9f8cb1a94eb336f2ce9ef872d2ae1a90ee276c772484" + }] } ``` From 9f85945480802edb92eba0339a44302d5847e17c Mon Sep 17 00:00:00 2001 From: niftynei Date: Thu, 9 Nov 2023 22:09:44 -0600 Subject: [PATCH 12/21] interactive-tx: highlight MUST of serial_id sorting Suggested-By: @dunxen --- 02-peer-protocol.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index a7efe4494..0518ff624 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -231,7 +231,7 @@ Each node must know the set of the transaction inputs. The *non-initiator* MAY omit this message. `serial_id` is a randomly chosen number which uniquely identifies this input. -Inputs in the constructed transaction are sorted by `serial_id`. +Inputs in the constructed transaction MUST be sorted by `serial_id`. `prevtx` is the serialized transaction that contains the output this input spends. Used to verify that the input is non-malleable. @@ -304,7 +304,7 @@ The receiving node: Each node must know the set of the transaction outputs. `serial_id` is a randomly chosen number which uniquely identifies this output. -Outputs in the constructed transaction are sorted by `serial_id`. +Outputs in the constructed transaction MUST be sorted by `serial_id`. `sats` is the satoshi value of the output. From d70552220d09f13bc6feac47d056167509a21583 Mon Sep 17 00:00:00 2001 From: Dustin Dettmer Date: Fri, 7 Apr 2023 14:18:59 -0400 Subject: [PATCH 13/21] Bolt 2: Make interactive-tx explicitly use SIGHASH_ALL This was previously assumed but adding it to the spec makes it explicit, should we ever want to change it in the future. Suggested-By: @morehouse --- 02-peer-protocol.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 0518ff624..b9faa7c15 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -416,6 +416,9 @@ The receiving node: - SHOULD apply the `witnesses` to the transaction and broadcast it - MUST reply with their `tx_signatures` if not already transmitted +Both nodes: + - MUST sign the transaction using SIGHASH_ALL + #### Rationale A strict ordering is used to decide which peer sends `tx_signatures` first. From e5b267728f29d42a5d528884260e26fd526a3dba Mon Sep 17 00:00:00 2001 From: niftynei Date: Thu, 9 Nov 2023 22:27:30 -0600 Subject: [PATCH 14/21] tx-abort: port over meaning of the `data` field from `warning` `tx_abort`'s structure comes from the `warning`/`error` messages, but we failed to port over the rationale/rules for the `data` field. Suggested-By: @morehouse --- 02-peer-protocol.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index b9faa7c15..0c02a4110 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -533,6 +533,10 @@ they may obtain incoming liquidity at no cost). A sending node: - MUST NOT have already transmitted `tx_signatures` - SHOULD forget the current negotiation and reset their state. + - MAY send an empty `data` field. + - when failure was caused by an invalid signature check: + - SHOULD include the raw, hex-encoded transaction in reply to a + `tx_signatures` or `commitment_signed` message. A receiving node: - if they have already sent `tx_signatures` to the peer: @@ -542,6 +546,10 @@ A receiving node: - SHOULD forget the current negotiation and reset their state. - if they have not sent `tx_abort`: - MUST echo back `tx_abort` + - if `data` is not composed solely of printable ASCII characters (For + reference: the printable character set includes byte values 32 through + 126, inclusive): + - SHOULD NOT print out `data` verbatim. #### Rationale From 5edaaa6bfa8a55a49174c2083986619f26c08e5b Mon Sep 17 00:00:00 2001 From: niftynei Date: Thu, 9 Nov 2023 22:37:41 -0600 Subject: [PATCH 15/21] tx-complete: clarify that the total input/total output incl funding Found-by: @morehouse --- 02-peer-protocol.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 0c02a4110..6dd530fd6 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -359,7 +359,9 @@ The nodes: The receiving node: - MUST use the negotiated inputs and outputs to construct a transaction - MUST fail the negotiation if: - - the peer's total input satoshis is less than their outputs + - the peer's total input satoshis is less than their outputs. One MUST + account for the peer's portion of the funding output when verifying + compliance with this requirement. - the peer's paid feerate does not meet or exceed the agreed `feerate` (based on the `minimum fee`). - if is the *non-initiator*: From 820852eb24bb80b7ff4774cf9d0422f526ca2c18 Mon Sep 17 00:00:00 2001 From: niftynei Date: Thu, 9 Nov 2023 22:38:48 -0600 Subject: [PATCH 16/21] nit: verbiage + wording Suggested-By: @morehouse --- 02-peer-protocol.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 6dd530fd6..ed5403dad 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -1313,7 +1313,7 @@ Upon receipt of consecutive `tx_complete`s, the receiving node: `open_channel2`.`funding_satoshis` and `accept_channel2`. `funding_satoshis` - the value of the funding output is less than the `dust_limit` - - if it is an RBF attempt: + - if this is an RBF attempt: - MUST fail the negotiation if: - the transaction's total fees is less than the last successfully negotiated transaction's fees @@ -1372,7 +1372,7 @@ The sending node: The receiving node: - if the `witness` weight lowers the effective `feerate` - below the the *opener*'s feerate for the funding transaction: + below the *opener*'s feerate for the funding transaction: - SHOULD broadcast their commitment transaction, closing the channel. - SHOULD apply `witnesses` to the funding transaction and broadcast it - if has already sent or received a `channel_ready` message for this From e73ce64426cf05e161a9e17b0093b86f0a13405d Mon Sep 17 00:00:00 2001 From: niftynei Date: Thu, 9 Nov 2023 22:44:27 -0600 Subject: [PATCH 17/21] tx-signatures: address comments regarding underpyament of fees Reported-By: @morehouse --- 02-peer-protocol.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index ed5403dad..4002a5995 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -1371,13 +1371,13 @@ The sending node: - MUST NOT send a `tx_signatures` message The receiving node: + - if has already sent or received a `channel_ready` message for this + channel: + - MUST ignore this message - if the `witness` weight lowers the effective `feerate` below the *opener*'s feerate for the funding transaction: - SHOULD broadcast their commitment transaction, closing the channel. - SHOULD apply `witnesses` to the funding transaction and broadcast it - - if has already sent or received a `channel_ready` message for this - channel: - - MUST ignore this message #### Rationale @@ -1385,10 +1385,10 @@ A peer sends their `tx_signatures` after receiving a valid `commitment_signed` message, following the order specified in the [`tx_signatures` section](#the-tx_signatures-message). In the case where a peer provides valid witness data that causes their paid -feerate to fall beneath the `open_channel2.funding_feerate_perkw`, the protocol -should be aborted and the channel should be double-spent when there is a -productive opportunity to do so. This should disincentivize peers from -underpaying fees. +feerate to fall beneath the `open_channel2.funding_feerate_perkw`, the channel +should be considered failed and the channel should be double-spent when +there is a productive opportunity to do so. This should disincentivize +peers from underpaying fees. ### Fee bumping: `tx_init_rbf` and `tx_ack_rbf` From 5185bd02357e78869b5a1f9004f97933f51ed56d Mon Sep 17 00:00:00 2001 From: niftynei Date: Sun, 12 Nov 2023 15:10:12 -0600 Subject: [PATCH 18/21] dual-fund, nit: change wording on common input heuristic Suggested-By: @devrandom --- 02-peer-protocol.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 4002a5995..28afb9422 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -1317,8 +1317,8 @@ Upon receipt of consecutive `tx_complete`s, the receiving node: - MUST fail the negotiation if: - the transaction's total fees is less than the last successfully negotiated transaction's fees - - the transaction does not share a common input with all previous - funding transactions + - the transaction does not share at least one input with + each previous funding transaction - if it has sent `require_confirmed_inputs` in `open_channel2` or `accept_channel2`: - MUST fail the negotiation if: - one of the inputs added by the other peer is unconfirmed From afc4c72c02735068094f93b54410acba4df39528 Mon Sep 17 00:00:00 2001 From: niftynei Date: Sun, 12 Nov 2023 15:15:10 -0600 Subject: [PATCH 19/21] dual-fund, wording: move sighash_all into existing verbiage Suggested-By: @morehouse --- 02-peer-protocol.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 28afb9422..e2bddb89f 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -407,6 +407,7 @@ The sending node: - MUST order the `witnesses` by the `serial_id` of the input they correspond to - `num_witnesses`s MUST equal the number of inputs they added + - MUST use the `SIGHASH_ALL` (0x01) flag on each signature The receiving node: - MUST fail the negotiation if: @@ -415,12 +416,10 @@ The receiving node: added by the sending node - the `txid` does not match the txid of the transaction - the `witnesses` are non-standard + - a signature uses a flag that is not `SIGHASH_ALL` (0x01) - SHOULD apply the `witnesses` to the transaction and broadcast it - MUST reply with their `tx_signatures` if not already transmitted -Both nodes: - - MUST sign the transaction using SIGHASH_ALL - #### Rationale A strict ordering is used to decide which peer sends `tx_signatures` first. From 024df99096bcfb499c67fb21c44d9ae754727642 Mon Sep 17 00:00:00 2001 From: niftynei Date: Sun, 12 Nov 2023 15:30:43 -0600 Subject: [PATCH 20/21] dual-fund, verbiage: clarify situation for closing a underfunded channel Moved up some rationale from the Rationale section and added a bit of clarification to when you'd want to close/cancel an open. Reported-By: @morehouse --- 02-peer-protocol.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index e2bddb89f..5916add76 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -1374,8 +1374,12 @@ The receiving node: channel: - MUST ignore this message - if the `witness` weight lowers the effective `feerate` - below the *opener*'s feerate for the funding transaction: - - SHOULD broadcast their commitment transaction, closing the channel. + below the *opener*'s feerate for the funding transaction and the effective + `feerate` is determined by the receiving node to be insufficient for + getting the transaction confirmed in a timely manner: + - SHOULD broadcast their commitment transaction, closing the channel + - SHOULD double-spend their channel inputs when there is a productive + opportunity to do so; effectively canceling this channel open - SHOULD apply `witnesses` to the funding transaction and broadcast it #### Rationale From 27ffef47aee985d37dcef85d528719f9a4608400 Mon Sep 17 00:00:00 2001 From: niftynei Date: Wed, 13 Dec 2023 14:58:02 -0600 Subject: [PATCH 21/21] dual-fund: add `require_confirmed_inputs` to RBF messages Make `require_confirmed_inputs` explicit for RBF regnegotiation. Requested-By: @t-bast --- 02-peer-protocol.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 5916add76..38e2b72ac 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -451,6 +451,7 @@ completed. 1. type: 0 (`funding_output_contribution`) 2. data: * [`s64`:`satoshis`] + 1. type: 2 (`require_confirmed_inputs`) #### Requirements @@ -459,6 +460,8 @@ The sender: of the previously constructed transaction, rounded down. - If it contributes to the transaction's funding output: - MUST set `funding_output_contribution` + - If it requires the receiving node to only use confirmed inputs: + - MUST set `require_confirmed_inputs` The recipient: - MUST respond either with `tx_abort` or with `tx_ack_rbf` @@ -466,6 +469,8 @@ The recipient: - the `feerate` is not greater than or equal to 25/24 times `feerate` of the last successfully constructed transaction - MAY send `tx_abort` for any reason + - MUST fail the negotiation if: + - `require_confirmed_inputs` is set but it cannot provide confirmed inputs #### Rationale @@ -492,21 +497,27 @@ not contributing to the funding output. * [`channel_id`:`channel_id`] * [`tx_ack_rbf_tlvs`:`tlvs`] + 1. `tlv_stream`: `tx_ack_rbf_tlvs` 2. types: 1. type: 0 (`funding_output_contribution`) 2. data: * [`s64`:`satoshis`] + 1. type: 2 (`require_confirmed_inputs`) #### Requirements The sender: - If it contributes to the transaction's funding output: - MUST set `funding_output_contribution` + - If it requires the receiving node to only use confirmed inputs: + - MUST set `require_confirmed_inputs` The recipient: - MUST respond with `tx_abort` or with a `tx_add_input` message, restarting the interactive tx collaboration protocol. + - MUST fail the negotiation if: + - `require_confirmed_inputs` is set but it cannot provide confirmed inputs #### Rationale @@ -1286,7 +1297,8 @@ protocol, with the following additional caveats. ##### Requirements The sending node: - - if the receiver set `require_confirmed_inputs` in `open_channel2` or `accept_channel2`: + - if the receiver set `require_confirmed_inputs` in `open_channel2`, + `accept_channel2`, `tx_init_rbf` or `tx_ack_rbf`: - MUST NOT send a `tx_add_input` that contains an unconfirmed input #### The `tx_add_output` Message @@ -1318,7 +1330,8 @@ Upon receipt of consecutive `tx_complete`s, the receiving node: successfully negotiated transaction's fees - the transaction does not share at least one input with each previous funding transaction - - if it has sent `require_confirmed_inputs` in `open_channel2` or `accept_channel2`: + - if it has sent `require_confirmed_inputs` in `open_channel2`, + `accept_channel2`, `tx_init_rbf` or `tx_ack_rbf`: - MUST fail the negotiation if: - one of the inputs added by the other peer is unconfirmed