Rusty Russell [ARCHIVE] on Nostr: 📅 Original date posted:2018-10-12 📝 Original message: Christian Decker ...
📅 Original date posted:2018-10-12
📝 Original message:
Christian Decker <decker.christian at gmail.com> writes:
> On Thu, Oct 11, 2018 at 3:40 AM Rusty Russell <rusty at rustcorp.com.au> wrote:
>
>> > * Once we have enough confirmations we merge the channels (either
>> > automatically or with the next channel update). A new commitment tx is
>> > being created which now spends each output of each of the two funding tx
>> > and assigns the channel balance to the channel partners accordingly to
>> the
>> > two independent channels. The old commitment txs are being invalidated.
>> > * The disadvantage is that while splicing is not completed and if the
>> > funder of the splicing tx is trying to publish an old commitment tx the
>> > node will only be punished by sending all the funds of the first funding
>> tx
>> > to the partner as the special commitment tx of the 2nd output has no
>> newer
>> > state yet.
>>
>> Yes, this is the alternative method; produce a parallel funding tx
>> (which only needs to support a single revocation, or could even be done
>> by a long timeout) and then join them when it reaches the agreed depth.
>>
>> It has some elegance; particularly because one side doesn't have to do
>> any validation or store anything until it's about to splice in. You get
>> asked for a key and signature, you produce a new one, and sign whatever
>> tx they want. They hand you back the tx and the key you used once it's
>> buried far enough, and you check the tx is indeed buried and the output
>> is the script you're expecting, then you flip the commitment tx.
>>
>> But I chose chose not to do this because every transaction commitment
>> forever will require 2 signatures, and doesn't allow us to forget old
>> revocation information.
>>
>> And it has some strange side-effects: onchain this looks like two
>> channels; do we gossip about both? We have to figure the limit on
>> splice-in to make sure the commitment tx stays under 400kSipa.
>>
>
> This is a lot closer to my original proposal for splicing, and I
> still like it a lot more since the transition from old to new
> channel is bascially atomic (not having to update state on both
> pre-splice and post-splice version). The new funds will remain
> unavailable for the same time, and since we allow only one
> concurrent splice in your proposal we don't even lose any
> additional time regarding the splice-outs.
>
> So pulling the splice_add_input and splice_add_output up to
> signal the intent of adding funds to a splice. Splice_all_added
> is then used to start moving the funds to a pre-allocated 2-of-2
> output where the funds can mature. Once the funds are
> matured (e.g., 6 confirmations) we can start the transition: both
> parties claim the funding output, and the pre-allocated funds, to
> create a new funding tx which is immediately broadcast, and we
> flip over to the new channel state. No need to keep parallel
> state and then disambiguating which one it was.
If we're going to do side splice-in like this, I would use a very
different protocol: the reason for this protocol was to treat splice-in
and splice-out the same, and inline splice-in requires wait time. Since
splice-out doesn't, we don't need this at all.
It would look much more like:
1. Prepare any output with script of specific form. eg:
OP_DEPTH 3 OP_EQUAL OP_IF
<funding_pubkey1> <funding_pubkey2> OP_CHECKMULTISIG
OP_ELSE
<blockheight> OP_CHECKLOCKTIMEVERIFY OP_DROP
<myrescue_pubkey> OP_CHECKSIG
OP_ENDIF
1. type: 40 (`splice_in`) (`option_splice`)
2. data:
* [`32`:`channel_id`]
* [`8`: `satoshis`]
* [`32`: `txid`]
* [`4`: `txoutnum`]
* [`4`: `blockheight`]
* [`33`: `myrescue_pubkey`]
1. type: 137 (`update_splice_in_accept`) (`option_splice`)
data:
* [`32`:`channel_id`]
* [`32`: `txid`]
* [`4`: `txoutnum`]
1. type: 138 (`update_splice_in_reject`) (`option_splice`)
data:
* [`32`:`channel_id`]
* [`32`: `txid`]
* [`2`:`len`]
* [`len`:`errorstr`]
The recipient of `splice_in` checks that it's happy with the
`blockheight` (far enough in future). Once it sees the tx referred to
buried to its own `minimum_depth`, it checks output is what they
claimed, then sends `update_splice_in_accept`; it's followed up
`commitment_signed` like normal, but from this point onwards, all
commitment txs signatures have one extra sig.
Similarly, splice-out:
1. type: 139 (`update_splice_out`) (`option_splice`)
* [`32`:`channel_id`]
* [`8`: `satoshis`]
* [`2`: `scriptlen`]
* [`scriptlen`: `outscript`]
The recipient checks that the output script is standard, and the amount
can be afforded by the other side. From then on, each commitment tx has
a new output.
Note this doesn't put the splice out on the blockchain!
1. type: 140 (`propose_reopen`) (`option_splice`)
* [`32`:`channel_id`]
* [`4`:`feerate_per_kw`]
* [`33`:`funding_pubkey`]
This is initiates a mutually-agreed broadcast of the current state: all
inputs (original and spliced), all spliced outputs, and a funding-style
2x2 which has all the remaining funds. Call this a 'reopen tx'.
This must be done with no outstanding commitments, like closing tx
negotiation, and it's a back-and-forth until both sides agree on
feerate. Then you send:
1. type: 141 (`reopen_accept`) (`option_splice`)
* [`32`:`channel_id`]
* [`4`:`feerate_per_kw`]
* [`64`: `new_commitment_sig`]
Once you've received and sent this, you're ready to sign the reopen tx:
1. type: 142 (`reopen`) (`option_splice`)
* [`32`:`channel_id`]
* [`64`: `reopen_commitment_sig`]
We need similar 'what happens on reconnect at various points' logic to
the previous one <handwave>.
Once you've sent and received the `reopen`, you can broadcast the reopen
tx at will and start updating again. If we recommend that public
channels reuse their old `funding_pubkey` then that means that we should
also have gossip continuity for upgraded nodes, and don't need the
previous channel_update hack.
We could add a new `reopen_locked` message which indicates that both
sides are happy with the reopen depth, if we don't want to allow reopens
back-to-back?
> This is one of the cases where a simpler solution (relatively
> speaking ^^) is to be preferred imho, allowing for future
> iterations.
Unless we can have both :)
Cheers,
Rusty.
📝 Original message:
Christian Decker <decker.christian at gmail.com> writes:
> On Thu, Oct 11, 2018 at 3:40 AM Rusty Russell <rusty at rustcorp.com.au> wrote:
>
>> > * Once we have enough confirmations we merge the channels (either
>> > automatically or with the next channel update). A new commitment tx is
>> > being created which now spends each output of each of the two funding tx
>> > and assigns the channel balance to the channel partners accordingly to
>> the
>> > two independent channels. The old commitment txs are being invalidated.
>> > * The disadvantage is that while splicing is not completed and if the
>> > funder of the splicing tx is trying to publish an old commitment tx the
>> > node will only be punished by sending all the funds of the first funding
>> tx
>> > to the partner as the special commitment tx of the 2nd output has no
>> newer
>> > state yet.
>>
>> Yes, this is the alternative method; produce a parallel funding tx
>> (which only needs to support a single revocation, or could even be done
>> by a long timeout) and then join them when it reaches the agreed depth.
>>
>> It has some elegance; particularly because one side doesn't have to do
>> any validation or store anything until it's about to splice in. You get
>> asked for a key and signature, you produce a new one, and sign whatever
>> tx they want. They hand you back the tx and the key you used once it's
>> buried far enough, and you check the tx is indeed buried and the output
>> is the script you're expecting, then you flip the commitment tx.
>>
>> But I chose chose not to do this because every transaction commitment
>> forever will require 2 signatures, and doesn't allow us to forget old
>> revocation information.
>>
>> And it has some strange side-effects: onchain this looks like two
>> channels; do we gossip about both? We have to figure the limit on
>> splice-in to make sure the commitment tx stays under 400kSipa.
>>
>
> This is a lot closer to my original proposal for splicing, and I
> still like it a lot more since the transition from old to new
> channel is bascially atomic (not having to update state on both
> pre-splice and post-splice version). The new funds will remain
> unavailable for the same time, and since we allow only one
> concurrent splice in your proposal we don't even lose any
> additional time regarding the splice-outs.
>
> So pulling the splice_add_input and splice_add_output up to
> signal the intent of adding funds to a splice. Splice_all_added
> is then used to start moving the funds to a pre-allocated 2-of-2
> output where the funds can mature. Once the funds are
> matured (e.g., 6 confirmations) we can start the transition: both
> parties claim the funding output, and the pre-allocated funds, to
> create a new funding tx which is immediately broadcast, and we
> flip over to the new channel state. No need to keep parallel
> state and then disambiguating which one it was.
If we're going to do side splice-in like this, I would use a very
different protocol: the reason for this protocol was to treat splice-in
and splice-out the same, and inline splice-in requires wait time. Since
splice-out doesn't, we don't need this at all.
It would look much more like:
1. Prepare any output with script of specific form. eg:
OP_DEPTH 3 OP_EQUAL OP_IF
<funding_pubkey1> <funding_pubkey2> OP_CHECKMULTISIG
OP_ELSE
<blockheight> OP_CHECKLOCKTIMEVERIFY OP_DROP
<myrescue_pubkey> OP_CHECKSIG
OP_ENDIF
1. type: 40 (`splice_in`) (`option_splice`)
2. data:
* [`32`:`channel_id`]
* [`8`: `satoshis`]
* [`32`: `txid`]
* [`4`: `txoutnum`]
* [`4`: `blockheight`]
* [`33`: `myrescue_pubkey`]
1. type: 137 (`update_splice_in_accept`) (`option_splice`)
data:
* [`32`:`channel_id`]
* [`32`: `txid`]
* [`4`: `txoutnum`]
1. type: 138 (`update_splice_in_reject`) (`option_splice`)
data:
* [`32`:`channel_id`]
* [`32`: `txid`]
* [`2`:`len`]
* [`len`:`errorstr`]
The recipient of `splice_in` checks that it's happy with the
`blockheight` (far enough in future). Once it sees the tx referred to
buried to its own `minimum_depth`, it checks output is what they
claimed, then sends `update_splice_in_accept`; it's followed up
`commitment_signed` like normal, but from this point onwards, all
commitment txs signatures have one extra sig.
Similarly, splice-out:
1. type: 139 (`update_splice_out`) (`option_splice`)
* [`32`:`channel_id`]
* [`8`: `satoshis`]
* [`2`: `scriptlen`]
* [`scriptlen`: `outscript`]
The recipient checks that the output script is standard, and the amount
can be afforded by the other side. From then on, each commitment tx has
a new output.
Note this doesn't put the splice out on the blockchain!
1. type: 140 (`propose_reopen`) (`option_splice`)
* [`32`:`channel_id`]
* [`4`:`feerate_per_kw`]
* [`33`:`funding_pubkey`]
This is initiates a mutually-agreed broadcast of the current state: all
inputs (original and spliced), all spliced outputs, and a funding-style
2x2 which has all the remaining funds. Call this a 'reopen tx'.
This must be done with no outstanding commitments, like closing tx
negotiation, and it's a back-and-forth until both sides agree on
feerate. Then you send:
1. type: 141 (`reopen_accept`) (`option_splice`)
* [`32`:`channel_id`]
* [`4`:`feerate_per_kw`]
* [`64`: `new_commitment_sig`]
Once you've received and sent this, you're ready to sign the reopen tx:
1. type: 142 (`reopen`) (`option_splice`)
* [`32`:`channel_id`]
* [`64`: `reopen_commitment_sig`]
We need similar 'what happens on reconnect at various points' logic to
the previous one <handwave>.
Once you've sent and received the `reopen`, you can broadcast the reopen
tx at will and start updating again. If we recommend that public
channels reuse their old `funding_pubkey` then that means that we should
also have gossip continuity for upgraded nodes, and don't need the
previous channel_update hack.
We could add a new `reopen_locked` message which indicates that both
sides are happy with the reopen depth, if we don't want to allow reopens
back-to-back?
> This is one of the cases where a simpler solution (relatively
> speaking ^^) is to be preferred imho, allowing for future
> iterations.
Unless we can have both :)
Cheers,
Rusty.