From decker.christian at gmail.com Wed Aug 1 12:04:47 2018 From: decker.christian at gmail.com (Christian Decker) Date: Wed, 01 Aug 2018 14:04:47 +0200 Subject: [Lightning-dev] Arbitrary Bitcoin Contracts over LN In-Reply-To: References: Message-ID: <877elal2cg.fsf@gmail.com> 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 OP_ELSE 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 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