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