lisa neigut [ARCHIVE] on Nostr: š Original date posted:2018-11-27 š Original message: Hello fellow Lightning ...
š
Original date posted:2018-11-27
š Original message:
Hello fellow Lightning devs!
What follows is a draft for the new dual funding flow. Note that the
`option_will_fund_for_food` specification has been omitted for this draft.
===== Proposal
Create a new channel open protocol set (v2), with three new message types:
`funding_puts2`, `commitment_signed2`, and `funding_signed2`, plus two for
negotiating RBF, `init_rbf` and `accept_rbf`.
Quick overview of the message exchange for v2:
+-------+ +-------+
| |--(1)--- open_channel2 ---->| |
| |<-(2)-- accept_channel2 ----| |
| | | |
| |--(3)-- funding_puts2 ----->| |
| |<-(4)-- funding_puts2 ----- | |
| | | |
--->| |--(5)-- commitment_signed2 -->| |
| | |<-(6)-- commitment_signed2 ---| |
| | A | | B |
| | |--(7)--- funding_signed2 ---->| |
| | |<-(8)--- funding_signed2 -----| |
| | | | |
| | |--(a)--- init_rbf ----------->| |
----| |<-(b)--- accept_rbf ----------| |
| | | |
| |--(9)--- funding_locked2 ---->| |
| |<-(10)---funding_locked2 -----| |
+-------+ +-------+
where node A is the āinitiatorā and node B is the ādual-funderā
== Negotiating the use of dual_funding (open_channel2) flow
Willingness to use v2 is flagged in init via `option_dual_fund`.
`init`
local channel feature flag, `option_dual_fund`
== Channel establishment with dual_funding
____`open_channel2`:
[32:chain_hash]
ā¦ // unchanged
[1:channel_flags]
[?: options_tlv]
options_tlv:
1.
Type: 1 `option_upfront_shutdown_script`
1.
[2:len]
2.
Value: `shutdown_scriptpubkey`
If nodes have negotiated `option_dual_fund`
The sending node:
-
MAY begin channel establishment using `open_channel2`
Otherwise the receiving node:
-
MUST return an error.
____ `accept_channel2`:
[32:temporary_channel_id]
ā¦ // unchanged
[33:first_per_commitment_point]
[?: options_tlv]
options_tlv:
1.
Type: 1 `option_upfront_shutdown_script`
[2:len]
Value: `shutdown_scriptpubkey`
____`funding_puts2`
This message exchanges the input and output information necessary to
compose the funding transaction.
[32:temporary_channel_id]
[`2`:`num_inputs`]
[`num_inputs*input_info`]
[`2`:`num_outputs`]
[`num_outputs`*ouput_info`]
1. subtype: `input_info`
2. data:
* [`8`:`satoshis`]
* [`32`:`prevtxid`]
* [`4`:`prevtxoutnum`]
* [`2`:`scriptlen`]
* [`scriptlen`:`script`]
* [`2`:`max_extra_witness_len`]
* [`2`:`wscriptlen`]
* [`wscriptlen`:`wscript`]
1. subtype: `output_info`
2. data:
* [`8`:`satoshis`]
* [`2`:`scriptlen`]
* [`scriptlen`:`script`]
Requirements:
The sending node:
-
MUST ensure each `input_info` refers to an existing UTXO
-
MUST ensure the `output_info`.`script` is a standard script
-
MUST NOT spend any UTXOs specified in funding_puts2 until/unless the
channel establishment has failed
If is the initiator (A):
- MUST NOT send an empty message (`num_inputs` + `num_outputs` = 0)
If is the dual-funder (B):
-
consider the `put_limit` the total number of `num_inputs` plus
`num_outputs` from `funding_puts2`, with minimum 2.
-
MUST NOT send a number of `input_data` and/or `output_data` which
exceeds the `put_limit`
-
MAY send an empty message
The receiving node:
If is the initiator (A):
-
MUST fail the channel if the `num_inputs` plus `num_outputs` is greater
than the `put_limit`
If has not yet sent a `fund_puts2` for this channel establishment
- SHOULD send their `fund_puts2` message
Otherwise
-
SHOULD send `commitment_signed2`
Rationale:
Each node must have a complete set of the transaction inputs/outputs, to
derive the funding transaction hash.
There is a dual_funding protocol that only requires one side to send their
witness data and inputs. This is more efficient, however it results in
asymmetry between the nodes, where one is revealing their UTXOs before the
funding transaction is committed.. We mitigate this asymmetry by asking the
initiator (A) to send their set of inputs before the dual-funder (B) does.
NB: This is reusing the input/output structures from the Splicing proposal,
but with a more generalized name.
____`commitment_signed2`
This message exchanges the counterpartyās signature for the first
commitment transaction, so it can broadcast the funding transaction knowing
that funds can be redeemed.
[32: `channel_id`]
[`64`: commitment_signature`]
Requirements:
The sending node:
-
MUST derive the `channel_id` from the funding transactionās id
-
MUST set signature to the valid signature, using its funding_pubkey for
the initial commitment transaction, as defined in BOLT #3
If it has not received a `funding_puts2`
-
MUST NOT send their `commitment_signature`
The receiving node:
-
MUST verify the commitment signature is valid for the funding
transaction -> commitment transaction that it has derived independently
If this signature is invalid it
-
MUST fail the channel
If it has not sent a `commitment_signed2` message
-
MUST send their `commitment_signed2` message
If this is in a flow initiated from `init_rbf`,:
-
MUST save the temporary_channel_id until the channel funding transaction
has been locked (this is the channel id of the currently broadcast
transaction)
Rationale:
In the previous channel establishment protocol, we were able to compress
the commitment signature exchange into `funding_created`/`funding_signed`.
With dual funding, we need interaction to build the funding transaction --
commitment sig exchange is now a separate step.
___`funding_signed2`
This message exchanges the witness data for the inputs that were originally
sent in the `funding_puts2` message.
[`32`:`channel_id`]
[`2`:`num_witnesses`]
[`num_witnesses*witness_stack`]
Requirements:
The sending node:
- MUST remember the details of this funding transaction
- MUST NOT send a `witness_stack` whose length exceeds the corresponding
`max_extra_witness_len`
If they have NOT received a valid `commitment_signed2` message
-
MUST not send their `funding_signed2` message
The receiving node:
-
SHOULD check that the number of witnesses sent matches the number of
inputs
If a `witness_stack` length exceeds the corresponding
`max_extra_witness_len`:
-
MAY error.
If is the `initiator` (A):
-
SHOULD apply `witness` to the funding transaction and broadcast the
result.
Rationale:
Exchanging witness data allows either side to broadcast the funding
transaction. It also maintains the information symmetry between the nodes.
___`funding_locked2`
// same as v1
Requirements:
A dual-funding node (B):
-
SHOULD broadcast their funding transaction if it does not see the
transaction broadcast after a reasonable timeout.
== RBF for Channel Establishment v2
_____`init_rbf`
This message is sent by the initiator, after the funding transaction has
been broadcast but before the `funding_locked2` has been exchanged.
[32: `channel_id`]
[8: funding_satoshis]
[8:dust_limit_satoshis]
[8:channel_reserve_satoshis]
[4: feerate_per_kw]
[`2`:`num_inputs`]
[`num_inputs*input_info`]
[`2`:`num_outputs`]
[`num_outputs`*ouput_info`]
Requirements
The sending node:
-
MUST be the initiator (A)
-
MAY update the amount, fee rate, dust limit, or channel reserve for the
channel
The receiving node:
-
MAY reject (error) the RBF request if:
-
the fee rate, dust, or channel reserve is unreasonable
-
MUST reject (error) the RBF request if:
-
the `fee_rate` is less than the rate that was originally proposed
-
the `funding_satoshis` amount is less than the previous negotiated
`push_mast`
-
It considers the `feerate_per_kw` too small for timely processing or
unreasonable
-
the `dust_limit_satoshis` is greater than the
`channel_reserve_satoshis`
-
the initiatorās amount for the initial commitment transaction is not
sufficient for full fee payment
-
the `inputs`.`satoshis` does not sum to the `funding_satoshis`
-
the `funding_satoshis` is insufficient to create the transaction at
the new `fee_rate`
-
there is no overlap in the proposed inputs and the original input set
included in the currently published funding transaction
-
they have already received or sent a `funding_locked2` message
-
If there are no errors or unreasonable demands:
-
SHOULD send an `accept_rbf`
Rationale:
Once an `init_rbf` has been accepted by the dual-funding node, the message
flow returns to `commitment_signed2` and proceeds as above, with the
exception that the `temporary_channel_id` remains as the `channel_id` for
the currently published but unmined transaction.
The channel id that becomes fixed for this node will be determined by the
`funding_locked2` message.
___`accept_rbf`
This message accepts an RBF request, and renegotiates a dual-funderās
funds, dust limit, and channel reserve, and sends the dual-funderās updated
puts.
[32: `channel_id`]
[8: funding_satoshis]
[8:ndust_limit_satoshis]
[8:channel_reserve_satoshis]
[`2`:`num_inputs`]
[`num_inputs*input_info`]
[`2`:`num_outputs`]
[`num_outputs`*ouput_info`]
Requirements:
The sending node:
-
MAY update the amount, dust limit, or channel reserve for the channel
The receiving node:
-
MAY reject (error) the RBF request if:
-
the dust or channel reserve is unreasonable
-
MUST reject (error) the RBF request if:
-
the `funding_satoshis` amount is less than the previous negotiated
`push_mast`
-
the `dust_limit_satoshis` is greater than the
`channel_reserve_satoshis`
-
the total fees incurred by the `input_info`s and `output_info`s at
the new `fee_rate` is more than their `funding_satoshis`
otherwise:
-
SHOULD send a `commitment_signed2` message
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20181127/b864846e/attachment-0001.html>
š Original message:
Hello fellow Lightning devs!
What follows is a draft for the new dual funding flow. Note that the
`option_will_fund_for_food` specification has been omitted for this draft.
===== Proposal
Create a new channel open protocol set (v2), with three new message types:
`funding_puts2`, `commitment_signed2`, and `funding_signed2`, plus two for
negotiating RBF, `init_rbf` and `accept_rbf`.
Quick overview of the message exchange for v2:
+-------+ +-------+
| |--(1)--- open_channel2 ---->| |
| |<-(2)-- accept_channel2 ----| |
| | | |
| |--(3)-- funding_puts2 ----->| |
| |<-(4)-- funding_puts2 ----- | |
| | | |
--->| |--(5)-- commitment_signed2 -->| |
| | |<-(6)-- commitment_signed2 ---| |
| | A | | B |
| | |--(7)--- funding_signed2 ---->| |
| | |<-(8)--- funding_signed2 -----| |
| | | | |
| | |--(a)--- init_rbf ----------->| |
----| |<-(b)--- accept_rbf ----------| |
| | | |
| |--(9)--- funding_locked2 ---->| |
| |<-(10)---funding_locked2 -----| |
+-------+ +-------+
where node A is the āinitiatorā and node B is the ādual-funderā
== Negotiating the use of dual_funding (open_channel2) flow
Willingness to use v2 is flagged in init via `option_dual_fund`.
`init`
local channel feature flag, `option_dual_fund`
== Channel establishment with dual_funding
____`open_channel2`:
[32:chain_hash]
ā¦ // unchanged
[1:channel_flags]
[?: options_tlv]
options_tlv:
1.
Type: 1 `option_upfront_shutdown_script`
1.
[2:len]
2.
Value: `shutdown_scriptpubkey`
If nodes have negotiated `option_dual_fund`
The sending node:
-
MAY begin channel establishment using `open_channel2`
Otherwise the receiving node:
-
MUST return an error.
____ `accept_channel2`:
[32:temporary_channel_id]
ā¦ // unchanged
[33:first_per_commitment_point]
[?: options_tlv]
options_tlv:
1.
Type: 1 `option_upfront_shutdown_script`
[2:len]
Value: `shutdown_scriptpubkey`
____`funding_puts2`
This message exchanges the input and output information necessary to
compose the funding transaction.
[32:temporary_channel_id]
[`2`:`num_inputs`]
[`num_inputs*input_info`]
[`2`:`num_outputs`]
[`num_outputs`*ouput_info`]
1. subtype: `input_info`
2. data:
* [`8`:`satoshis`]
* [`32`:`prevtxid`]
* [`4`:`prevtxoutnum`]
* [`2`:`scriptlen`]
* [`scriptlen`:`script`]
* [`2`:`max_extra_witness_len`]
* [`2`:`wscriptlen`]
* [`wscriptlen`:`wscript`]
1. subtype: `output_info`
2. data:
* [`8`:`satoshis`]
* [`2`:`scriptlen`]
* [`scriptlen`:`script`]
Requirements:
The sending node:
-
MUST ensure each `input_info` refers to an existing UTXO
-
MUST ensure the `output_info`.`script` is a standard script
-
MUST NOT spend any UTXOs specified in funding_puts2 until/unless the
channel establishment has failed
If is the initiator (A):
- MUST NOT send an empty message (`num_inputs` + `num_outputs` = 0)
If is the dual-funder (B):
-
consider the `put_limit` the total number of `num_inputs` plus
`num_outputs` from `funding_puts2`, with minimum 2.
-
MUST NOT send a number of `input_data` and/or `output_data` which
exceeds the `put_limit`
-
MAY send an empty message
The receiving node:
If is the initiator (A):
-
MUST fail the channel if the `num_inputs` plus `num_outputs` is greater
than the `put_limit`
If has not yet sent a `fund_puts2` for this channel establishment
- SHOULD send their `fund_puts2` message
Otherwise
-
SHOULD send `commitment_signed2`
Rationale:
Each node must have a complete set of the transaction inputs/outputs, to
derive the funding transaction hash.
There is a dual_funding protocol that only requires one side to send their
witness data and inputs. This is more efficient, however it results in
asymmetry between the nodes, where one is revealing their UTXOs before the
funding transaction is committed.. We mitigate this asymmetry by asking the
initiator (A) to send their set of inputs before the dual-funder (B) does.
NB: This is reusing the input/output structures from the Splicing proposal,
but with a more generalized name.
____`commitment_signed2`
This message exchanges the counterpartyās signature for the first
commitment transaction, so it can broadcast the funding transaction knowing
that funds can be redeemed.
[32: `channel_id`]
[`64`: commitment_signature`]
Requirements:
The sending node:
-
MUST derive the `channel_id` from the funding transactionās id
-
MUST set signature to the valid signature, using its funding_pubkey for
the initial commitment transaction, as defined in BOLT #3
If it has not received a `funding_puts2`
-
MUST NOT send their `commitment_signature`
The receiving node:
-
MUST verify the commitment signature is valid for the funding
transaction -> commitment transaction that it has derived independently
If this signature is invalid it
-
MUST fail the channel
If it has not sent a `commitment_signed2` message
-
MUST send their `commitment_signed2` message
If this is in a flow initiated from `init_rbf`,:
-
MUST save the temporary_channel_id until the channel funding transaction
has been locked (this is the channel id of the currently broadcast
transaction)
Rationale:
In the previous channel establishment protocol, we were able to compress
the commitment signature exchange into `funding_created`/`funding_signed`.
With dual funding, we need interaction to build the funding transaction --
commitment sig exchange is now a separate step.
___`funding_signed2`
This message exchanges the witness data for the inputs that were originally
sent in the `funding_puts2` message.
[`32`:`channel_id`]
[`2`:`num_witnesses`]
[`num_witnesses*witness_stack`]
Requirements:
The sending node:
- MUST remember the details of this funding transaction
- MUST NOT send a `witness_stack` whose length exceeds the corresponding
`max_extra_witness_len`
If they have NOT received a valid `commitment_signed2` message
-
MUST not send their `funding_signed2` message
The receiving node:
-
SHOULD check that the number of witnesses sent matches the number of
inputs
If a `witness_stack` length exceeds the corresponding
`max_extra_witness_len`:
-
MAY error.
If is the `initiator` (A):
-
SHOULD apply `witness` to the funding transaction and broadcast the
result.
Rationale:
Exchanging witness data allows either side to broadcast the funding
transaction. It also maintains the information symmetry between the nodes.
___`funding_locked2`
// same as v1
Requirements:
A dual-funding node (B):
-
SHOULD broadcast their funding transaction if it does not see the
transaction broadcast after a reasonable timeout.
== RBF for Channel Establishment v2
_____`init_rbf`
This message is sent by the initiator, after the funding transaction has
been broadcast but before the `funding_locked2` has been exchanged.
[32: `channel_id`]
[8: funding_satoshis]
[8:dust_limit_satoshis]
[8:channel_reserve_satoshis]
[4: feerate_per_kw]
[`2`:`num_inputs`]
[`num_inputs*input_info`]
[`2`:`num_outputs`]
[`num_outputs`*ouput_info`]
Requirements
The sending node:
-
MUST be the initiator (A)
-
MAY update the amount, fee rate, dust limit, or channel reserve for the
channel
The receiving node:
-
MAY reject (error) the RBF request if:
-
the fee rate, dust, or channel reserve is unreasonable
-
MUST reject (error) the RBF request if:
-
the `fee_rate` is less than the rate that was originally proposed
-
the `funding_satoshis` amount is less than the previous negotiated
`push_mast`
-
It considers the `feerate_per_kw` too small for timely processing or
unreasonable
-
the `dust_limit_satoshis` is greater than the
`channel_reserve_satoshis`
-
the initiatorās amount for the initial commitment transaction is not
sufficient for full fee payment
-
the `inputs`.`satoshis` does not sum to the `funding_satoshis`
-
the `funding_satoshis` is insufficient to create the transaction at
the new `fee_rate`
-
there is no overlap in the proposed inputs and the original input set
included in the currently published funding transaction
-
they have already received or sent a `funding_locked2` message
-
If there are no errors or unreasonable demands:
-
SHOULD send an `accept_rbf`
Rationale:
Once an `init_rbf` has been accepted by the dual-funding node, the message
flow returns to `commitment_signed2` and proceeds as above, with the
exception that the `temporary_channel_id` remains as the `channel_id` for
the currently published but unmined transaction.
The channel id that becomes fixed for this node will be determined by the
`funding_locked2` message.
___`accept_rbf`
This message accepts an RBF request, and renegotiates a dual-funderās
funds, dust limit, and channel reserve, and sends the dual-funderās updated
puts.
[32: `channel_id`]
[8: funding_satoshis]
[8:ndust_limit_satoshis]
[8:channel_reserve_satoshis]
[`2`:`num_inputs`]
[`num_inputs*input_info`]
[`2`:`num_outputs`]
[`num_outputs`*ouput_info`]
Requirements:
The sending node:
-
MAY update the amount, dust limit, or channel reserve for the channel
The receiving node:
-
MAY reject (error) the RBF request if:
-
the dust or channel reserve is unreasonable
-
MUST reject (error) the RBF request if:
-
the `funding_satoshis` amount is less than the previous negotiated
`push_mast`
-
the `dust_limit_satoshis` is greater than the
`channel_reserve_satoshis`
-
the total fees incurred by the `input_info`s and `output_info`s at
the new `fee_rate` is more than their `funding_satoshis`
otherwise:
-
SHOULD send a `commitment_signed2` message
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/lightning-dev/attachments/20181127/b864846e/attachment-0001.html>