diff --git a/.aspell.en.pws b/.aspell.en.pws index 15b8def16..d4444c74a 100644 --- a/.aspell.en.pws +++ b/.aspell.en.pws @@ -114,6 +114,30 @@ delayedsig hopDataSize I'th segwit +SegWit +sizeof +varint +tlv +rbf +RBF +accepter +accepter's +subtype +subsubtype +redeemScript +UTXO +utxo +scriptPubkey +scriptPubKey +scriptPubKeys +RBFs +ack'd +scriptlen +btc +sats +prevoutnum +prevtxid +ints htlc htlcs ChaCha @@ -375,3 +399,5 @@ GitHub IRC bitmasks CSPRNG +workflow +PUSHDATA diff --git a/02-peer-protocol.md b/02-peer-protocol.md index 1f4f0a5ee..ec7e835a8 100644 --- a/02-peer-protocol.md +++ b/02-peer-protocol.md @@ -13,6 +13,15 @@ operation, and closing. * [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) + * [The `funding_add_input` Message](#the-funding_add_input-message) + * [The `funding_add_output` Message](#the-funding_add_output-message) + * [The `funding_add_complete` Message](#the-funding_add_complete-message) + * [The `funding_signed2` Message](#the-funding_signed2-message) + * [Kicking Off Replace-By-Fee: `init_rbf` Message](#kicking-off-replace-by-fee-init_rbf) + * [Acknowledging Replace-By-Fee `ack_rbf` Message](#acknowledging-replace-by-fee-ack_rbf) * [Channel Close](#channel-close) * [Closing Initiation: `shutdown`](#closing-initiation-shutdown) * [Closing Negotiation: `closing_signed`](#closing-negotiation-closing_signed) @@ -54,6 +63,11 @@ ids. 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 @@ -215,6 +229,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. @@ -417,6 +433,519 @@ 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). + +## Channel Establishment v2 + +This is the second version of the channel establishment protocol. +It extends version one to allow the non-`open_channel` participant +(the accepter) to contribute inputs to the funding transaction. + +The protocol is also expanded to include a mechanism for initiating RBF. + + +-------+ +-------+ + | |--(1)--- open_channel2 ----->| | + | |<-(2)--- accept_channel2 -----| | + | | | | + | |--(3a)- funding_add_input -->| | + | |<-(3b)- funding_add_input ---| | + | |--(3c)- funding_add_input -->| | + | |--(3d)- funding_add_output ->| | + | |<-(3e)- funding_add_output --| | + | | | | + | |--(4a)- funding_add_complete >| | + | |<-(4b)- funding_add_complete -| | + | A | | B | + --->| |--(5)-- commitment_signed -->| | + | | |<-(6)-- commitment_signed ---| | + | | | | | + | | |--(7)-- funding_signed2 -->| | + | | |<-(8)-- funding_signed2 ---| | + | | | | | + | | |--(a)--- init_rbf ----------->| | + ----| |<-(b)--- ack_rbf ------------| | + | | | | + | |--(9)--- funding_locked ----->| | + | |<-(10)-- funding_locked ------| | + +-------+ +-------+ + + - where node A is 'opener' and node B is 'accepter' + +### 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`] + * [`u64`:`funding_satoshis`] + * [`u64`:`push_msat`] + * [`u64`:`dust_limit_satoshis`] + * [`u64`:`max_htlc_value_in_flight_msat`] + * [`u64`:`htlc_minimum_msat`] + * [`u32`:`feerate_per_kw`] + * [`u32`:`feerate_per_kw_funding`] + * [`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`] + * [`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` + +#### Rationale + +`feerate_per_kw_funding` 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). + +`channel_reserve_satoshi` has been omitted. The channel reserve is fixed at 1% of +the total channel balance (sum of `funding_satoshis` from `open_channel2` and `accept_channel2`) +or the `dust_limit_satoshis`, whichever is greater. + + +### 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: + * [`32*byte`:`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`:`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 + +Accepter sends their `funding_satoshi` value here instead of allowing the opener to derive +it from their `funding_compose` response so that the opener can notionally decide whether +to complete the opening without exposing their output set. + +`channel_reserve_satoshi` has been omitted. The channel reserve is fixed at 1% of +the total channel balance (sum of `funding_satoshis` from `open_channel2` and `accept_channel2`) +or the `dust_limit_satoshis`, whichever is greater. + + +### Funding Composition +There are three messages which nodes use to communicate their input and output set +for a funding transaction: `funding_add_input`, `funding_add_output`, and `funding_add_complete`. + +To add inputs to a transaction, a node may send one or more `funding_add_input` messages. +To add outputs to a transaction, a node may send one or more `funding_add_output` messages. + +Once a node has relayed all of their inputs and output contributions, it sends +`funding_add_complete` to signal the completion of their contribution transmission. + +#### The `funding_add_input` Message + +This message contains information for inputs to a funding transaction. + +1. type: 66 (`funding_add_input`) +2. data: + * [`32*byte`:`temporary_channel_id`] + * [`u16`:`num_inputs`] + * [`num_inputs*input_info`:`input_info`] + +1. subtype: `input_info` +2. data: + * [`u64`:`sats`] + * [`sha256`:`prevtx_txid`] + * [`u32`:`prevtx_vout`] + * [`u16`:`prevtx_scriptpubkey_len`] + * [`prevtx_scriptpubkey_len*byte`:`prevtx_scriptpubkey`] + * [`u16`:`max_witness_len`] + * [`u16`:`scriptlen`] + * [`scriptlen*byte`:`script`] + +##### Requirements + +The sending node: + - MUST NOT send `funding_add_input` if it has already transmitted `funding_add_complete` + - MUST add all sent inputs to the funding transaction + - MUST NOT re-transmit inputs it has already received from the peer + - MUST ensure each `input_info` refers to a non-malleable (segwit) UTXO. + - if is the `opener`: + - MUST send at least one `funding_add_input` message + - MUST NOT send a total count of more than 64 inputs, across all `funding_add_input` messages. + - if is the `accepter`: + - MAY omit this message + - MUST NOT send a total count of more than 16 inputs, across all `funding_add_input` messages. + +The receiving node: + - MUST add all received inputs to the funding transaction + - MUST fail the channel if: + - it receives a duplicate input to one it sent previously + - it receives this message after `funding_add_complete` is received. + - it receives an input that would create a malleable transaction id (e.g. pre-Segwit) + - it receives an unconfirmed input + - if is the `opener`: + - MUST fail the channel if: + - the total count of `input_info`s is greater than 6 + + +##### Rationale +Each node must have a complete set of the transaction inputs +to derive the funding transaction and subsequent commitment signatures. + +`sats` is the satoshi value of the input. + +`prevtx_txid`, `prevtx_vout`, and `prevtx_scriptpubkey` specify the output +to be spent. `prevtx_txid` is the hash of the transaction that this input is +an output of; `prevtx_vout` its outpoint; and `prevtx_scriptpubkey` the +corresponding `scriptPubKey` value. + +`max_witness_len` is the total serialized length of the +witness data that will be supplied (e.g. sizeof(varint) + +sizeof(witness) for each) in `funding_signed2`. + +`input_info`.`script` is the script signature field for the input. Only applicable +for P2SH-wrapped inputs. +Native SegWit inputs (P2WPKH and P2WSH) inputs, will have an empty `script` field +See [BIP141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#examples). + + +#### The `funding_add_output` Message + +This message contains information for outputs to a funding transaction. + +1. type: 67 (`funding_add_output`) +2. data: + * [`32*byte`:`temporary_channel_id`] + * [`u16`:`num_outputs`] + * [`num_outputs*output_info`:`output_info`] + +1. subtype: `output_info` +2. data: + * [`u64`:`sats`] + * [`u16`:`scriptlen`] + * [`scriptlen*byte`:`script`] + +##### Requirements + +Either node: + - MAY omit this message + +The sending node: + - MUST NOT send `funding_add_output` if it has already transmitted `funding_add_complete` + - MUST add all sent outputs to the funding transaction + - MUST ensure the `output_info`.`script` is a standard script + - MUST NOT include the channel funding output. + - if is the `opener`: + - MAY specify an output with value zero, which will be used + as the change address for any resulting funds after fees are deducted + - if is the `accepter`: + - MUST NOT send a total count of more than 8 outputs, across all `funding_add_output` messages. + +The receiving node: + - MUST add all received outputs to the funding transaction + - MUST fail the channel if + - it receives this message after receiving `funding_add_complete` + - if is the `opener`: + - MUST fail the channel if: + - receives a total count of more than 8 outputs, across all `funding_add_output`s + + +##### Rationale +Each node must have a complete set of the transaction outputs +to derive the funding transaction and subsequent commitment signatures. + +`sats` is the satoshi value of the output. + +The opening node may include one output with `sats` value +of zero. This will be used for change, or discarded if its value is +below `dust_limit_satoshis`. + +Change is calculated as the sum of the opener's `input_info`.`sats` +minus the estimated funding transaction size times the +`feerate_per_kw_funding` minus the `funding_satoshis` minus all other +`output_info`.`satoshis`. If the `change_satoshis` value is negative, +the difference is subtracted from `funding_satoshis`. In the case where +the fee entirely consumes the value of the opener's `funding_satoshis`, +the remainder will be subtracted from the accepter's `funding_satoshis`. +Either peer may fail the channel open if the resulting fee payment is +deemed exorbitant. + +A more in-depth discussion of fee payment and change handling can be +found in [BOLT-3, v2 Funding Transaction Fees](03-transactions.md#channel-establishment-v2-funding-transaction-fees). + +`output_info`.`script` is the scriptPubKey for the output. + +The channel funding output is not exchanged, as it can be derived +independently. + + +#### The `funding_add_complete` Message + +This message signals the conclusion of a peer's funding transaction +contributions. + +1. type: 68 (`funding_add_complete`) +2. data: + * [`32*byte`:`temporary_channel_id`] + * [`u16`:`num_inputs`] + * [`u16`:`num_outputs`] + + +##### Requirements + +Both nodes: + - MUST send this message after `accept_channel2` has been sent/received. + +The sending node: + - MUST ensure that the `num_inputs` corresponds to the total sum of all `num_inputs` + sent in all `funding_add_input` messages that originated from them + - MUST ensure that the `num_outputs` corresponds to the total sum of all `num_outputs` + sent in all `funding_add_output` messages that originated from them + +The receiving node: + - MUST fail the channel if: + - the `num_inputs` does not correspond to the total sum of all `num_inputs` + received in all `funding_add_input` messages + - the `num_outputs` does not correspond to the total sum of all `num_outputs` + received in all `funding_add_output` messages + - the total satoshis of the senders inputs is less than their outputs plus + the `funding_satoshis`, specified earlier + - the resulting `funding_output` value is less than the `dust_limit`. + - if is the `opener`: + - MAY fail the channel if: + - the fee cost of the proposed funding transaction is deemed exorbitant. + - if has not yet sent a `funding_add_complete`: + - MUST send its `funding_add_complete` message. + - otherwise: + - MUST use the sent and received `input_info` and `output_info` + to create the funding transaction, using `max_witness_len` + for each `input_info` and `feerate_per_kw_funding` as specified in + `open_channel2`. + - 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)): + - MUST fail the channel + - MUST send `commitment_signed`. + + +##### Rationale + +Each node must have a complete set of the transaction inputs and outputs, +to derive the funding transaction and subsequent commitment signatures. + +`funding_add_complete` concludes a node's transmission of its contributions +to the funding transaction, which serve as an early check that all +`funding_add_input` and `funding_add_output` messages have been received. + +Upon successful exchange of `funding_add_complete` messages, both nodes +should build the funding transaction and update their channel id +to be transmitted in `commitment_signed`. + + +### The `commitment_signed` Message + +This message is sent by the opening node. It contains the signatures for +the first commitment transaction. + +Rationale and Requirements are the same as listed above, +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 channel. + - if it has not already transmitted its `commitment_signed`: + - MUST send `commitment_signed` + - Otherwise: + - MUST send `funding_signed2` + +#### Rationale + +The first commitment transaction has no HTLC's in it. + +Note that the `commitment_signed` message will include the `channel_id` derived from +the `funding_txid`, instead of the `temporary_node_id`. + + +### The `funding_signed2` Message + +This message contains witness data for the inputs that were +originally exchanged in `funding_add_input`. + +1. type: 69 (`funding_signed2`) +2. data: + * [`channel_id`:`channel_id`] + * [`u16`:`num_witnesses`] + * [`num_witnesses*witness_stack`:`witness_stack`] + +1. subtype: `witness_stack` +2. data: + * [`sha256`:`prevtx_txid`] + * [`u32`:`prevtx_vout`] + * [`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 verify it has received valid commitment signatures from its peer + - MUST set `witness` to the serialized witness data for the input + corresponding to `prevtx_txid`:`prevtx_vout` + - MUST remember the details of this funding transaction. + - MUST NOT send a `witness_stack` whose length exceeds its + previously indicated `max_witness_len`. + - if it has NOT received a valid `commitment_signed` message: + - MUST NOT send a `funding_signed2` message. + +The receiving node: + - if the `witness_stack` length exceeds `max_witness_len`: + - MUST error. + - 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 + +Every node must transmit their complete set of witness data for +the inputs included in the funding transaction. + +`prevtx_txid` and `prevtx_vout` are the identifier for the input +which the witness data pertain to + +`witness` is the data for a witness element in a witness stack + +It is possible but a protocol error for an accepter node to +fail to send a `funding_signed2` message while also +successfully broadcasting the signed funding transaction. + +### Kicking Off Replace-By-Fee: `init_rbf` + +This message initiates the flow to create a replacement funding +transaction. It is sent by the channel opener, after the funding +transaction has been broadcast but before a `funding_locked` message +is exchanged. + +Once an `init_rbf` message has been successfully ack'd by the accepter +node, the message flow returns to `commitment_signed` and proceeds as +indicated above. + +1. type: 70 (`init_rbf`) +2. data: + * [`channel_id`:`channel_id`] + * [`u64`:`funding_satoshis`] + * [`u32`:`feerate_per_kw`] + * [`u32`:`feerate_per_kw_funding`] + * [`u16`:`num_additional_inputs`] + * [`num_additional_inputs*input_info`:`input_info`] + * [`u16`:`num_outputs`] + * [`num_outputs*output_info`:`output_info`] + +#### Requirements + +The sending node: + - MUST have sent `open_channel2`. + - MUST NOT have sent or received a `funding_locked` message. + - MUST send a `feerate_per_kw_funding` greater than the most recently + negotiated rate. + - MAY update the `feerate_per_kw`, the commitment transaction feerate. + - MAY include additional inputs. + - MAY set the `num_inputs` to zero. + - MUST transmit all outputs, excluding the channel funding output. + - MAY include at least one output with the `sats` set to zero, + to be used as the change output. + +The receiving node: + - MUST return an error if: + - the `feerate_per_kw_funding` is not greater than the previously + negotiated rate. + + +#### Rationale +The sending node's half of the funding transaction will be composed with +all of the previously relayed inputs plus the ones included here. + +All outputs must be transmitted in the `init_rbf` message, including +ones communicated previously, except for the channel funding output. + +If a valid `funding_locked` message is received in the middle of an +RBF workflow, the RBF attempt MUST be abandoned. + + +### Acknowledging Replace-By-Fee `ack_rbf` + +This message acknowledges the start of an RBF workflow. + +1. type: 71 (`ack_rbf`) +2. data: + * [`channel_id`:`channel_id`] + +#### Requirements + +The sending node: + - MUST NOT have already sent or received a `funding_locked` message + for this channel. + - MUST NOT have seen the previously signed funding transaction appear + in a block + +The receiving node: + - MUST respond with a `commitment_signed` message for the + updated funding transaction. + +#### Rationale + +Signals to receiving node to proceed with commitment signature exchange. + + ## 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 c72bd0981..59ca07f98 100644 --- a/03-transactions.md +++ b/03-transactions.md @@ -35,6 +35,7 @@ This details the exact format of on-chain transactions, which both sides need to * [Generation Tests](#generation-tests) * [Storage Tests](#storage-tests) * [Appendix E: Key Derivation Test Vectors](#appendix-e-key-derivation-test-vectors) + * [Appendix F: Dual Funded Transaction Test Vectors](#appendix-f-dual-funded-transaction-test-vectors) * [References](#references) * [Authors](#authors) @@ -383,6 +384,43 @@ A node: - if the resulting fee rate is too low: - MAY fail the channel. +## Channel Establishment v2 Funding Transaction Fees + +For channel establishment v2, fees are paid by the opener (the node that +sends the `open_channel` message). Change, if any, is paid to the +opener's change address, a zero value output in their output set. + +A change output of value `change_satoshis` will be included if its +value is greater than `dust_limit_satoshis`. + +``` + change_satoshis = sum(inputs.satoshis) - est_tx_fee + - sum(outputs.satoshis) - sum(funding_satoshis) +``` + +### Calculating `est_tx_fee` + +The fee for a v2 funding transaction is calculated in up to two rounds. + - if the `opener` provided a change address, first: + - MUST calculate the `est_tx_fee` as: + 1. Multiply (funding_transaction_weight + witness_weight) by `feerate_per_kw_funding` + and divide by 1000 (rounding down). + 2. Confirm that `change_satoshis` is greater than `dust_limit_satoshis`. + - if no change address is provided or `change_satoshis` is less + than or equal to the negotiated `dust_limit_satoshis`: + - MUST calculate the `est_tx_fee` without the change output (if provided) as: + 1. Multiply (funding_transaction_weight - change_output_weight + + witness_weight) by `feerate_per_kw_funding` and divide by + 1000 (rounding down). + 2. As there is no change_output, any remaining `change_satoshis` + will be added to the funding output, and credited to the opener's + initial channel balance. + - if the resulting `change_satoshis` is less than zero: + - `opener_funding` will be decreased by the difference. + + +Computation details are included in [Appendix A](#appendix-a-expected-weights) and [Appendix F, Dual Funded Transaction Test Vectors](#appendix-f-dual-funded-transaction-test-vectors). + ## Commitment Transaction Construction This section ties the previous sections together to detail the @@ -606,6 +644,44 @@ 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 + + ## Expected Weight of the Commitment Transaction The *expected weight* of a commitment transaction is calculated as follows: @@ -868,7 +944,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). @@ -1564,6 +1640,235 @@ All of them use the following secrets (and thus the derived points): # => 0xd09ffff62ddb2297ab000cc85bcb4283fdeb6aa052affbc9dddcf33b61078110 revocationprivkey: 0xd09ffff62ddb2297ab000cc85bcb4283fdeb6aa052affbc9dddcf33b61078110 +# Appendix F: 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): + +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 `funding_compose.input_info` (inputs 0+1 above): +``` + num_inputs: 2 + input_info:[ + { + satoshis: 250000000, + prev_txid: 4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9, + prev_vout: 0, + prev_scriptpubkey_len: 34, + prev_scriptpubkey: 0020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b946, + max_witness_len: 75, + scriptlen: 0, + script: null + },{ + satoshis: 250000000, + prev_txid: 4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9, + prev_vout: 1, + prev_scriptpubkey_len: 23, + prev_scriptpubkey: a9146a235d064786b49e7043e4a042d4cc429f7eb69487, + max_witness_len: 75, + scriptlen: 34, + script: 0020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b946 + } + ] +``` + +Expected Accepter's `funding_compose.input_info` (inputs 2+3 above): +``` + num_inputs: 2 + input_info:[ + { + satoshis: 250000000, + prev_txid: 4303ca8ff10c6c345b9299672a66f111c5b81ae027cc5b0d4d39d09c66b032b9, + prev_vout: 2, + prev_scriptpubkey_len: 22, + prev_scriptpubkey: 0014fbb4db9d85fba5e301f4399e3038928e44e37d32, + max_witness_len: 109, + scriptlen: 0, + script: null + },{ + satoshis: 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 +``` + +Unsigned Funding Transaction: +``` +0200000004b932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430000000000ffffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430100000000ffffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430200000000ffffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430300000000ffffffff03ea7f0100000000001600141ca1cca8855bad6bc1ea5436edd8cff10b7e448b00c2eb0b0000000016001444cb0c39f93ecc372b5851725bd29d865d333b106081ad2f00000000220020297b92c238163e820b82486084634b4846b86a3c658d87b9384192e6bea98ec500000000 +``` + +Signed Funding Transaction: +``` +02000000000104b932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430000000000ffffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430100000023220020fd89acf65485df89797d9ba7ba7a33624ac4452f00db08107f34257d33e5b946ffffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430200000000ffffffffb932b0669cd0394d0d5bcc27e01ab8c511f1662a6799925b346c0cf18fca03430300000017160014fbb4db9d85fba5e301f4399e3038928e44e37d32ffffffff03ea7f0100000000001600141ca1cca8855bad6bc1ea5436edd8cff10b7e448b00c2eb0b0000000016001444cb0c39f93ecc372b5851725bd29d865d333b106081ad2f00000000220020297b92c238163e820b82486084634b4846b86a3c658d87b9384192e6bea98ec5022068656c6c6f2074686572652c2074686973206973206120626974636f6e2121212782012088a820add57dfe5277079d069ca4ad4893c96de91f88ffb981fdc6a2a34d5336c66aff87022068656c6c6f2074686572652c2074686973206973206120626974636f6e2121212782012088a820add57dfe5277079d069ca4ad4893c96de91f88ffb981fdc6a2a34d5336c66aff870247304402204bd649762ff5620cd67b5b90a382dd528ae1e35063f3fdabc6f035df04bb17a502200afb3369cdf014615261e2ce2226b851809b19e678847c9780c7f25f151209cf0121034695f5b7864c580bf11f9f8cb1a94eb336f2ce9ef872d2ae1a90ee276c7724840247304402207c7e66be6518d5ad6b7f314fd392cfb7a3d980d9270cc3c0ec10e9fd752f20280220687233cbec066b71fa96434197e88e04dde2ccfd1b17c78e4d50e4bbcf6df1860121034695f5b7864c580bf11f9f8cb1a94eb336f2ce9ef872d2ae1a90ee276c77248400000000 +``` + +Weight Count: +``` + Max Witness Len: 368\* + 2 Segwit bytes (flag + marker) + Non-Witness Data Byte Count: 337 + Total Weight: 370 + 337 * 4 = 1718 +``` +\* The signatures calculated for this transaction come to 71-bytes. + + +## Fee Calculation +Assuming a total of 10 Bitcoin inputs, 5btc from each peer. + +Opener's `funding_satoshi` is `499900000` (4.999btc), with a single +change output provided. +Accepter `funding_satoshi` is `300000000` (3btc), with `200000000` (2btc) +to their change address. + +Output1 is Opener's change address output. +Output2 is the Accepter's output. +Output3 is the Channel Funding output. + +All fractional fees are rounded down. + +### Example A: Positive Change Value +With `feerate_per_kw_funding` communicated at `1000 sats/kw`: + +``` + Fee: 0.00001716 btc + Output1: 0.00098284 btc + Output2: 2.0 btc + Output3: 7.999 btc + + Opener (A) Starting Balance: 4.999 btc + Accepter (B) Starting Balance: 3 btc +``` + +### Example B: Negative Change on Round 1, Negative Change on Round 2 +With `feerate_per_kw_funding` communicated at `100k sats/kw`: + +Round1: +``` + Fee: 0.00171600 btc + Output1: -0.00071600 btc + Output2: 2.0 btc + Output3: 7.999 btc +``` + +Round2, Re-calculate transaction, with Output1 removed: + +``` + Max Witness Len: 368 + Non-Witness Data Byte Count: 306 + Total Weight: 1592 +``` + +``` + Fee: 0.00159200 btc + Output2: 2.0 btc + Output3: 7.99840800 btc + + Opener (A) Starting Balance: 4.99850800 btc + Accepter (B) Starting Balance: 3 btc +``` + +### Example C: Negative Change on Round 1, Positive Change on Round 2 +With `feerate_per_kw_funding` communicated at `60k sats/kw`: + +Round1: +``` + Fee: 0.00102960 btc + Output1: -0.00002960 btc + Output2: 2.0 btc + Output3: 7.999 btc +``` + +Round2: +``` + Max Witness Len: 368 + Non-Witness Data Byte Count: 306 + Total Weight: 1592 +``` + +``` + Fee: 0.00095520 btc + Output2: 2.0 btc + Output3: 7.99904480 btc + + Opener (A) Starting Balance: 4.99904480 btc + Accepter (B) Starting Balance: 3 btc +``` + + # References # Authors diff --git a/09-features.md b/09-features.md index 74e1c7925..8adad471c 100644 --- a/09-features.md +++ b/09-features.md @@ -37,6 +37,7 @@ The Context column decodes as follows: | 12/13 | `option_static_remotekey` | Static key for remote output | IN | | [BOLT #3](03-transactions.md) | | 14/15 | `payment_secret` | Node supports `payment_secret` field | IN9 | `var_onion_optin` | [Routing Onion Specification][bolt04] | | 16/17 | `basic_mpp` | Node can receive basic multi-part payments | IN9 | `payment_secret` | [BOLT #4][bolt04-mpp] | +| 28/29 | `option_dual_fund` | Use v2 of channel open, enables dual funding | IN9 | | [BOLT #2](02-peer-protocol.md) | ## Requirements diff --git a/tools/spellcheck.sh b/tools/spellcheck.sh index c11bc1723..09e0bfa07 100755 --- a/tools/spellcheck.sh +++ b/tools/spellcheck.sh @@ -68,7 +68,7 @@ do -e 's/[a-fA-F0-9]\{20,\}//g' \ -e 's/^ .*_htlcs//g' \ -e 's/ ln\(bc\|tb\)[0-9munp]*1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]\+//g' \ - -e 's/ \(bc\|tb\)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]\+//g' \ + -e 's/ \(bc\|tb\|bcrt\)1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]\+//g' \ -e 's/[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]\{20,\}//g' < $f | aspell -l en_US --home-dir ${homedir} list) if [ -n "$WORDS" ]; then echo Misspelled words in $f: $WORDS >&2