Return-Path: Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 259EEAE7 for ; Mon, 13 Nov 2017 15:31:59 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-lf0-f42.google.com (mail-lf0-f42.google.com [209.85.215.42]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id E359AE5 for ; Mon, 13 Nov 2017 15:31:57 +0000 (UTC) Received: by mail-lf0-f42.google.com with SMTP id r135so18814813lfe.5 for ; Mon, 13 Nov 2017 07:31:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=SM7v/7jxtKXxVA4AYWJ7iRLOvwrrQSfDHBvlfll5JMg=; b=oCVfODWdWAhC7pUja6/e4QZ3ULcG2jLapFyMf+Vhdv798C4Q8En6jSo+jmi0Pdxzuv m/lYPc78CH+h5wcI8Rhf+nqI8t0VJx4f9DaOGHGEukGzqFeAsEDkk7zOEUrS3rI9mRor Fywd1zmtauF7biyf5422Yfuck80oRT8kBoGuQIYn7jTCyMk1PFOxBGfUeVx25VkWhnTT JmwstPMEx6v2ktHT1XSdT9nxuqyt26geD7VNjrXH1UrPzSYMkrFRSPTTsJ3X3l1+BcEy yImJVGRm6C2nmU5rCiOdp2QouMUQiO039JPAljSgxOkOd+6efGRK6DSI299rA3XzxwXG 2rAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=SM7v/7jxtKXxVA4AYWJ7iRLOvwrrQSfDHBvlfll5JMg=; b=kPpiIT7E5s8wlawBty1fu8NZQ34gF9d0L0G38rt1zZnuAtjFIvZHqb+v2HpBugh6to u7wIAH/YTm6Kf8qmqR5pDEYc8HbmmEGnPOlh4NgZIpfhm6R3gcUdX4azxbQ+QQg0bnRY UQMirFrXCiG81ywTQwToMumG8J5ZFfkg+AM8D0ZnCMKowG6gYhqmg/xR6hlz927HoFx1 C6p9Abg74AwMrZTdqLezPHUb7LG+UcBTnAI2Z8yJzicC7tClZG6d2WbfxjMXWIqSaAB4 ov3FmstSccnGwQL1N9eXfPOTnxdptaFR13JZf+Pv0p5ez7yBz//a7HRZOMySs/AOw4wf MmRQ== X-Gm-Message-State: AJaThX51017YllUOsk9qkxwJmWTx2wDG4qMX57pBKyWXrslTH6rb/y+F Fy3jqSuOTDsPF6KCtNUzHoesi8ShQ8oGqcv2En4Udjyu X-Google-Smtp-Source: AGs4zMaPFiex1vNLf4jBvyzJzR3PDHunBbe92+BS2oWQhCXJmo8vxZu+4gGap0php81cjOtkGwQ2hwTIpB9RWBPDI/M= X-Received: by 10.25.78.91 with SMTP id c88mr2349414lfb.4.1510587116287; Mon, 13 Nov 2017 07:31:56 -0800 (PST) MIME-Version: 1.0 Received: by 10.25.168.7 with HTTP; Mon, 13 Nov 2017 07:31:55 -0800 (PST) In-Reply-To: <24A6C651-272B-4452-8A81-31651D9A2694@blockchain.com> References: <7601C2CD-8544-4501-80CE-CAEB402A72D2@blockchain.com> <45C2D68B-BA8E-47DE-BFA5-643922395B2A@sprovoost.nl> <95ECB451-56AE-45E5-AAE6-10058C4B7FD7@sprovoost.nl> <55467A01-A8B2-4E73-8331-38C0A7CD90EF@sprovoost.nl> <46E317DF-C97C-4797-B989-594298BC6030@sprovoost.nl> <3FBEE883-A15E-425C-8BF1-F7792FA63961@blockchain.com> <24A6C651-272B-4452-8A81-31651D9A2694@blockchain.com> From: Jacob Eliosoff Date: Mon, 13 Nov 2017 10:31:55 -0500 Message-ID: To: Mats Jerratsch Content-Type: multipart/alternative; boundary="94eb2c1cdbb677fb60055ddef821" X-Spam-Status: No, score=-0.1 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_NONE autolearn=disabled version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org X-Mailman-Approved-At: Mon, 13 Nov 2017 15:34:38 +0000 Cc: Bitcoin Dev Subject: Re: [bitcoin-dev] Generalised Replay Protection for Future Hard Forks X-BeenThere: bitcoin-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Bitcoin Protocol Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Nov 2017 15:31:59 -0000 --94eb2c1cdbb677fb60055ddef821 Content-Type: text/plain; charset="UTF-8" > > This is actually incorrect. There are two transactions involved in LN. The > funding transaction, which opens a payment channel, and a commitment > transaction, which closes the channel when broadcasted to the network (the > cooperative closing transaction can be considered a commitment transaction > in a loose sense). > > Now you want to protect the funding transaction, as otherwise you would be > subject to a replay-attack on all *past* forks. So you will set > `nForkId>=1` for the funding transaction, making this payment channel > non-existent on any *past* forks. However, if during the lifetime of the > payment channel another fork happens, the payment channel exists for both > tokens. So for the commitment transaction, you will have `nForkId=0`, > making it valid on both of these chains. While this `nForkId` is valid on > all chains, the parent transaction it tries to spend (the funding > transaction) does only exist on two chains, the original one you created > the channel for and the one that forked away. > Thanks for the clarification. How would a tx specify a constraint like "nForkId>=1"? I was thinking of it just as a number set on the tx. Also note that since forks form a partial order, but IDs (numbers) form a total order, ">=" will miss some cases. Eg, suppose BCH had forked with nForkId 2, and then you set up a LN funding tx on BCH with nForkId>=2, and then Segwit2x forked (from BTC!) with nForkId 3. The BCH funding tx would be valid on Segwit2x. This is more of a fundamental problem than a bug - to avoid it you'd have to get into stuff like making each fork reference its parent-fork's first block or something, someone has written about this... On Mon, Nov 13, 2017 at 5:03 AM, Mats Jerratsch wrote: > > OK, so nForkId 0 is exactly the "valid on all chains" specifier I was > asking about, cool. And your LN example (and nLockTime txs in general) > illustrate why it's preferable to implement a generic replay protection > scheme like yours *in advance*, rather than before each fork: all ad hoc > RP schemes I know of break old txs on one of the chains, even when that's > not desirable - ie, they offer no wildcard like nForkId 0. > > > Exactly! > > One comment on your LN example: users would have to take note that nForkId > 0 txs would be valid not only on future forks, but on *past* forks too. > Eg, if BCH had been deployed with nForkId 2, then a user setting up BTC LN > txs now with nForkId 0 would have to be aware that those txs would be valid > for BCH too. Of course the user could avoid this by funding from a > BTC-only address, but it is a potential minor pitfall of nForkId 0. (Which > I don't see any clean way around.) > > > This is actually incorrect. There are two transactions involved in LN. The > funding transaction, which opens a payment channel, and a commitment > transaction, which closes the channel when broadcasted to the network (the > cooperative closing transaction can be considered a commitment transaction > in a loose sense). > > Now you want to protect the funding transaction, as otherwise you would be > subject to a replay-attack on all *past* forks. So you will set > `nForkId>=1` for the funding transaction, making this payment channel > non-existent on any *past* forks. However, if during the lifetime of the > payment channel another fork happens, the payment channel exists for both > tokens. So for the commitment transaction, you will have `nForkId=0`, > making it valid on both of these chains. While this `nForkId` is valid on > all chains, the parent transaction it tries to spend (the funding > transaction) does only exist on two chains, the original one you created > the channel for and the one that forked away. > --94eb2c1cdbb677fb60055ddef821 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
This is actually incorrect. There are= two transactions involved in LN. The funding transaction, which opens a pa= yment channel, and a commitment transaction, which closes the channel when = broadcasted to the network (the cooperative closing transaction can be cons= idered a commitment transaction in a loose sense).=C2=A0

Now you want to protect the funding transaction, as otherwise you wo= uld be subject to a replay-attack on all *past* forks. So you will set `nFo= rkId>=3D1` for the funding transaction, making this payment channel non-= existent on any *past* forks. However, if during the lifetime of the paymen= t channel another fork happens, the payment channel exists for both tokens.= So for the commitment transaction, you will have `nForkId=3D0`, making it = valid on both of these chains. While this `nForkId` is valid on all chains,= the parent transaction it tries to spend (the funding transaction) does on= ly exist on two chains, the original one you created the channel for and th= e one that forked away.=C2=A0

= Thanks for the clarification.=C2=A0 How would a tx specify a constraint lik= e "nForkId>=3D1"?=C2=A0 I was thinking of it just as a number = set on the tx.

Also note that since forks form a partial= order, but IDs (numbers) form a total order, ">=3D" will miss= some cases.=C2=A0 Eg, suppose BCH had forked with nForkId 2, and then you = set up a LN funding tx on BCH with nForkId>=3D2, and then Segwit2x forke= d (from BTC!) with nForkId 3.=C2=A0 The BCH funding tx would be valid on Se= gwit2x.=C2=A0 This is more of a fundamental problem than a bug - to avoid i= t you'd have to get into stuff like making each fork reference its pare= nt-fork's first block or something, someone has written about this...


O= n Mon, Nov 13, 2017 at 5:03 AM, Mats Jerratsch <mats@blockchain.com&= gt; wrote:

OK, so nForkId 0 is exactly the "= valid on all chains" specifier I was asking about, cool.=C2=A0 And you= r LN example (and nLockTime txs in general) illustrate why it's prefera= ble to implement a generic replay protection scheme like yours in advanc= e, rather than before each fork: all ad hoc RP schemes I know of break = old txs on one of the chains, even when that's not desirable - ie, they= offer no wildcard like nForkId 0.

<= /span>
Exactly!

One comment on your LN example: us= ers would have to take note that nForkId 0 txs would be valid not only on f= uture forks, but on past forks too.=C2=A0 Eg, if BCH had been deploy= ed with nForkId 2, then a user setting up BTC LN txs now with nForkId 0 wou= ld have to be aware that those txs would be valid for BCH too.=C2=A0 Of cou= rse the user could avoid this by funding from a BTC-only address, but it is= a potential minor pitfall of nForkId 0.=C2=A0 (Which I don't see any c= lean way around.)

This is actually incorrect. There = are two transactions involved in LN. The funding transaction, which opens a= payment channel, and a commitment transaction, which closes the channel wh= en broadcasted to the network (the cooperative closing transaction can be c= onsidered a commitment transaction in a loose sense).=C2=A0

<= /div>
Now you want to protect the funding transaction, as otherwise you= would be subject to a replay-attack on all *past* forks. So you will set `= nForkId>=3D1` for the funding transaction, making this payment channel n= on-existent on any *past* forks. However, if during the lifetime of the pay= ment channel another fork happens, the payment channel exists for both toke= ns. So for the commitment transaction, you will have `nForkId=3D0`, making = it valid on both of these chains. While this `nForkId` is valid on all chai= ns, the parent transaction it tries to spend (the funding transaction) does= only exist on two chains, the original one you created the channel for and= the one that forked away.=C2=A0

--94eb2c1cdbb677fb60055ddef821--