Christian Decker [ARCHIVE] on Nostr: 📅 Original date posted:2018-05-01 📝 Original message: Excellent summary ...
📅 Original date posted:2018-05-01
📝 Original message:
Excellent summary ZmnSCPxj, I'll try to address the points inline (if
there is anything to add that is):
ZmnSCPxj <ZmnSCPxj at protonmail.com> writes:
> Hi Christian,
>
> Let me know if I have summarized the paper accurately below:
>
> 1. SIGHASH_NOINPUT removes all inputs of the transaction copy before
> signing/verifying.
It sets them to a known constant, in this case we just blank
them. Removing could entail more costly serialization depending on the
implementation. bitcoind serializes into a hash accumulator so it'd not
make a difference there, but others may do it differently.
> 2. SIGHASH_NOINPUT can be combined with SIGHASH_SINGLE. It is
> dangerous to combine it with SIGHASH_NONE (as this also deletes all
> outputs of the transaction copy, so the signature only commits to
> nLockTime) and possibly pointless to combine it with
> SIGHASH_ANYONECANPAY (which deletes other inputs, but since there are
> no inputs after SIGHASH_NOINPUT, there is nothing else to delete).
> The BIP only mentions combining it with SIGHASH_SINGLE, in any case.
`SIGHASH_SINGLE` really is only singled out (no pun intended) because it
is usefull for the fee feature that Rusty came up with. It's not our
intention to exclude other uses, but you're right, it's hard to come up
with a use-case for `SIGHASH_NOINPUT` in combination with
`SIGHASH_NONE` or `SIGHASH_ANYONECANPAY` :-)
In particular we don't want to exclude potential future sighash types,
but those will have to be dealt with when they come up.
> 3. We have these kinds transactions: (1) funding transaction paying
> out to an ordinary N-of-N multisig (confirmed onchain); (2) offchain
> trigger transaction spending a funding transaction and paying out to
> the "update transaction script"; (3) offchain update transaction
> spending a trigger or update transaction and paying out to the "update
> transaction script" (the same script template as in trigger
> transaction); (4) offchain settlement transaction spending a trigger
> or update transaction and paying out to the counterparties according
> to the final agreed distribution of funds. Update and settlement
> transactions are signed with SIGHASH_NOINPUT flags.
>
> 4. The update transaction script has two branches: a CSV-encumbered
> N-of-N "settlement" branch, and a CLTV-encumbered N-of-N "update"
> branch. Crucially, we use past Unix timestamps for the CLTV
> encumberance on the update. The CLTV-encumberance starts with a
> minimum time value on the trigger transaction, and increments by 1 for
> every update transaction.
Really any monotonically increasing sequence of increments will work,
but incrementing by 1 maximizes the number of updates we can perform,
yes.
> 5. The CLTV-encumberance ensures that if a past update transaction is
> confirmed, we can spend it using any later update transaction, since
> CLTV uses `stackTop <= nLockTime`. The actual `nLockTime` we use is a
> past Unix timestamp so they are not actually time-encumbered, but the
> `OP_CLTV` still ensures that any later update transaction can be used
> to spend from any earlier update transaction, but not vice versa.
> This is actually quite clever.
Correct, the only reason to use `nLocktime` here is that we need the
signature of the update transaction to commit to the state number, so we
can't put it in the script itself.
> 6. The pubkeys on the settlement branch of each update transaction
> are different, and are derived using any hierarchical derivation
> method (trivially we can simply use the CLTV-encumberance value as the
> derivation index). This ensures that each settlement transaction can
> only spend a particular update transaction. Or in other words: There
> is a one-to-one correspondence between update and settlement
> transaction, and a settlement transaction can only confirm if the
> corresponding update transaction can be confirmed deeply enough
> without having its output re-spent.
Other bindings are possible, e.g., compare the `nLocktime` again, but
binding through pubkeys minimizes the script size.
> 7. The pubkeys on the update branch are all the same in all update
> transactions. This lets any update transaction replace any other
> update transaction, as long as the CLTV-encumberance (which is used
> for ordering rather than actual absolute locktime) is respected;
> together they mean that any later update transaction can replace any
> earlier update transaction.
>
> 8. If an old update transaction is confirmed, the settlement
> transaction corresponding to it is still encumbered by CSV and cannot
> be confirmed immediately. During this time, a later update
> transaction can spend it and be confirmed. If that update transaction
> is still not the latest available, it can be further replaced with
> any, later transaction (since the CLTV-encumberance and the
> `nLockTime` increase in lockstep with each other) until the latest
> update transaction is confirmed.
Notice that the update transactions are actually paying their keep,
i.e., they have fees attached, so we think that participants will simply
jump to the latest state and not waste fees on things that have no
chance of getting them closer to getting an old state enforced.
> 9. When the latest update transaction gets confirmed, no other update
> transaction can successfully spend its "update" branch (as their
> `nLockTime` is less than the CLTV-encumberance on that branch). This
> lets the CSV-encumbered settlement transaction be confirmable after
> some blocks.
>
> 10. Update transactions pay no fees! Instead, for update
> transactions (but not settlement transactions) we additionally give
> SIGHASH_SINGLE: thus, no matter what transaction they end up in, the
> signatures for the update transaction will always be verified against
> only the update transaction output that pays out to the update
> transaction script. We join update transactions with a spend of some
> onchain UTXO we control, which pays for the fees of the joined the
> update transactions, and may have a second output that is the
> remainder of the fund after paying the fees.
>
> 11. Settlement transactions can carry contracts (in much the same way
> that Poon-Dryja commitment transactions); however contracts that
> contain absolute timelock components will be affected by the
> CSV-encumberance of the settlement transaction.
Exactly, the timeouts need to be chosen high enough in order to allow an
orderly resolution on-chain, should one party become uncooperative.
> ---
>
> Some pros and cons relative to Poon-Dryja (LN-penalty) channels:
>
> - Requires more transactions in the worst-case: trigger, update,
> settlement. Compare to Poon-Dryja: commitment, claim.
> Decker-Russell-Osuntokun channels can be trigger-settlement but only
> in the degenerate case where the channel was never updated (indeed for
> implementation simplicity we might rather prefer to make an initial
> update transaction at the start, instead of starting with a
> trigger-settlement).
Actually the trigger can also be replaced in the cooperative case,
meaning that the settlement in that case is just a single transaction,
identical to LN-penalty. It is true that we've split the unilateral
commitment from LN-penalty into two transactions, but we removed the
need for a claim transaction, since funds directly go to the recipient
and we have no our_unilateral/to_us or their_unilateral/to_them delay
that needs to be sweeped (technically also not necessary, but all
implementation do that if I'm not mistaken). Even if funds are not
sweeped, the UTXO state is larger due to the bigger script that our
simple outputs for the settlement.
> - Dropping unilaterally onchain requires the party doing the drop to
> have some onchain funds it controls completely, since update
> transactions do not pay fees by themselves. We cannot have an
> autopilot that puts all onchain funds on channels, we need to reserve
> some small amount for paying fees of unilateral closes.
That is true, and I think this falls into the same category as the
reserve funds in the LN-penalty mechanism, i.e., funds that are there
but can't be used. There may be a clever way to build a penalty on top
of eltoo and then combine the fees and the penalties. Then again, a
misbehaving participant risking their on-chain fees for an outdated
update transaction may be a sufficient deterrent.
> + The above is counterbalanced by the fact that we can easily adjust
> onchain fees for update transactions, unlike the case for Poon-Dryja
> commitment transactions which once signed cannot have fees updated.
>
> = The onchain reserve (for paying fees for unilaterally dropped
> channels) is roughly equivalent to the channel reserve under
> Poon-Dryja; such a channel reserve no longer exists under
> Decker-Russell-Osuntukun channels, but is replaced by the onchain
> fee-paying reserve. Possibly the fee-paying reserve here might be
> feasibly smaller than the channel reserve under Poon-Dryja.
The one downside that this has is that the channel participants have
very little control over the fees that a misbehaving node may get
punished with. As one endpoint I can no longer impose an arbitrary
minimum loss in case of breach.
> - The CSV-encumberance on settlement transactions, which are the ones
> which carry the contracts in the channel, affects all
> absolute-timelocked contracts transported on the channel. Compare to
> Poon-Dryja, where commitment transactions themselves are unencumbered
> by CSV, and we simply insert the revocation to spends of the contracts
> being transported (i.e. the reason why we have HTLC-success and
> HTLC-timeout transactions in BOLT spec).
True, but as I argued in another mail, this is a fixed offset, that is
in the same range as today's CLTV deltas for some nodes. So for the
network of today using eltoo is roughly equivalent of adding another hop
to our path :-)
> + Like invalidation trees, we can use N-party funds rather than just
> 2-party funds (channels). We can even use M-of-N, so if there is at
> least some amount of trust you have with a group of entities (family,
> close friends, conglomeration partners, ZmnSCPxj, politicians...) it
> would be possible to have funds that require say only a majority of
> its owners to be updated.
The trust really comes down to a tradeoff between group size and
liveness: the bigger the group and the more churn you have in that
group, the less reliable the system becomes. Loss of liveness means that
the funds in the contract become unavailable for a know period of time.
📝 Original message:
Excellent summary ZmnSCPxj, I'll try to address the points inline (if
there is anything to add that is):
ZmnSCPxj <ZmnSCPxj at protonmail.com> writes:
> Hi Christian,
>
> Let me know if I have summarized the paper accurately below:
>
> 1. SIGHASH_NOINPUT removes all inputs of the transaction copy before
> signing/verifying.
It sets them to a known constant, in this case we just blank
them. Removing could entail more costly serialization depending on the
implementation. bitcoind serializes into a hash accumulator so it'd not
make a difference there, but others may do it differently.
> 2. SIGHASH_NOINPUT can be combined with SIGHASH_SINGLE. It is
> dangerous to combine it with SIGHASH_NONE (as this also deletes all
> outputs of the transaction copy, so the signature only commits to
> nLockTime) and possibly pointless to combine it with
> SIGHASH_ANYONECANPAY (which deletes other inputs, but since there are
> no inputs after SIGHASH_NOINPUT, there is nothing else to delete).
> The BIP only mentions combining it with SIGHASH_SINGLE, in any case.
`SIGHASH_SINGLE` really is only singled out (no pun intended) because it
is usefull for the fee feature that Rusty came up with. It's not our
intention to exclude other uses, but you're right, it's hard to come up
with a use-case for `SIGHASH_NOINPUT` in combination with
`SIGHASH_NONE` or `SIGHASH_ANYONECANPAY` :-)
In particular we don't want to exclude potential future sighash types,
but those will have to be dealt with when they come up.
> 3. We have these kinds transactions: (1) funding transaction paying
> out to an ordinary N-of-N multisig (confirmed onchain); (2) offchain
> trigger transaction spending a funding transaction and paying out to
> the "update transaction script"; (3) offchain update transaction
> spending a trigger or update transaction and paying out to the "update
> transaction script" (the same script template as in trigger
> transaction); (4) offchain settlement transaction spending a trigger
> or update transaction and paying out to the counterparties according
> to the final agreed distribution of funds. Update and settlement
> transactions are signed with SIGHASH_NOINPUT flags.
>
> 4. The update transaction script has two branches: a CSV-encumbered
> N-of-N "settlement" branch, and a CLTV-encumbered N-of-N "update"
> branch. Crucially, we use past Unix timestamps for the CLTV
> encumberance on the update. The CLTV-encumberance starts with a
> minimum time value on the trigger transaction, and increments by 1 for
> every update transaction.
Really any monotonically increasing sequence of increments will work,
but incrementing by 1 maximizes the number of updates we can perform,
yes.
> 5. The CLTV-encumberance ensures that if a past update transaction is
> confirmed, we can spend it using any later update transaction, since
> CLTV uses `stackTop <= nLockTime`. The actual `nLockTime` we use is a
> past Unix timestamp so they are not actually time-encumbered, but the
> `OP_CLTV` still ensures that any later update transaction can be used
> to spend from any earlier update transaction, but not vice versa.
> This is actually quite clever.
Correct, the only reason to use `nLocktime` here is that we need the
signature of the update transaction to commit to the state number, so we
can't put it in the script itself.
> 6. The pubkeys on the settlement branch of each update transaction
> are different, and are derived using any hierarchical derivation
> method (trivially we can simply use the CLTV-encumberance value as the
> derivation index). This ensures that each settlement transaction can
> only spend a particular update transaction. Or in other words: There
> is a one-to-one correspondence between update and settlement
> transaction, and a settlement transaction can only confirm if the
> corresponding update transaction can be confirmed deeply enough
> without having its output re-spent.
Other bindings are possible, e.g., compare the `nLocktime` again, but
binding through pubkeys minimizes the script size.
> 7. The pubkeys on the update branch are all the same in all update
> transactions. This lets any update transaction replace any other
> update transaction, as long as the CLTV-encumberance (which is used
> for ordering rather than actual absolute locktime) is respected;
> together they mean that any later update transaction can replace any
> earlier update transaction.
>
> 8. If an old update transaction is confirmed, the settlement
> transaction corresponding to it is still encumbered by CSV and cannot
> be confirmed immediately. During this time, a later update
> transaction can spend it and be confirmed. If that update transaction
> is still not the latest available, it can be further replaced with
> any, later transaction (since the CLTV-encumberance and the
> `nLockTime` increase in lockstep with each other) until the latest
> update transaction is confirmed.
Notice that the update transactions are actually paying their keep,
i.e., they have fees attached, so we think that participants will simply
jump to the latest state and not waste fees on things that have no
chance of getting them closer to getting an old state enforced.
> 9. When the latest update transaction gets confirmed, no other update
> transaction can successfully spend its "update" branch (as their
> `nLockTime` is less than the CLTV-encumberance on that branch). This
> lets the CSV-encumbered settlement transaction be confirmable after
> some blocks.
>
> 10. Update transactions pay no fees! Instead, for update
> transactions (but not settlement transactions) we additionally give
> SIGHASH_SINGLE: thus, no matter what transaction they end up in, the
> signatures for the update transaction will always be verified against
> only the update transaction output that pays out to the update
> transaction script. We join update transactions with a spend of some
> onchain UTXO we control, which pays for the fees of the joined the
> update transactions, and may have a second output that is the
> remainder of the fund after paying the fees.
>
> 11. Settlement transactions can carry contracts (in much the same way
> that Poon-Dryja commitment transactions); however contracts that
> contain absolute timelock components will be affected by the
> CSV-encumberance of the settlement transaction.
Exactly, the timeouts need to be chosen high enough in order to allow an
orderly resolution on-chain, should one party become uncooperative.
> ---
>
> Some pros and cons relative to Poon-Dryja (LN-penalty) channels:
>
> - Requires more transactions in the worst-case: trigger, update,
> settlement. Compare to Poon-Dryja: commitment, claim.
> Decker-Russell-Osuntokun channels can be trigger-settlement but only
> in the degenerate case where the channel was never updated (indeed for
> implementation simplicity we might rather prefer to make an initial
> update transaction at the start, instead of starting with a
> trigger-settlement).
Actually the trigger can also be replaced in the cooperative case,
meaning that the settlement in that case is just a single transaction,
identical to LN-penalty. It is true that we've split the unilateral
commitment from LN-penalty into two transactions, but we removed the
need for a claim transaction, since funds directly go to the recipient
and we have no our_unilateral/to_us or their_unilateral/to_them delay
that needs to be sweeped (technically also not necessary, but all
implementation do that if I'm not mistaken). Even if funds are not
sweeped, the UTXO state is larger due to the bigger script that our
simple outputs for the settlement.
> - Dropping unilaterally onchain requires the party doing the drop to
> have some onchain funds it controls completely, since update
> transactions do not pay fees by themselves. We cannot have an
> autopilot that puts all onchain funds on channels, we need to reserve
> some small amount for paying fees of unilateral closes.
That is true, and I think this falls into the same category as the
reserve funds in the LN-penalty mechanism, i.e., funds that are there
but can't be used. There may be a clever way to build a penalty on top
of eltoo and then combine the fees and the penalties. Then again, a
misbehaving participant risking their on-chain fees for an outdated
update transaction may be a sufficient deterrent.
> + The above is counterbalanced by the fact that we can easily adjust
> onchain fees for update transactions, unlike the case for Poon-Dryja
> commitment transactions which once signed cannot have fees updated.
>
> = The onchain reserve (for paying fees for unilaterally dropped
> channels) is roughly equivalent to the channel reserve under
> Poon-Dryja; such a channel reserve no longer exists under
> Decker-Russell-Osuntukun channels, but is replaced by the onchain
> fee-paying reserve. Possibly the fee-paying reserve here might be
> feasibly smaller than the channel reserve under Poon-Dryja.
The one downside that this has is that the channel participants have
very little control over the fees that a misbehaving node may get
punished with. As one endpoint I can no longer impose an arbitrary
minimum loss in case of breach.
> - The CSV-encumberance on settlement transactions, which are the ones
> which carry the contracts in the channel, affects all
> absolute-timelocked contracts transported on the channel. Compare to
> Poon-Dryja, where commitment transactions themselves are unencumbered
> by CSV, and we simply insert the revocation to spends of the contracts
> being transported (i.e. the reason why we have HTLC-success and
> HTLC-timeout transactions in BOLT spec).
True, but as I argued in another mail, this is a fixed offset, that is
in the same range as today's CLTV deltas for some nodes. So for the
network of today using eltoo is roughly equivalent of adding another hop
to our path :-)
> + Like invalidation trees, we can use N-party funds rather than just
> 2-party funds (channels). We can even use M-of-N, so if there is at
> least some amount of trust you have with a group of entities (family,
> close friends, conglomeration partners, ZmnSCPxj, politicians...) it
> would be possible to have funds that require say only a majority of
> its owners to be updated.
The trust really comes down to a tradeoff between group size and
liveness: the bigger the group and the more churn you have in that
group, the less reliable the system becomes. Loss of liveness means that
the funds in the contract become unavailable for a know period of time.