Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Dual Funding (v2 Channel Establishment protocol) #524

Open
wants to merge 44 commits into
base: master
from

Conversation

@niftynei
Copy link
Collaborator

niftynei commented Dec 5, 2018

This is a first draft proposal for adding a second open channel version. This will empower either side of the channel to contribute to the funding transaction.

Broadly speaking, the largest change between this and version one of open_channel is that both sides now construct and broadcast the funding transaction. This adds a few more communication rounds, as the commitment transaction signatures can't be exchanged until both sides have the info necessary to construct the funding transaction.

Errata

Copy link
Collaborator

rustyrussell left a comment

This is generally good, and I like the rbf flow. @Roasbeef suggested we keep it more minimal (ie. no change of inputs), but that doesn't gain very much compared to this approach, AFAICT.

I've bikeshedded a few things, because that's what we do :)

- MUST fail the channel if:
- `change_satoshis` would be negative.
- if has not yet sent a `funding_compose`:
- MUST send their `funding_compose` message.

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Dec 10, 2018

Collaborator

s/their/its/

- MUST send their `funding_compose` message.
- otherwise:
- MUST use the sent and received `input_info` and `output_info`
to create the funding transaction, using `max_extra_witness_len`

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Dec 10, 2018

Collaborator

It's now called 'max_witness_len'.

the `put_limit`.
- otherwise:
- MUST fail the channel if:
- `change_satoshis` would be negative.

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Dec 10, 2018

Collaborator

It may not be able to figure this out yet (fees). So, perhaps this should be 'sum of input amounts < sum of output amounts'? And add the change_satoshis test only once it has calculated the tx?

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Dec 10, 2018

Collaborator

Hmm, actually, I think this being negative should be allowed: in that case, funding_satoshis should be reduced. In effect, this allows you to say "I don't want change, take the fee out of my initial balance". Or perhaps we should make the change output optional for this case?

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 30, 2019

Author Collaborator

This seems like a valid use case. Will remove the 'change_satoshis must be positive' requirement.

Allowing negative change amounts means the resulting channel balance will be less than the indicated funding_satoshis, which ostensibly came from the user. Implementations would probably want to add a way for users to indicate where to take the fees out -- either the provided channel fund amount or in addition to that. (You could do this with the existing flow too, since it's just UX.)

My hesitation with making the change_address optional is that 1) it's an edge case (depends on available UTXO set) 2) it has a small chance of introducing bugs (i.e. broken implementation forgets to include a change address so you end up with a huge channel balance by accident). Leaving out the change address doesn't save you much in calculation overhead when picking out the input UTXO set either. The only thing it does save on is wire bytes, in the case where your funding amt works out exactly right.

to create the funding transaction, using `max_extra_witness_len`
for each `input_info` and `feerate_per_kw_funding` as specified in
`open_channel2`.
- MUST send `commitment_signed2`.

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Dec 10, 2018

Collaborator

Can we just use commitment_signed. It's identical, and performs the identical function, so I really think it deserves the same name...

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 26, 2019

Author Collaborator

Right. The rationale was that it might be nice to decouple the two flows as that would allow future modification without needing to worry much about backwards compatibility.


`satoshis` is the value of the input or output. The opener must provide
one change address for the transaction, which is flagged with a
`satoshis` value of zero.

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Dec 10, 2018

Collaborator

You said this below as well; delete one? We try to avoid spec-sounding language (i.e. "must") in Rationales to avoid confusion; I would say "The opener provides one output with satoshis equal zero, as a change address once the amount of change can be calculated".

#### Requirements
The sending node:
- MUST set `witness` to the marshalled witness data for each of its
inputs, in funding transaction order. FIXME: add reference

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Dec 10, 2018

Collaborator

I realize this is quoting me, but the term I should have used is 'serialized' which IIRC is what the BIPs use.

Exchanging witness data allows both sides to broadcast the funding
transaction and maintains information symmetry.

### The `funding_locked2` Message

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Dec 10, 2018

Collaborator

Again, prefer direct 'funding_locked' reuse.

This comment has been minimized.

Copy link
@niftynei

niftynei Feb 13, 2019

Author Collaborator

inclusion of the funding_tx_id means we need a v2 for this

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Mar 4, 2019

Collaborator

Hmm, OK.

* [`4`:`feerate_per_kw`]
* [`4`:`feerate_per_kw_funding`]
* [`2`:`num_inputs`]
* [`num_inputs`\*`input_info`]

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Dec 10, 2018

Collaborator

num_additional_inputs might be clearer?

e.g. an `output_info` entry with `satoshis` set to zero.
- the `feerate_per_kw_funding` is not greater than the previously
negotiated rate.
- `change_satoshis` is negative.

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Dec 10, 2018

Collaborator

I think we should allow "extract from channel" in this case, as well.

02-peer-protocol.md Show resolved Hide resolved
@rustyrussell rustyrussell added this to the v1.1 milestone Dec 10, 2018
@niftynei niftynei force-pushed the niftynei:dual-funding branch from 00c6e6f to 8bacfe4 Feb 6, 2019
@niftynei niftynei changed the title WIP: dual funding first draft WIP: Dual Funding (v2 Channel Establishment protocol) Feb 6, 2019
#### Requirements

The sending node:
- MUST ensure each `input_info` refers to an existing UTXO

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Mar 4, 2019

Collaborator

Moreover, it must ensure that it's non-malleable.

- MAY send zero inputs and/or outputs.
The receiving node:
- if the total `input_info`.`satoshis` is less than the total `output_info`.`satoshis`

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Mar 4, 2019

Collaborator

(Summary of discussion with @niftynei elsewhere)

Unfortunately, the receiving node needs to know this input is not malleable. That requires that it know the output being spent. We could either have the sender include the entire TX, or insist the recipient know the UTXO. Both are unappealing: the 64k packet size means some txs can't be used, and the UTXO requirement means no CPFP.

I think we have to go for "send the input tx"; creating a "fetch tx" for this would lead to another untested code path. Which makes this different from splice, which doesn't have this problem.

This comment has been minimized.

Copy link
@niftynei

niftynei Mar 6, 2019

Author Collaborator

Thinking about this more, I think we can simplify this requirement by checking the scriptSig data in addition to the txid/vout for inputs, and merely verifying that it is either 00 or one of the two acceptable v0 redeemScript formats for P2SH-P2W*. (i.e. 0014xxx or 0020xxx)

This comment has been minimized.

Copy link
@niftynei

niftynei Mar 7, 2019

Author Collaborator

Ok, updated to include the scriptPubKey of the desired output as well.

Exchanging witness data allows both sides to broadcast the funding
transaction and maintains information symmetry.

### The `funding_locked2` Message

This comment has been minimized.

Copy link
@rustyrussell

rustyrussell Mar 4, 2019

Collaborator

Hmm, OK.

@niftynei niftynei force-pushed the niftynei:dual-funding branch 2 times, most recently from 3cb65ff to 4c0a516 Mar 7, 2019
@niftynei niftynei force-pushed the niftynei:dual-funding branch 3 times, most recently from bc409b8 to cb8990b Apr 2, 2019
@niftynei

This comment has been minimized.

Copy link
Collaborator Author

niftynei commented Apr 30, 2019

Working on the implementation of this for c-lightning, and I've hit a bit of a conundrum around what's the best way forward wrt the channel_reserve_satoshi.

In v1 of the channel establishment protocol, the entire funding balance is known as of the first open_channel message. In v2, the entire funding balance won't be known until after accept_channel2 has been exchanged.

Here's a few options that I've come up with for how to deal with this. Leaning towards the 3rd option.

  • leave it as is, and have both the opener and the accepter's values be based on the opener's funding_satoshis value (same as v1)
  • leave the opener's reserve requirement to be the same, and have the accepter's value include their contribution as well. e.g. the opener sends funding_satoshi: 10 000 and channel_reserve_satoshi: 1 000; accepter sends funding_satoshis:10 000 and channel_reserve_satoshi:2 000.
  • move the channel_reserve_satoshi field to the funding_compose message, so that the entire funding balance can be taken into account. e.g. both would send channel_reserve_satoshi:2 000 (which is 1% of the entire funding balance).
  • remove the channel_reserve_satoshi field altogether, and set it permanently at 1% of the entire funding balance
@niftynei niftynei force-pushed the niftynei:dual-funding branch from 7d50c70 to 2b1cf09 Jul 24, 2019
@niftynei niftynei force-pushed the niftynei:dual-funding branch from 2b1cf09 to 1a9a018 Oct 1, 2019
@niftynei niftynei force-pushed the niftynei:dual-funding branch from 1a9a018 to 867a6d8 Oct 11, 2019

If nodes have negotiated `option_dual_fund`:
- the opening node:
- MUST not send `open_channel`

This comment has been minimized.

Copy link
@darosior

darosior Oct 30, 2019

Contributor

nit

Suggested change
- MUST not send `open_channel`
- MUST NOT send `open_channel`
- MUST add all received inputs to the funding transaction
- MUST fail the channel if:
- it receives a duplicate input to one it sent previously
- if it receives this message after `funding_add_complete` is received.

This comment has been minimized.

Copy link
@darosior

darosior Oct 30, 2019

Contributor

nit: trailing if

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 `accepter` node may omit this message.

This comment has been minimized.

Copy link
@niftynei

niftynei Nov 13, 2019

Author Collaborator

ack, removed.

- 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 3 outputs, across all `funding_add_output`s
Comment on lines 701 to 709

This comment has been minimized.

Copy link
@darosior

darosior Oct 30, 2019

Contributor

max of 8 then 3 ?

- 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 3 outputs, across all `funding_add_output`s
Comment on lines 701 to 709

This comment has been minimized.

Copy link
@darosior

darosior Oct 30, 2019

Contributor

max of 8 then 3 ?

- 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_sats, specified earlier

This comment has been minimized.

Copy link
@darosior

darosior Oct 30, 2019

Contributor
Suggested change
the funding_sats, specified earlier
the `funding_satoshis`, specified earlier

### The `funding_signed2` Message

This message contains witness data for for the inputs that were

This comment has been minimized.

Copy link
@darosior

darosior Oct 30, 2019

Contributor
Suggested change
This message contains witness data for for the inputs that were
This message contains witness data for the inputs that were
- MUST return an error if:
- the `feerate_per_kw_funding` is not greater than the previously
negotiated rate.
- MUST return an error, but not fail the channel if:

This comment has been minimized.

Copy link
@darosior

darosior Oct 30, 2019

Contributor

How does the remote node know that it should not fail the channel upon receiving the error ?

This comment has been minimized.

Copy link
@niftynei

niftynei Nov 1, 2019

Author Collaborator

This is, at best, a case for the 'soft error' idea that @rustyrussell has been talking about. Clearly the node that sent you the init_rbf is confused, the polite thing to do in the case is to inform them that they've made a mistake. The other option, without a 'soft error' is probably to ignore the init_rbf request entirely.

You make a good point though, what we really want here is that a node MUST NOT send an init_rbf if it has already sent a funding_locked message.

* [`u16`:`num_outputs`]
* [`num_outputs*output_info`:`output_info`]

#### Requirements

This comment has been minimized.

Copy link
@darosior

darosior Oct 30, 2019

Contributor

As it has been stated for other messages, maybe :

Either node:
    - MAY omit this message

?

- MAY include additional inputs.
- MAY set the `num_inputs` to zero.
- MUST transmit all outputs, excluduing the channel funding output.
- MAY include at least one output with the `sats` set to zero,

This comment has been minimized.

Copy link
@darosior

darosior Oct 30, 2019

Contributor

Should we also specify which output to reduce ?

This comment has been minimized.

Copy link
@darosior

darosior Oct 30, 2019

Contributor

Hmm reading further it seems that the opener should pay for the fees. Maybe we then should explicit the receiver of init_rbf to check that the reduced (or removed) output is receiver's change ?

This comment has been minimized.

Copy link
@niftynei

niftynei Nov 1, 2019

Author Collaborator

Well, retransmitting all of the outputs would give you the opportunity to update the outputs as necessary.

The change output is calculated dynamically by each of the peers, and is identifiable in the output set as "the output of value zero", so you wouldn't need to update it. In fact, the change calculation should 1) drop the change output if it's below dust and 2) add or subtract any resultant amount to the opener's satoshis in the funding output. So, you wouldn't need to update the outputs on an rbf, unless you wanted to preserve your funding output's value.

This comment has been minimized.

Copy link
@darosior

darosior Nov 8, 2019

Contributor

So, you wouldn't need to update the outputs on an rbf, unless you wanted to preserve your funding output's value.

That's what I assumed: doesn't it make it more simple for both participants if the funding amount stayed the same but the fee bump was taken on the change output of the funder instead ?
Since both add inputs to the tx, they will most likely also include change outputs, at least that what I assumed when writing that.
My question was then whether to introduce an explicit MUST on the receiver side to check that the tx the funder sends does not greeds on the fundee's change output (which implems would of course do, but ..)

But maybe I'm missing something here ?

This comment has been minimized.

Copy link
@niftynei

niftynei Nov 13, 2019

Author Collaborator

That's what I assumed: doesn't it make it more simple for both participants if the funding amount stayed the same but the fee bump was taken on the change output of the funder instead ?

It's up to the funder to know what it's estimated change burden will be and add sufficient funds such that the total amount of funding is untouched by a fee-bump, if that's what they desire.

does not greeds on the fundee's change output (which implems would of course do, but ..)

Fees never come out of the accepter's change; though it might (hypothetically) start eating out of their funding balance if the opener's balance is consumed by change. Reconsidering this and the point you made earlier, a nack_rbf message (or a 'soft-error') might be appropriate here. This would allow the second node to disallow a fee update that would eat into the entirety of the fundchannel amount.

Copy link
Contributor

ariard left a comment

Really cool work! Thanks to pushing this forward

What's your thoughts about splitting the transaction composition part to enable batching from the dual-funding channel part ? There is at least 3 cases where it may be reused :

  • channel closing
  • channel novation (or splicing)
  • channel opening

I think you need one party among all being the coordinator to act as tie-breaker and avoid endless input/output add, fees changes dependencies (though there is other design issue like fees management, belongs more to the ml)

@@ -27,7 +27,8 @@ These flags may only be used in the `init` message:
| 4/5 | `option_upfront_shutdown_script` | Commits to a shutdown scriptpubkey when opening channel | [BOLT #2][bolt02-open] |
| 6/7 | `gossip_queries` | More sophisticated gossip control | [BOLT #7][bolt07-query] |
| 10/11 | `gossip_queries_ex` | Gossip queries can include additional information | [BOLT #7][bolt07-query] |
| 12/13| `option_static_remotekey` | Static key for remote output | [BOLT #3](03-transactions.md) |
| 12/13 | `option_static_remotekey` | Static key for remote output | [BOLT #3](03-transactions.md)|
| 28/29 | `option_dual_fund` | Use v2 of channel open, enables dual funding | [BOLT #2](02-peer-protocol) |

This comment has been minimized.

Copy link
@ariard

ariard Jan 21, 2020

Contributor

Should be rebased for flat features ofc but what context should we assign, IN- (you should let old nodes routes through you even if you enforce dual funding opening with your local peers) ?

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 28, 2020

Author Collaborator

are we waiting on a spec change for 'N+/-', it's not currently listed in the features doc (but C+/- is)

This comment has been minimized.

Copy link
@t-bast

t-bast Jan 29, 2020

Collaborator

Yes, we need to discuss this during the next meeting, but we still need some clarifying on feature bits (potentially the N+/N- modifiers).


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.

This comment has been minimized.

Copy link
@ariard

ariard Jan 21, 2020

Contributor

Should we require ownership proof of input to avoid opener freely probing utxo set of accepter ? Though it may be tricky if it's a non-templated P2WSH, accepter need to solve the script...

Also, maybe introduce concept of a quarantine utxo set ? If input as been announced as part of a cancelled dual-funding, it should be used in priority for next ones, and you should avoid to mix it with lambda onchain transactions.

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 27, 2020

Author Collaborator

Vectors for revelation of your utxo set heavily depends on how much/how many inputs an accepter chooses to contribute to a channel, and will vary depending on the policy individual nodes set for their threshold and amount they've decided to contribute to a channel.

Currently, the c-lightning implementation mitigates this (slightly) by promoting any exposed utxos to be first eligible for spending. A repeated inquiry should expose the exact same utxos, until they're spent.

This comment has been minimized.

Copy link
@ariard

ariard Jan 29, 2020

Contributor

I'm fine with this for a first version. We may TLV ownership proof in a later one.

Maybe we should add privacy note somewhere on the risks, including some implementation advice like the one you're describing without this being mandatory.

- 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
- MAY omit this message

The sending node:
- MUST NOT send `funding_add_input` if it has already transmitted `funding_add_complete`

This comment has been minimized.

Copy link
@ariard

ariard Jan 21, 2020

Contributor

We don't write this common sense requirements in the current specs w.r.t funding_created which must come after open/accept sequence though obviously everyone encode this in their state machine ? IMO makes the spec unnecessarily verbose.

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 28, 2020

Author Collaborator

i'm not sure this is common sense -- it needs to be specified somewhere

- MUST send this after `accept_channel2` has been exchanged, but before `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.

This comment has been minimized.

Copy link
@ariard

ariard Jan 21, 2020

Contributor

You may check also that's a mature coinbase (but generally we may have issues with light-clients, unable to verify mempool rejection reasons and starting to RBF as crazy)

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 27, 2020

Author Collaborator

Oh good point. This isn't currently checked on funding transactions.

of zero. This will be used for change, or discarded if its value is
be below `dust_limit_satoshis`.

Change is calculated as the sum of the opener's `input_info`.`sats`

This comment has been minimized.

Copy link
@ariard

ariard Jan 21, 2020

Contributor

I'm not sure about the opener paying only the fees, it means if Alice funds with 1 input as opener but Bob puts max input 16, Bob utxo aggregation cost is externalized to Alice ? Sure you can hardcode or use a smart-fee-algo(tm) to reject but incentive-level it means accepter should seek this limit to free-ride ?

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 28, 2020

Author Collaborator

Yess, I've got a draft for how to re-distribute fees (and a tweak to this protocol) I'm about to send to the mailing list. :)

the `funding_txid`, instead of the `temporary_node_id`.


### The `funding_signed2` Message

This comment has been minimized.

Copy link
@ariard

ariard Jan 21, 2020

Contributor

Message name is a bit confusing, funding_signedv1 refers to accepter giving commitment tx signatures to fundee, here it refers to signatures exchange for the funding tx (even now wondering if a funding_signed distinct from commitment_signed wasn't a spec oversight..)

- 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.

This comment has been minimized.

Copy link
@ariard

ariard Jan 21, 2020

Contributor

IIRC I think that hurts BIP 125 rule 2, you can't add new inputs to rbf'ed transactions

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 28, 2020

Author Collaborator

This is a misinterpretation of rule 2; an "unconfirmed input" is a utxo that has not yet been confirmed in a block (mined).

  1. The replacement transaction may only include an unconfirmed input if that input was included in one of the original transactions. (An unconfirmed input spends an output from a currently-unconfirmed transaction.)

I think this is an oversight of the spec though; it should strictly exclude unconfirmed inputs (and thus disallow chaining), as they're difficult for the peer to verify.

This comment has been minimized.

Copy link
@ariard

ariard Jan 29, 2020

Contributor

You're right, thanks the rule is more liberal than I believed.

Yes sure the LN spec should disallow unconfirmed input to avoid chaining. That would be a real attack vector for zero-conf channels if people keep doing them. Maybe even ask for few confirmations to avoid messy 1-depth reorg edges cases.

RBF workflow, the RBF attempt MUST be abandoned.


### Acknowledging Replace-By-Fee `ack_rbf`

This comment has been minimized.

Copy link
@ariard

ariard Jan 21, 2020

Contributor

What problem the ack_rbf is handling ? Can't receiver of init_rbf directly replies with a commitment_signed ?

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 28, 2020

Author Collaborator

good point, i think it is infact superfluous.

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 28, 2020

Author Collaborator

update: in order to avoid reversing the order of commitment_signed exchange, you need to get at least one message back from the peer before you send them the commitment_signed message.

This comment has been minimized.

Copy link
@ariard

ariard Jan 29, 2020

Contributor

Can't the init_rbf sender joins a commitment_signed and interpret the lack of getting back a commitment_signed as a refusal (though harder for the state machine I guess) ?

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

This comment has been minimized.

Copy link
@ariard

ariard Jan 21, 2020

Contributor

What if rbf is refused by party ? Maybe we should recommend to always have an output available to rbf and avoid input being stuck in the mempool for 2 weeks if funding tx feerate isn't enough to confirm

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 27, 2020

Author Collaborator

I believe you mean 'output available to cpfp'. :)

Including an output for CPFP might be one strategy here, but there's no reason to make it standard in the spec, as its not required and if not a 'useful' output (i.e. a withdrawal or another closing output etc) contributes to utxo bloat.

Given that RBF is an option for opening transactions, it seems reasonable to not make CPFP mandatory here.

This comment has been minimized.

Copy link
@ariard

ariard Jan 29, 2020

Contributor

Concerning the UTXO bloat it's likely they add a change output so they may use it for CPFP.

I was thinking about the use-case of a zero-conf chans, for the party bearing the risk, adding a CPFP output and disabling RBF would be a lightweight mempool-enforced protection (though don't prevent malicious peer to directly send double-spend to miner..).

Sure no need to make it mandatory, it's up to the party if they want to be safe against stuck-in-the-mempool cases.

Copy link
Collaborator

t-bast left a comment

This is really nicely spec-ed, thanks @niftynei !

It's honestly a bit hard for me to find meaningful design comments without trying to implement this, at first glance it looks good and there are already many interesting discussions/comments.

I was wondering how the batching would work in terms of fees. If we have A <-> B <-> C, it seems to me that the naive version would have A pay all the fees, which is quite unfair (A shouldn't pay for a B <-> C channel). How do you think distributing the fee between all openers would work?


The receiving node:
- if the `witness_stack` length exceeds `max_witness_len`:
- MUST error.

This comment has been minimized.

Copy link
@t-bast

t-bast Jan 21, 2020

Collaborator

What does that mean exactly? Sending an error message to the other party and forgetting everything about this channel creation attempt?

I haven't thought about it deeply enough yet, but I feel that aborting during the funding flow may have some subtle edge cases. Are there some gotchas you ran into while implementing?

This comment has been minimized.

Copy link
@niftynei

niftynei Jan 28, 2020

Author Collaborator

Hmm. You've highlighted what I believe is the most subjective error case.

How the opener chooses to handle this is hard to enforce. At this point, they have all the information necessary to successfully broadcast the transaction (the accepter is the only peer that transmits their signatures). If they choose to accept the lower effective feerate anyway and broadcast the tx, there's nothing stopping them. What we're looking to accomplish is incentivize the peer (accepter) to provide an accurate witness length, so that the agreed upon feerate is accurate. The way I've chosen to incentivize this is by threatening that the opener will cancel the open on them.

So yes, the opener would send the peer and error message and, ideally, spend an input to the tx such that the opening transaction was definitively invalidated.

@niftynei niftynei force-pushed the niftynei:dual-funding branch from f150a15 to 45fbb33 Jan 24, 2020
Copy link
Collaborator Author

niftynei left a comment

Thanks for the most recent feedback @t-bast and @ariard. I just sent a message to the mailing list with a draft proposal for how to break out a more "universal collaborative transaction" protocol. It's a bit different than the protocol proposed here (namely in that it includes two removal messages), but should be largely compatible with the work already specified herein.

@niftynei niftynei force-pushed the niftynei:dual-funding branch from 45fbb33 to eb9bec1 Jan 28, 2020
@niftynei niftynei force-pushed the niftynei:dual-funding branch 2 times, most recently from ebfdc9e to 36561fc Jan 28, 2020
niftynei added 2 commits Dec 5, 2018
First draft of flow for v2 of channel establishment.
niftynei added 29 commits Apr 30, 2019
simplifies the funding and reserve calculations later if the
accepter knows at the outset how many inputs they'll be allowed
to contribute to the funding transaction
put `channel_reserve_satoshi` exchange into the `funding_compose`
message, so that it can reflect the full channel balance, and not
just the opener's funding.
the commitment_signed message must not contain any htlc's
during channel establishment.
since we now require the opener to 'pre-send' the total number
of inputs and outputs that they're going to be including in the
funding tx, if the number of actual inputs and outputs that they
send is less than this, we can fail the channel.

we do this because we base our input selection on the number of
inputs and outputs that they send. having a lower number means
that we might be in violation of the rule so we fail this requirement
also
fixes incorrect calculation of funding output's weight.
for v2 channel establishment we switch from the temporary channel_id
to the channel_id derived from the funding_txid after both
funding_compose messages have been exchanged, as at this point
both opener/accepter have the ability to derive the funding_txid
which is required for the channel_id.
On further consideration, the channel_id encapsulates all of the
necessary info to determine which funding transaction attempt
that the funding_locked message pertains to
We fix the total permitted contribution from the acceptor node
to 4, and remove it from the protocol.
Fix the reserve to always be 1% of the channel balance, or
the dust_limit, whichever is greater.

This reduces the complexity around calculating the
reserve balance.
Shorten the round trips required by only having the accepter
 send their sigs to the opener. This means only the opener
is able to compose the funding transaction completely, and that
only they are in control of publishing it, which is the same
as current implementations.
Break funding_compose into 3 messages, to allow for asynchronous
input and output construction.

This is done to enable multi-party funding transaction construction
Further limit the total inputs/outputs allowed from a peer
Reported-By: @darosior
Makes a non-malleable input more concise, and adds missing restriction
that input must be confirmed, i.e. mined.
@niftynei niftynei force-pushed the niftynei:dual-funding branch from 36561fc to 2e40838 Jan 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

5 participants
You can’t perform that action at this time.