From afac2ffcab76618f988f8f3dc243887dfcff6efa Mon Sep 17 00:00:00 2001 From: lisa neigut Date: Mon, 3 Dec 2018 13:36:03 -0600 Subject: [PATCH] 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 | 31 ++ 01-messaging.md | 4 +- 02-peer-protocol.md | 697 ++++++++++++++++++++++++++++++++++++++++++++ 03-transactions.md | 357 ++++++++++++++++++++++- 09-features.md | 1 + tools/spellcheck.sh | 3 +- 6 files changed, 1089 insertions(+), 4 deletions(-) diff --git a/.aspell.en.pws b/.aspell.en.pws index c9e3a0206..3f5a72923 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -23,6 +23,7 @@ nhops retransmitted dev tradeoff +kiloweight mixHeader uint hopsData @@ -115,6 +116,31 @@ delayedsig hopDataSize I'th segwit +SegWit +sizeof +varint +tlv +rbf +RBF +accepter +accepter's +subtype +subsubtype +redeemScript +UTXO +utxo +utxos +scriptPubkey +scriptPubKey +scriptPubKeys +RBFs +ack'd +scriptlen +btc +sats +prevoutnum +prevtxid +ints htlc htlcs ChaCha @@ -386,3 +412,8 @@ csv CHECKSIGVERIFY IFDUP sats +workflow +PUSHDATA +perkw +prev +vout diff --git a/01-messaging.md b/01-messaging.md index 678393e1b..ea928c20c 100644 --- a/01-messaging.md +++ b/01-messaging.md @@ -316,11 +316,11 @@ The 2-byte `len` field indicates the number of bytes in the immediately followin 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 `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`. diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 535c81dcf..c803001bc 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -7,12 +7,29 @@ operation, and closing. * [Channel](#channel) * [Definition of `channel_id`](#definition-of-channel_id) + * [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` Message](#the-tx_remove_input-message) + * [The `tx_remove_output` Message](#the-tx_remove_output-message) + * [The `tx_complete` Message](#the-tx_complete-message) + * [The `tx_signatures` Message](#the-tx_signatures-message) * [Channel Establishment](#channel-establishment) * [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 `funding_locked` Message](#the-funding_locked-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) + * [The `init_rbf` Message](#the-init_rbf-message) + * [The `ack_rbf` Message](#the-ack_rbf-message) * [Channel Close](#channel-close) * [Closing Initiation: `shutdown`](#closing-initiation-shutdown) * [Closing Negotiation: `closing_signed`](#closing-negotiation-closing_signed) @@ -50,10 +67,350 @@ pubkey corresponding to the funding output nothing prevents duplicative channel ids. +### `channel_id`, v2 + +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. +The basepoints are compact DER-encoded public keys. + + +## 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 `contributor`. + 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`; for a close, the `initiator` sends `shutdown`. + +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 has been negotiated, or is established + via convention. +- The transaction version is 2. + +### 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 `contributor` responds with any +of `tx_add_input`, `tx_add_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`. + +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. + +Here are a few example exchanges. + +#### `initiator` only + +A, `initiator` has two inputs and an output (the funding output). +B, the `contributor` 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 `contributor` + +A the `initiator` contributes 2 inputs and an output that they +then remove. B, the `contributor`, 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_add_output --| | + | |--(8)- tx_rm_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`] + * [`u16`:`redeemscript_len`] + * [`redeemscript_len*byte`:`script`] + +#### Requirements + +The sending node: + - MUST add all sent inputs to the transaction + - MUST use a unique `serial_id` for each input + - MUST NOT re-transmit inputs it has received from the peer + - if is the `initiator`: + - MUST send even `serial_id`s + - if is the `contributor`: + - MAY omit this message + - MUST send odd `serial_id`s + +The receiving node: + - MUST add all received inputs to the funding transaction + - MUST fail the negotiation if: + - it receives a duplicate input + - it receives a malleable input (e.g. pre-Segwit) + - it receives a duplicate `serial_id` + - it receives a `serial_id` with the wrong parity + - it receives more than 2^12 `tx_add_input` messages during + this negotiation + +#### Rationale +Each node must know the set of the transaction inputs. + +`serial_id` is a randomly chosen number which uniquely identifies this input. +Inputs in the constructed transaction are sorted by `serial_id`. + +`prevtx_tx` 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. Must be less than +4278190079 (0xfefffff little endian). + +`script` is the script signature field for the input, with length omitted. +The `script` for non-P2SH-wrapped inputs will be an empty byte. + +### The `tx_add_output` Message + +This message 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 + - MUST use a unique `serial_id` for each output + +The receiving node: + - MUST add the specified output to the transaction + - MUST fail the negotiation if: + - it receives a duplicate `serial_id` + - it receives a `serial_id` with the wrong parity + - it receives more than 2^12 `tx_add_output` messages during + this negotiation + - the `sats` amount is less than or equal to the `dust_limit` + - the `script` is non-standard + + +#### 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. The length is omitted. + + +### The `tx_remove_input` Message +This message removes an input from the transaction. + +1. type: 68 (`tx_remove_input`) +2. data: + * [`channel_id`:`channel_id`] + * [`u64`:`serial_id`] + +#### Requirements + +The sending node: + - MUST NOT send a `tx_remove_input` with the wrong parity + (even for `iniiator`, odd for `contributor`) + +The receiving node: + - MUST remove the indicated input from the transaction + - MAY ignore the message if: + - the `serial_id` is novel (has not been communicated previously) + - MUST fail the negotiation if: + - the `serial_id`'s parity is incorrect + - it receives more than 2^12 `tx_remove_input` messages during this + negotiation + + +### The `tx_remove_output` Message +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_output` with the wrong parity + (even for `iniiator`, odd for `contributor`) + +The receiving node: + - MUST remove the indicated output from the final transaction + - MAY ignore the message if: + - the `serial_id` is novel (has not been communicated previously) + - MUST fail negotiation if: + - the `serial_id` parity is incorrect + - it receives more than 2^12 `tx_remove_output` messages during this + negotiation + + +### 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 `contributor`: + - the `initiator`'s fees do not cover the `common` fields + +If this exchange was initiated by an `init_rbf` message: + - MUST include at least one input from the previously negotiated transaction + - MUST pay a larger fee than the previously negotiated transaction + +#### 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 `tx_signatures` Message + +1. type: 71 (`tx_signatures`) +2. data: + * [`channel_id`:`channel_id`] + * [`sha256`:`txid`] + * [`u16`:`num_witnesses`] + * [`num_witnesses*witness_stack`:`witness_stack`] + +1. subtype: `witness_stack` +2. data: + * [`u16`:`num_input_witness`] + * [`num_input_witness*witness_element`:`witness_element`] + +1. subtype: `witness_element` +2. data: + * [`u16`:`len`] + * [`len*byte`:`witness`] + + +#### Requirements +The sending node: + - MUST order the `witness_stack`s by the `serial_id` of the input they + correspond to + +The receiving node: + - MUST fail the negotiation if: + - a `witness_stack` is empty or missing + - the `txid` does not match the txid of the receiving node's + constructed transaction + - MUST fail the channel if: + - the `witness_stack` weight is lowers the effective `feerate` + below the agreed upon transaction feerate + - SHOULD apply the `witness`es to the transaction and broadcast it + - MUST reply with their `tx_signatures` if not already transmitted + + +#### Rationale +`witness` is the data for a witness element in a witness stack. +Witness elements should *not* include their length. + +Witness data must be sorted according to the `serial_id` of +the corresponding input. + +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 110. +If the fees paid by the peer (inputs - outputs) does not meet or exceed +the pre-established `feerate`, the receiving peer SHOULD immediately +fail the channel by broadcasting their commitment transaction. + ## Channel Establishment 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 @@ -230,6 +587,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: - `announce_channel` is `false` (`0`), yet it wishes to publicly announce the channel. @@ -437,6 +796,344 @@ funds are at risk. If the fundee were to remember the channel forever, this would create a Denial of Service risk; therefore, forgetting it is recommended (even if the promise of `push_msat` is significant). +If an RBF negotiation is in progress when a `funding_locked` 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`/`contributor`) to contribute inputs to the funding transaction, +via the interactive transaction construction protocol. + +The protocol is also expanded to include a mechanism for initiating RBF. + + +-------+ +-------+ + | |--(1)--- open_channel2 ----->| | + | |<-(2)--- accept_channel2 -----| | + | | | | + --->| | | | + | | | | | + | | |--(3)-- commitment_signed -->| | + | | |<-(4)-- commitment_signed ---| | + | | A | | B | + | | |<-(5)-- tx_signatures -------| | + | | |--(6)-- tx_signatures ------>| | + | | | | | + | | |--(a)--- init_rbf ----------->| | + ----| |<-(b)--- ack_rbf ------------| | + | | | | + | |--(7)--- funding_locked ----->| | +n- + | |<-(8)--- funding_locked ------| | + +-------+ +-------+ + + - where node A is `opener`/`initiator` and node B is + `accepter`/`contributor` + +### The `open_channel2` Message + +This message initiates the v2 channel establishment workflow. + +1. type: 64 (`open_channel2`) +2. data: + * [`chain_hash`:`chain_hash`] + * [`32*byte`:`temporary_channel_id`] + * [`u32`:`funding_feerate_perkw`] + * [`u32`:`commitment_feerate_perkw`] + * [`u32`:`feerate_funding_min`] + * [`u32`:`feerate_funding_best`] + * [`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`:`opening_tlv`] + + +1. tlvs: `opening_tlvs` +2. types: + 1. type: 1 (`option_upfront_shutdown_script`) + 2. data: + * [`u16`:`shutdown_len`] + * [`shutdown_len*byte`:`shutdown_scriptpubkey`] + + +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 + - MUST ensure `temporary_channel_id` is unique from any + other channel ID with the same peer. + +The receiving node: + - MAY fail the negotiation if: + - the `locktime` is unacceptable + - the `funding_feerate_per_kw` is unacceptable + +#### Rationale +`temporary_channel_id` is required until after a successful `accept_channel2` +message has been received. This allows the peer to return channel-assignable +errors while the `channel_id` is unknown. + +`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 `feerate_funding_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`:`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`:`accept_tlv`] + +1. tlvs: `accept_tlvs` +2. types: + 1. type: 1 (`option_upfront_shutdown_script`) + 2. data: + * [`u16`:`shutdown_len`] + * [`shutdown_len*byte`:`shutdown_scriptpubkey`] + + +Rationale and Requirements are the same as listed above, +for [`accept_channel`](#the-accept_channel-message) with the following +additions. + +#### Requirements: + +The accepting node: + - 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`, the channel funding output + +The receiving node: + - if is the `accepter`: + - MUST fail the negotiation if: + - the value of the funding output is incorrect + - if the `funding_output` of the resulting transaction is less than + the `dust_limit` ([BOLT #3: Calculating `est_tx_fee`](03-transactions.md#channel-establishment-v2-funding-transaction-fees)): + +##### Rationale +The channel funding output must be added by the `opener`, who pays its fees. + + +#### The `tx_complete` Message + +The receiving node: + - if this is the last exchange `tx_complete` and an RBF attempt: + - if is the `accepter`: + - MUST fail the negotiation if: + - no funding output is received + - the value of the funding output is incorrect (not equal + to `open_channel2`.`funding_satoshis` + + `accept_channel2`.`funding_satoshis`) + - if is an RBF attempt, MUST fail the negotiation if: + - the transaction's total fees is less than the + last successful funding transaction's fees. + - the transaction does not contain at least one input from + every previous funding transaction + +### 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 HTLC's. + +The receiving node: + - if the message has one or more HTLC's: + - MUST fail the negotiation + - if it has not already transmitted its `commitment_signed`: + - MUST send `commitment_signed` + - Otherwise: + - MUST send `tx_signatures` + +#### Rationale + +The first commitment transaction has no HTLC's. + + +### Sharing funding signatures: `tx_signatures` + +After a valid `commitment_signature` has been received +from the peer and a `commitment_signature` has been sent, a peer: + - MUST transmit a [`tx_signatures` message](#the-tx_signatures-message) with their signatures for + the funding transaction + + +#### 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 received `witness_stack` weight results in the peer's + paid feerate falling below the `opener`'s feerate for the funding + transaction: + - SHOULD broadcast their commitment transaction, closing the channel. + - SHOULD apply `witness`es to the funding transaction and broadcast it + - if has already sent or received a `funding_locked` message for this + channel: + - MUST ignore this message + +#### Rationale +A peer sends their `tx_signatures` as soon as they have received a valid +`commitments_signed` message. + +The channel should be preemptively closed in the case where a peer provides +valid witness data that causes their paid feerate to fall beneath the +`open_channel2.funding_feerate_perkw` rate. This penalizes the peer +for underpayment of fees. + + +### The `init_rbf` Message + +This message initiates a replacement of a broadcast funding transaction. + +1. type: 72 (`init_rbf`) +2. data: + * [`channel_id`:`channel_id`] + * [`u64`:`funding_satoshis`] + * [`u32`:`locktime`] + * [`byte`:`fee_step`] + +#### Requirements + +The sender: + - MUST have sent `open_channel2` + - MUST set `fee_step` greater than zero and greater than any prior `fee_step` + - MUST NOT have sent or received a `funding_locked` message. + +The recipient: + - MUST respond with either an error or an `ack_rbf` message. + - MUST fail the negotiation if: + - the `fee_step` is not greater than the last successfully negotiated + `init_rbf` attempt or `one` if no prior successful `init_rbf` has + been received + - they have already sent or received `funding_locked` + - MAY fail the negotiation for any reason + +#### Rationale +`fee_step` is an integer value, which specifies the `feerate` for this +funding transaction, as a rate of increase above the `open_channel2`. +`funding_feerate_perkw`. + +The effective `funding_feerate_perkw` for this RBF attempt +if calculated as 1.25^`fee_step` * `funding_feerate_perkw`. +E.g. if `feerate_per_kw_funding` is 512 and the `fee_step` is 1, +the effective `feerate` for this RBF attempt is 512 + 512 / 4 or 640 sat/kw. +A `fee_step` 2 would be `1.25^2 * 512` (or 640 + 640 / 4), 800 sat/kw. + +If a valid `funding_locked` message is received in the middle of an +RBF attempt, the attempt MUST be abandoned. + +### The `ack_rbf` Message + +1. type: 73 (`ack_rbf`) +2. data: + * [`channel_id`:`channel_id`] + * [`u64`:`funding_satoshis`] + +#### Requirements + +The sender: + - MUST NOT have sent or received a `funding_locked` message + +The recipient: + - MUST either fail the negotiation or transmit a `tx_add_input` message + +#### Rationale +`funding_satoshis` is the amount of satoshis that this peer will +contribute to the funding output. Note that this may be different than +the amount transmitted in either `accept_channel2`.`funding_satoshis` or +any previous `ack_rbf`.`funding_satoshis`, as the amount the `accepter` +wishes to commit to the funding output may change. + +It's recommended that a peer, rather than fail the RBF negotiation due to +a large feerate change, instead sets their `funding_satoshis` to zero, +and decline to participate further in the channel funding. + ## Channel Close Nodes can negotiate a mutual close of the connection, which unlike a diff --git a/03-transactions.md b/03-transactions.md index 43b7ed1cd..919931211 100644 --- a/03-transactions.md +++ b/03-transactions.md @@ -37,6 +37,7 @@ This details the exact format of on-chain transactions, which both sides need to * [Storage Tests](#storage-tests) * [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: Dual Funded Transaction Test Vectors](#appendix-f-dual-funded-transaction-test-vectors) * [References](#references) * [Authors](#authors) @@ -477,6 +478,14 @@ A node: - if the resulting fee rate is too low: - MAY 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 `feerate` determined during the +initiation, with the initiator covering the fees for the common transaction fields. + + ## Commitment Transaction Construction This section ties the previous sections together to detail the @@ -710,6 +719,104 @@ 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: 40 bytes + var_int + `scriptlen` + - previous_out_point: 36 bytes + - hash: 32 bytes + - index: 4 bytes + - var_int: ? bytes (dependent on `scriptlen`) + - script_sig: `scriptlen` + - witness <---- Cost for "witness" data calculated separately. + - sequence: 4 bytes + + non_funding_outputs: 8 bytes + var_int + `scriptlen` + - value: 8 bytes + - var_int: ? bytes (dependent on `scriptlen`) + - script_sig: `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 * 40 + num_outputs * 8 + // + sum(scriptlen) + sum(var_ints) + + funding_transaction_weight = 4 * (funding_transaction + transaction_fields) + segwit_fields + + witness_weight = sum(max_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 110. + +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 down to the nearest satoshi. + + initiator_weight = transaction_fields * 4 + + segwit_fields + + p2wpkh_input * 4 + + funding_output * 4 + + p2wpkh_output * 4 + + input_count * 110 (minimum witness weight) + + initiator_weight = 10 * 4 + + 2 + + 41 * 4 + + 43 * 4 + + 31 * 4 + + 107 + + initiator_weight = 612 + + initiator_fees = initiator_weight * feerate + initiator_fees = 612 * 253 / 1000 + initiator_fees = 154 sats + +The contributor's minimum fee is calculated as follows. + + contributor_weight = 2 * p2wpkh_input * 4 + + 2 * p2wpkh_output * 4 + + input_count * 110 (minimum witness weight) + + contributor_weight = 2 * 41 * 4 + + 2 * 31 * 4 + + 2 * 110 + + contributor_weight = 796 + + contributor_fees = contributor_weight * feerate + contributor_fees = 796 * 253 / 1000 + contributor_fees = 201 sats + + +This is an estimated fee. The peer MUST at least contribute the estimated rate, +and MUST exceed the minimum fee in the case that their witness weight is greater +than the estimated weight of 110 per input. + + ## Expected Weight of the Commitment Transaction The *expected weight* of a commitment transaction is calculated as follows: @@ -1006,7 +1113,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). @@ -1953,6 +2060,254 @@ before subtraction of: "RemoteSigHex": "30450221008fd5dbff02e4b59020d4cd23a3c30d3e287065fda75a0a09b402980adf68ccda022001e0b8b620cd915ddff11f1de32addf23d81d51b90e6841b2cb8dcaf3faa5ecf" } ] + +# Appendix G: 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: 618013 +Feerate: 253 sat/kiloweight +Opener's `funding_satoshi`: 4 0000 0000 sat +Accepter's `funding_satoshi`: 4 0000 0000 sat + +Inputs: +``` +4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9 0 + witness_data: + preimage: 20 68656c6c6f2074686572652c2074686973206973206120626974636f6e212121 + witness_script: 27 82012088a820add57dfe5277079d069ca4ad4893c96de91f88ffb981fdc6a2a34d5336c66aff87 + scriptPubKey: 0020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b946 + address: bcrt1qlky6eaj5sh0cj7tanwnm573nvf9vg3f0qrdssyrlxsjh6vl9h9rql40v2g + +4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9 1 + redeemScript: 0020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b946 + witness_data: + preimage: 20 68656c6c6f2074686572652c2074686973206973206120626974636f6e212121 + witness_script: 27 82012088a820add57dfe5277079d069ca4ad4893c96de91f88ffb981fdc6a2a34d5336c66aff87 + scriptPubKey: a9146a235d064786b49e7043e4a042d4cc429f7eb69487 + address: 2N2vRyi3cm5VYpw218MJJrJWK1Jd4qbaefW + +4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9 2 + pubkey: 034695f5b7864c580bf11f9f8cb1a94eb336f2ce9ef872d2ae1a90ee276c772484 + privkey: cUM8Dr33wK4uFmw3Tz8sbQ7BiBNgX5BthRurU7RkgXVvNUPcWrJf + witness_program: fbb4db9d85fba5e301f4399e3038928e44e37d32 + scriptPubKey: 0014fbb4db9d85fba5e301f4399e3038928e44e37d32 + address: bcrt1qlw6dh8v9lwj7xq058x0rqwyj3ezwxlfjxsy7er + +4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9 3 + pubkey: 034695f5b7864c580bf11f9f8cb1a94eb336f2ce9ef872d2ae1a90ee276c772484 + privkey: cUM8Dr33wK4uFmw3Tz8sbQ7BiBNgX5BthRurU7RkgXVvNUPcWrJf + redeemScript: 0014fbb4db9d85fba5e301f4399e3038928e44e37d32 + witness_program: fbb4db9d85fba5e301f4399e3038928e44e37d32 + scriptPubKey: a9147ecd1b519326bc13b0ec716e469b58ed02b112a087 + address: 2N4ogqX3kaLTT2jjxi18nAiyWdwKtE5PxLF +``` + +Expected Opener's `tx_add_input` (inputs 0+1 above): +``` + num_inputs: 2 + tx_add_input:[ + { + channel_id: xxx, + serial_id: 10, + sats: 250000000, + prev_txid: 4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9, + prev_vout: 0, + prev_scriptpubkey_len: 34, + prev_scriptpubkey: 0020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b946, + max_witness_len: 74, + scriptlen: 0, + script: null + },{ + channel_id: xxx, + serial_id: 20, + sats: 250000000, + prev_txid: 4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9, + prev_vout: 1, + prev_scriptpubkey_len: 23, + prev_scriptpubkey: a9146a235d064786b49e7043e4a042d4cc429f7eb69487, + max_witness_len: 74, + scriptlen: 34, + script: 0020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b946 + } + ] +``` + +Expected Accepter's `tx_add_input` (inputs 2+3 above): +``` + num_inputs: 2 + tx_add_input:[ + { + channel_id: xxx, + serial_id: 11, + sats: 250000000, + satoshis: 250000000, + prev_txid: 4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9, + prev_vout: 2, + prev_scriptpubkey_len: 22, + prev_scriptpubkey: 0014fbb4db9d85fba5e301f4399e3038928e44e37d32, + max_witness_len: 109, + scriptlen: 0, + script: null + },{ + channel_id: xxx, + serial_id: 17, + sats: 250000000, + prev_txid: 4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9, + prev_vout: 3, + prev_scriptpubkey_len: 23, + prev_scriptpubkey: a9147ecd1b519326bc13b0ec716e469b58ed02b112a087, + max_witness_len: 109, + scriptlen: 22, + script: 0014fbb4db9d85fba5e301f4399e3038928e44e37d32 + } + ] +``` + +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: 99999809 + scriptlen: 22 + script: 1600141ca1cca8855bad6bc1ea5436edd8cff10b7e448b + },{ + channel_id: xxx, + serial_id: 44, + sats: 800000000 + scriptlen: 34 + script: 220020297b92c238163e820b82486084634b4846b86a3c658d87b9384192e6bea98ec5 + } + ] +``` + +Expected Accepter's `tx_add_output`: + +``` + num_outputs: 1 + tx_add_output[ + { + channel_id: xxx, + serial_id: 33, + sats: 99999809 + scriptlen: 22 + script: 16001444cb0c39f93ecc372b5851725bd29d865d333b10 + } +``` + +Expected Fee Calculation: + +Opener's fees and change: +``` + initiator_weight = transaction_fields * 4 + + segwit_fields + + inputs * 4 + + funding_output * 4 + + change_output * 4 + + sum_max_witness_weight + + initiator_weight = 10 * 4 + + 2 + + (41 + 74) * 4 + + 43 * 4 + + 31 * 4 + + 148 + + initiator_weight = 946 + + initiator_fees = initiator_weight * feerate + initiator_fees = 946 * 253 / 1000 + initiator_fees = 239 sats + + change = total_funding + - funding_sats + - fees + + change = 5 0000 0000 + - 4 0000 0000 + - 239 + + change = 9999 9761 +``` + +Accepter's fees and change: +``` + contributor_weight = 2 * p2wpkh_input * 4 + + 2 * p2wpkh_output * 4 + + sum_max_witness_weight + + contributor_weight = (41 + 63) * 4 + + 31 * 4 + + 218 + + contributor_weight = 758 + + contributor_fees = contributor_weight * feerate + contributor_fees = 758 * 253 / 1000 + contributor_fees = 191 sats + + change = total_funding + - funding_sats + - fees + + change = 5 0000 0000 + - 4 0000 0000 + - 191 + + change = 9999 9809 + +``` + +Unsigned Funding Transaction: +``` +0200000004b932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430000000000ffffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430200000000ffffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430300000000ffffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430100000000ffffffff0341e0f505000000001600141ca1cca8855bad6bc1ea5436edd8cff10b7e448b11e0f5050000000016001444cb0c39f93ecc372b5851725bd29d865d333b100008af2f00000000220020297b92c238163e820b82486084634b4846b86a3c658d87b9384192e6bea98ec51d6e0900 +``` + +Signed Funding Transaction: +``` +TODO ``` # References diff --git a/09-features.md b/09-features.md index ea37b8b5e..7adbeae34 100644 --- a/09-features.md +++ b/09-features.md @@ -40,6 +40,7 @@ The Context column decodes as follows: | 18/19 | `option_support_large_channel` | Can create large channels | IN | | [BOLT #2](02-peer-protocol.md#the-open_channel-message) | | 20/21 | `option_anchor_outputs` | Anchor outputs | IN | `option_static_remotekey` | [BOLT #3](03-transactions.md) | | 22/23 | `option_anchors_zero_fee_htlc_tx` | Anchor commitment type with zero fee HTLC transactions | IN | | [BOLT #3][bolt03-htlc-tx], [lightning-dev][ml-sighash-single-harmful]| +| 26/27 | `option_dual_fund` | Use v2 of channel open, enables dual funding | IN9 | `option_anchor_outputs`, `option_static_remotekey` | [BOLT #2](02-peer-protocol.md) | ## Requirements 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