Christian Decker [ARCHIVE] on Nostr: 📅 Original date posted:2018-08-01 📝 Original message: Thanks for the excellent ...
📅 Original date posted:2018-08-01
📝 Original message:
Thanks for the excellent writeup ZmnSCPxj, I just have a minor issue
with your characterization that LN-penalty is to be preferred.
My issue is with the fact that CLTV-branches and nLocktimed spending
transactions also need to be guarded with a further `OP_CSV` condition,
since they may leak on-chain, and be immediately valid. This is the
reason why we introduced the two stage HTLC resolution, with the first
stage acting as the `OP_CSV` guard, and keeping the second stage clean.
I think therefore the construction of the contract ought to be this:
[/*arbitrary*/, A && B] -> [signA signB, (revoke) || (CSV && A && B && C)] -> [signA signB witnessCbyA, revoke || A] /* held by A */
[/*arbitrary*/, A && B] -> [signA signB, (revoke) || (CSV && A && B && C)] -> [signA signB witnessCbyB, revoke || B] /* held by B */
Namely the CSV belongs in the output script, not the input script (which
is under the control of the spending party). Notice that I might have
misgroked your syntax :-) If C now contains a CLTV-branch whose timeout
expires before we attempt the on-chain mediation, suddenly both branches
become valid and we have a race.
Take this for example:
```
OP_IF
x OP_CLTV
<checksigs>
OP_ELSE
<checksigs>
OP_END
```
If we wait until block x was found, we attempt to cheat by publishing
this state, and suddenly both prepared reaction transactions are valid,
resulting in a race. This is simply due to the fact that transactions
can leak. To fix this we'd have to encumber the OP_IF branch with an
additional CSV. So it's not really like we can just add an OR-clause to
an arbitrary contract and we're safe, we actually have to weave it into
the logic, or create a second stage that just disambiguates the cheat
and the non-cheat unilateral case.
With eltoo this sort of weaving falls away, since we guarantee that the
old state can never leak on-chain. If we squint at it we can see that
we have effectively pushed down the second stage into the on-chain state
resolution, allowing us to keep the contracts clean.
Cheers,
Christian
ZmnSCPxj via Lightning-dev <lightning-dev at lists.linuxfoundation.org>
writes:
> Good morning list,
>
> Recently, somebody on the IRC channel, asked regarding smart contracts
> being transported via LN.
>
> Indeed, this is theoretically possible, provided the "smart contract"
> is implementable as a Bitcoin SCRIPT.
>
> Afterwards, I opined that, for transportation of *arbitrary*
> contracts, Poon-Dryja is superior to either Decker-Wattenhofer or
> Decker-Osuntokun-Russell.
>
> So, first, my other opinions:
>
> 1. The only smart contract you really want to transport is HTLC (or
> equivalent in scriptless script). There really is no point in
> transporting any other contract on LN. HTLCs can even be used to
> implement (nontransferable) swap options, and can be composed (at the
> cost of increasing CLTV limits on backoff) to create multi-step swaps.
>
> 2. Decker-Osuntokun-Russell "eltoo" is far superior to Poon-Dryja
> "LN-penalty" in everything else, except transportation of *arbitrary*
> contracts.
>
> Now, ultimately any Bitcoin SCRIPT may be expressed as a Boolean
> computation whether or not the contract has been fulfilled by the
> transaction that attempts to claim it.
>
> So I introduce, an arbitrary contract C, ostensibly to be transported
> over LN.
>
> And I introduce our transactions, as so: [scriptSig, redeemScript] ->
> redeeming transaction
>
> To transport C over a channel between nodes A and B, under Poon-Dryja,
> we first have a channel anchoring transaction onchain:
>
> [/*arbitrary*/, A && B] ->
>
> Now suppose the entire output is to be put into a contract C. Under
> Poon-Dryja, we create the below symmetrical series of transactions,
> with only the anchoring transaction existing onchain:
>
> [/*arbitrary*/, A && B] -> [signA signB, (revoke) || (A && B && C)] ->
> [signA signB witnessCbyA, revoke || (A && CSV)] /* held by A */
>
> [/*arbitrary*/, A && B] -> [signA signB, (revoke) || (A && B && C)] ->
> [signA signB witnessCbyB, revoke || (B && CSV)] /* held by B */
>
> Where (revoke) is the revocation key, whose derivation requires both A
> and B, and whose half is kept secret by the A (resp. B) until they
> both agree to revoke the old state.
>
> Of note is that the only additional condition added to C is (A && B),
> which makes sense since the contract is between nodes A and B (and
> which would be implicitly required by the funding transaction anyway).
> The (revoke) || does not affect the enforcement of C if the revocation
> key is not yet revealed; once the revocation key is revealed, that
> revokes the entire sequence of transactions (which is why (revoke) ||
> appears in both the second and third transactions above). In
> particular, the CSV-encumberance does not affect claiming of C; it
> encumbers the claiming of the money, but does not interact with C
> itself. Thus, any CLTV conditions in C will not be interefered with
> by the CSV-encumberance on the *next* transaction.
>
> Note also that only signA and signB for the final transaction needs to
> be shared; the witnessC can presumably be fulfilled by each side
> themselves automatically.
>
> On the other hand, under Decker-Osuntokun-Russell eltoo, the
> transaction series is:
>
> [/*arbitrary*/, A && B] -> [signA signB, (CSV && A && B) || (CLTV && A
> && B)] -> [nSequence signA signB, C]
>
> Now the above is massively simpler with no additional SCRIPT that
> needs to be written, around the transported contract C --- but the CSV
> in the second transaction, is now potentially interfering with the
> operation of the contract C, as the final transaction cannot be
> enforced onchain until the CSV has been satisfied. This is in
> contrast with the Poon-Dryja case, where the contract C appears
> immediately on the second transaction in the sequence, and can be
> enforced, as soon as it appears onchain.
>
> (In eltoo, the (CTLV && A && B) branch of the intermediate contract is
> the "update" path, and the CLTV required is always a past Unix Epoch
> time, so this CLTV cannot interfere with the contract C).
>
> The above consideration, is why I suppose that, *for arbitrary
> contracts*, Poon-Dryja is superior.
>
> Simply, the conclusion is that Decker-Osuntokun-Russell channels
> require a CSV that may interfere with the contract C if C is
> time-sensitive (i.e. has a CLTV or CSV itself), whereas Poon-Dryja
> requires CSV only for revocability, and the CSV cannot prevent the
> enforcement of time-sensitive C.
>
> Indeed, as I pointed out, even when transporting HTLCs,
> Decker-Osuntokun-Russell will require consideration of the CSV on top
> of the CLTV-deltas imposed by intermediary nodes, with weights
> complicated by the fact that CLTV-deltas are summed together but the
> highest CSV is added to the CLTV total, which does not mix well with
> typical route-finding algorithms (most of which assume a simple
> summing of costs, which CLTV-deltas use but CSVs on
> Decker-Osuntokun-Russell do not since highest is used).
>
> In almost all other ways, Poon-Dryja is inferior:
>
> 1. Does not use nLockTime in a sufficiently clever way. 2.
> Dangerous "toxic waste" (old revoked transactions) which (1) you
> should not recover from your backups and (2) you should not let your
> worst enemy find, because they can publish those onchain and make you
> LOSE MONEY. 3. Symmetrical chains of transactions, different for
> both parties, instead of a single chain.
>
> In addition, arbitrary contracts are not really particularly useful.
> HTLCs seem to me an important building block for digital value
> transfers, and they (and their equivalents under scriptless) are
> sufficient for most practical transfers. Thus, moving forward,
> Decker-Osuntokun-Russell remains a superior technology over
> Poon-Dryja.
>
> Regards, ZmnSCPxj _______________________________________________
> Lightning-dev mailing list Lightning-dev at lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
📝 Original message:
Thanks for the excellent writeup ZmnSCPxj, I just have a minor issue
with your characterization that LN-penalty is to be preferred.
My issue is with the fact that CLTV-branches and nLocktimed spending
transactions also need to be guarded with a further `OP_CSV` condition,
since they may leak on-chain, and be immediately valid. This is the
reason why we introduced the two stage HTLC resolution, with the first
stage acting as the `OP_CSV` guard, and keeping the second stage clean.
I think therefore the construction of the contract ought to be this:
[/*arbitrary*/, A && B] -> [signA signB, (revoke) || (CSV && A && B && C)] -> [signA signB witnessCbyA, revoke || A] /* held by A */
[/*arbitrary*/, A && B] -> [signA signB, (revoke) || (CSV && A && B && C)] -> [signA signB witnessCbyB, revoke || B] /* held by B */
Namely the CSV belongs in the output script, not the input script (which
is under the control of the spending party). Notice that I might have
misgroked your syntax :-) If C now contains a CLTV-branch whose timeout
expires before we attempt the on-chain mediation, suddenly both branches
become valid and we have a race.
Take this for example:
```
OP_IF
x OP_CLTV
<checksigs>
OP_ELSE
<checksigs>
OP_END
```
If we wait until block x was found, we attempt to cheat by publishing
this state, and suddenly both prepared reaction transactions are valid,
resulting in a race. This is simply due to the fact that transactions
can leak. To fix this we'd have to encumber the OP_IF branch with an
additional CSV. So it's not really like we can just add an OR-clause to
an arbitrary contract and we're safe, we actually have to weave it into
the logic, or create a second stage that just disambiguates the cheat
and the non-cheat unilateral case.
With eltoo this sort of weaving falls away, since we guarantee that the
old state can never leak on-chain. If we squint at it we can see that
we have effectively pushed down the second stage into the on-chain state
resolution, allowing us to keep the contracts clean.
Cheers,
Christian
ZmnSCPxj via Lightning-dev <lightning-dev at lists.linuxfoundation.org>
writes:
> Good morning list,
>
> Recently, somebody on the IRC channel, asked regarding smart contracts
> being transported via LN.
>
> Indeed, this is theoretically possible, provided the "smart contract"
> is implementable as a Bitcoin SCRIPT.
>
> Afterwards, I opined that, for transportation of *arbitrary*
> contracts, Poon-Dryja is superior to either Decker-Wattenhofer or
> Decker-Osuntokun-Russell.
>
> So, first, my other opinions:
>
> 1. The only smart contract you really want to transport is HTLC (or
> equivalent in scriptless script). There really is no point in
> transporting any other contract on LN. HTLCs can even be used to
> implement (nontransferable) swap options, and can be composed (at the
> cost of increasing CLTV limits on backoff) to create multi-step swaps.
>
> 2. Decker-Osuntokun-Russell "eltoo" is far superior to Poon-Dryja
> "LN-penalty" in everything else, except transportation of *arbitrary*
> contracts.
>
> Now, ultimately any Bitcoin SCRIPT may be expressed as a Boolean
> computation whether or not the contract has been fulfilled by the
> transaction that attempts to claim it.
>
> So I introduce, an arbitrary contract C, ostensibly to be transported
> over LN.
>
> And I introduce our transactions, as so: [scriptSig, redeemScript] ->
> redeeming transaction
>
> To transport C over a channel between nodes A and B, under Poon-Dryja,
> we first have a channel anchoring transaction onchain:
>
> [/*arbitrary*/, A && B] ->
>
> Now suppose the entire output is to be put into a contract C. Under
> Poon-Dryja, we create the below symmetrical series of transactions,
> with only the anchoring transaction existing onchain:
>
> [/*arbitrary*/, A && B] -> [signA signB, (revoke) || (A && B && C)] ->
> [signA signB witnessCbyA, revoke || (A && CSV)] /* held by A */
>
> [/*arbitrary*/, A && B] -> [signA signB, (revoke) || (A && B && C)] ->
> [signA signB witnessCbyB, revoke || (B && CSV)] /* held by B */
>
> Where (revoke) is the revocation key, whose derivation requires both A
> and B, and whose half is kept secret by the A (resp. B) until they
> both agree to revoke the old state.
>
> Of note is that the only additional condition added to C is (A && B),
> which makes sense since the contract is between nodes A and B (and
> which would be implicitly required by the funding transaction anyway).
> The (revoke) || does not affect the enforcement of C if the revocation
> key is not yet revealed; once the revocation key is revealed, that
> revokes the entire sequence of transactions (which is why (revoke) ||
> appears in both the second and third transactions above). In
> particular, the CSV-encumberance does not affect claiming of C; it
> encumbers the claiming of the money, but does not interact with C
> itself. Thus, any CLTV conditions in C will not be interefered with
> by the CSV-encumberance on the *next* transaction.
>
> Note also that only signA and signB for the final transaction needs to
> be shared; the witnessC can presumably be fulfilled by each side
> themselves automatically.
>
> On the other hand, under Decker-Osuntokun-Russell eltoo, the
> transaction series is:
>
> [/*arbitrary*/, A && B] -> [signA signB, (CSV && A && B) || (CLTV && A
> && B)] -> [nSequence signA signB, C]
>
> Now the above is massively simpler with no additional SCRIPT that
> needs to be written, around the transported contract C --- but the CSV
> in the second transaction, is now potentially interfering with the
> operation of the contract C, as the final transaction cannot be
> enforced onchain until the CSV has been satisfied. This is in
> contrast with the Poon-Dryja case, where the contract C appears
> immediately on the second transaction in the sequence, and can be
> enforced, as soon as it appears onchain.
>
> (In eltoo, the (CTLV && A && B) branch of the intermediate contract is
> the "update" path, and the CLTV required is always a past Unix Epoch
> time, so this CLTV cannot interfere with the contract C).
>
> The above consideration, is why I suppose that, *for arbitrary
> contracts*, Poon-Dryja is superior.
>
> Simply, the conclusion is that Decker-Osuntokun-Russell channels
> require a CSV that may interfere with the contract C if C is
> time-sensitive (i.e. has a CLTV or CSV itself), whereas Poon-Dryja
> requires CSV only for revocability, and the CSV cannot prevent the
> enforcement of time-sensitive C.
>
> Indeed, as I pointed out, even when transporting HTLCs,
> Decker-Osuntokun-Russell will require consideration of the CSV on top
> of the CLTV-deltas imposed by intermediary nodes, with weights
> complicated by the fact that CLTV-deltas are summed together but the
> highest CSV is added to the CLTV total, which does not mix well with
> typical route-finding algorithms (most of which assume a simple
> summing of costs, which CLTV-deltas use but CSVs on
> Decker-Osuntokun-Russell do not since highest is used).
>
> In almost all other ways, Poon-Dryja is inferior:
>
> 1. Does not use nLockTime in a sufficiently clever way. 2.
> Dangerous "toxic waste" (old revoked transactions) which (1) you
> should not recover from your backups and (2) you should not let your
> worst enemy find, because they can publish those onchain and make you
> LOSE MONEY. 3. Symmetrical chains of transactions, different for
> both parties, instead of a single chain.
>
> In addition, arbitrary contracts are not really particularly useful.
> HTLCs seem to me an important building block for digital value
> transfers, and they (and their equivalents under scriptless) are
> sufficient for most practical transfers. Thus, moving forward,
> Decker-Osuntokun-Russell remains a superior technology over
> Poon-Dryja.
>
> Regards, ZmnSCPxj _______________________________________________
> Lightning-dev mailing list Lightning-dev at lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev