Return-Path: <bastien.teinturier@acinq.fr> Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id CB653C0032 for <bitcoin-dev@lists.linuxfoundation.org>; Wed, 18 Oct 2023 14:35:56 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id A4F8F400DA for <bitcoin-dev@lists.linuxfoundation.org>; Wed, 18 Oct 2023 14:35:56 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org A4F8F400DA Authentication-Results: smtp2.osuosl.org; dkim=pass (2048-bit key) header.d=acinq.fr header.i=@acinq.fr header.a=rsa-sha256 header.s=google header.b=TiExUDv+ X-Virus-Scanned: amavisd-new at osuosl.org X-Spam-Flag: NO X-Spam-Score: -2.088 X-Spam-Level: X-Spam-Status: No, score=-2.088 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, T_SPF_PERMERROR=0.01] autolearn=ham autolearn_force=no Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KsTDbPwav2SG for <bitcoin-dev@lists.linuxfoundation.org>; Wed, 18 Oct 2023 14:35:54 +0000 (UTC) Received: from mail-ot1-x32e.google.com (mail-ot1-x32e.google.com [IPv6:2607:f8b0:4864:20::32e]) by smtp2.osuosl.org (Postfix) with ESMTPS id 3E5B7404FE for <bitcoin-dev@lists.linuxfoundation.org>; Wed, 18 Oct 2023 14:35:54 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org 3E5B7404FE Received: by mail-ot1-x32e.google.com with SMTP id 46e09a7af769-6c4b9e09521so4540353a34.3 for <bitcoin-dev@lists.linuxfoundation.org>; Wed, 18 Oct 2023 07:35:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=acinq.fr; s=google; t=1697639753; x=1698244553; darn=lists.linuxfoundation.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=zin0xJTfYoFKaOBDKGDywG1vVBKJRze9t2yk5ki+5Hc=; b=TiExUDv+00ELdLB5ao9FKDWMXKOytofx4/gMPM0TWl21wJQF33z9344ZCdt2h/gAeL m28Ytkkud3VaueYqu3b53Ek3uxOMO6k8VEukVrBIJds1+aw9N67r+0tpLpemmLcqF7Z6 LXgMyNkQumIBCz5JD9iYnM2oxHWdn+W6Anw2EKxFg09MUL7eoc6Ynfpofli1Jv9lFIFf Hay0onrigcrxsNtJqVX0c0JWwBjZwHRk5sb156zz0m+J5XDwulLK7bd3BMU3B9XymePN q/TlRSSJtspRQ1LdcF2jR91rShenMb8LLxLO48JaLiwBlePOXCaooivs1aDhVOkurwGo qltQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697639753; x=1698244553; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=zin0xJTfYoFKaOBDKGDywG1vVBKJRze9t2yk5ki+5Hc=; b=g7Vto16YzQcEOxOsa528mmGkbJFithq9LAxCEwvf3B/NkMcAYTFY6Ku2WGSASp5I/8 Ul+jk/4fs2V9jA6VBWTQ5Mw9Fea7j+nAoWSoDuoXN30Fn9VDO3hKMCNDI1idXFNRbHCE GPOz/mdJV9eg70glqR10dBX9ip00YTm227PznVfw5vBtIT1O9LfHbFRdsUNav1nMKXc8 9fVEmBYLuQHfKuF9mQ1qR3N7I1l5xdjK2TN7y6oba6jFDA1o5O4hoj0WqpiZ5gtuykWq eD0M/hLRXxia4TxlZ+D4r2UyvaoXcgnfJriauxJhZHv6rg1c4ii3A5Y3wjKd/5ZTGOn2 kiHg== X-Gm-Message-State: AOJu0YyF75S9mbuLSfweaW4g9baLnLZh/keR3Eyi25zy32Gj5DuaC3Pf 5Izyd4dS9zUjqGvKXQL0MPXm3bcu9BpCh/74DNX7qg== X-Google-Smtp-Source: AGHT+IE97JDyVfN0XJjy0TVU6lXEo1aCqdt4YxmymyEi3rEYiBusxdw4iJs3XUa3zshWOMpdP4KBeX9g3eXT2G3tTis= X-Received: by 2002:a05:6871:c84:b0:1ea:29a:861e with SMTP id vf4-20020a0568710c8400b001ea029a861emr5218740oab.12.1697639752988; Wed, 18 Oct 2023 07:35:52 -0700 (PDT) MIME-Version: 1.0 References: <CACdvm3MuKmzQ1EFMJDc0ahhrG6xpD6Rr9Vh=ZTpVHa12ZALB0w@mail.gmail.com> <CALZpt+E+od+nejiZDeMfQ+qLNMc8UnU=G1YVsH+REut6+Jj-Bg@mail.gmail.com> In-Reply-To: <CALZpt+E+od+nejiZDeMfQ+qLNMc8UnU=G1YVsH+REut6+Jj-Bg@mail.gmail.com> From: Bastien TEINTURIER <bastien@acinq.fr> Date: Wed, 18 Oct 2023 16:35:40 +0200 Message-ID: <CACdvm3OJsg2Br91aDL8=eACTW1WkdQcUSCvpWyniuEZf+qSAuA@mail.gmail.com> To: Antoine Riard <antoine.riard@gmail.com> Content-Type: multipart/alternative; boundary="0000000000006f1e2b0607fe8e71" X-Mailman-Approved-At: Wed, 18 Oct 2023 16:39:50 +0000 Cc: Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>, "lightning-dev\\\\@lists.linuxfoundation.org" <lightning-dev@lists.linuxfoundation.org> Subject: Re: [bitcoin-dev] [Lightning-dev] Batch exchange withdrawal to lightning requires covenants X-BeenThere: bitcoin-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org> List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>, <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe> List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/> List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org> List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help> List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>, <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe> X-List-Received-Date: Wed, 18 Oct 2023 14:35:56 -0000 --0000000000006f1e2b0607fe8e71 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hey Z-man, Antoine, Thank you for your feedback, responses inline. z-man: > Then if I participate in a batched splice, I can disrupt the batched > splice by broadcasting the old state and somehow convincing miners to > confirm it before the batched splice. Correct, I didn't mention it in my post but batched splices cannot use 0-conf, the transaction must be confirmed to remove the risk of double spends using commit txs associated with the previous funding tx. But interestingly, with the protocol I drafted, the LSP can finalize and broadcast the batched splice transaction while users are offline. With a bit of luck, when the users reconnect, that transaction will already be confirmed so it will "feel 0-conf". Also, we need a mechanism like the one you describe when we detect that a splice transaction has been double-spent. But this isn't specific to batched transactions, 2-party splice transactions can also be double spent by either participant. So we need that mechanism anyway? The spec doesn't have a way of aborting a splice after exchanging signatures, but you can always do it as an RBF operation (which actually just does a completely different splice). This is what Greg mentioned in his answer. > part of the splice proposal is that while a channel is being spliced, > it should not be spliced again, which your proposal seems to violate. The spec doesn't require that, I'm not sure what made you think that. While a channel is being spliced, it can definitely be spliced again as an RBF attempt (this is actually a very important feature), which double spends the other unconfirmed splice attempts. ariard: > It is uncertain to me if secure fee-bumping, even with future > mechanisms like package relay and nversion=3D3, is robust enough for > multi-party transactions and covenant-enable constructions under usual > risk models. I'm not entirely sure why you're bringing this up in this context... I agree that we most likely cannot use RBF on those batched transactions we will need to rely on CPFP and potentially package relay. But why is it different from non-multi-party transactions here? > See test here: > https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72= f1efcf I'd argue that this is quite different from the standard replacement cycling attack, because in this protocol wallet users can only unilaterally double-spend with a commit tx, on which they cannot set the feerate. The only participant that can "easily" double-spend is the exchange, and they wouldn't have an incentive to here, users are only withdrawing funds, there's no opportunity of stealing funds? Thanks, Bastien Le mar. 17 oct. 2023 =C3=A0 21:10, Antoine Riard <antoine.riard@gmail.com> = a =C3=A9crit : > Hi Bastien, > > > The naive way of enabling lightning withdrawals is to make the user > > provide a lightning invoice that the exchange pays over lightning. The > > issue is that in most cases, this simply shifts the burden of making an > > on-chain transaction to the user's wallet provider: if the user doesn't > > have enough inbound liquidity (which is likely), a splice transaction > > will be necessary. If N users withdraw funds from an exchange, we most > > likely will end up with N separate splice transactions. > > It is uncertain to me if secure fee-bumping, even with future mechanisms > like package relay and nversion=3D3, is robust enough for multi-party > transactions and covenant-enable constructions under usual risk models. > > See test here: > > https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d= 72f1efcf > > Appreciated expert eyes of folks understanding both lightning and core > mempool on this. > There was a lot of back and forth on nversion=3D3 design rules, though th= e > test is normally built on glozow top commit of the 3 Oct 2023. > > Best, > Antoine > > Le mar. 17 oct. 2023 =C3=A0 14:03, Bastien TEINTURIER <bastien@acinq.fr> = a > =C3=A9crit : > >> Good morning list, >> >> I've been trying to design a protocol to let users withdraw funds from >> exchanges directly into their lightning wallet in an efficient way >> (with the smallest on-chain footprint possible). >> >> I've come to the conclusion that this is only possible with some form of >> covenants (e.g. `SIGHASH_ANYPREVOUT` would work fine in this case). The >> goal of this post is to explain why, and add this usecase to the list of >> useful things we could do if we had covenants (insert "wen APO?" meme). >> >> The naive way of enabling lightning withdrawals is to make the user >> provide a lightning invoice that the exchange pays over lightning. The >> issue is that in most cases, this simply shifts the burden of making an >> on-chain transaction to the user's wallet provider: if the user doesn't >> have enough inbound liquidity (which is likely), a splice transaction >> will be necessary. If N users withdraw funds from an exchange, we most >> likely will end up with N separate splice transactions. >> >> Hence the idea of batching those into a single transaction. Since we >> don't want to introduce any intermediate transaction, we must be able >> to create one transaction that splices multiple channels at once. The >> issue is that for each of these channels, we need a signature from the >> corresponding wallet user, because we're spending the current funding >> output, which is a 2-of-2 multisig between the wallet user and the >> wallet provider. So we run into the usual availability problem: we need >> signatures from N users who may not be online at the same time, and if >> one of those users never comes online or doesn't complete the protocol, >> we must discard the whole batch. >> >> There is a workaround though: each wallet user can provide a signature >> using `SIGHASH_SINGLE | SIGHASH_ANYONECANPAY` that spends their current >> funding output to create a new funding output with the expected amount. >> This lets users sign *before* knowing the final transaction, which the >> exchange can create by batching pairs of inputs/outputs. But this has >> a fatal issue: at that point the wallet user has no way of spending the >> new funding output (since it is also a 2-of-2 between the wallet user >> and the wallet provider). The wallet provider can now blackmail the user >> and force them to pay to get their funds back. >> >> Lightning normally fixes this by exchanging signatures for a commitment >> transaction that sends the funds back to their owners *before* signing >> the parent funding/splice transaction. But here that is impossible, >> because we don't know yet the `txid` of the batch transaction (that's >> the whole point, we want to be able to sign before creating the batch) >> so we don't know the new `prevout` we should spend from. I couldn't find >> a clever way to work around that, and I don't think there is one (but >> I would be happy to be wrong). >> >> With `SIGHASH_ANYPREVOUT`, this is immediately fixed: we can exchange >> anyprevout signatures for the commitment transaction, and they will be >> valid to spend from the batch transaction. We are safe from signature >> reuse, because funding keys are rotated at each splice so we will never >> create another output that uses the same 2-of-2 script. >> >> I haven't looked at other forms of covenants, but most of them likely >> address this problem as well. >> >> Cheers, >> Bastien >> _______________________________________________ >> Lightning-dev mailing list >> Lightning-dev@lists.linuxfoundation.org >> https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev >> > --0000000000006f1e2b0607fe8e71 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">Hey Z-man, Antoine,<br><br>Thank you for your feedback, re= sponses inline.<br><br>z-man:<br><br>> Then if I participate in a batche= d splice, I can disrupt the batched<br>> splice by broadcasting the old = state and somehow convincing miners to<br>> confirm it before the batche= d splice.<br><br>Correct, I didn't mention it in my post but batched sp= lices cannot use<br>0-conf, the transaction must be confirmed to remove the= risk of double<br>spends using commit txs associated with the previous fun= ding tx.<br><br>But interestingly, with the protocol I drafted, the LSP can= finalize and<br>broadcast the batched splice transaction while users are o= ffline. With a<br>bit of luck, when the users reconnect, that transaction w= ill already be<br>confirmed so it will "feel 0-conf".<br><br>Also= , we need a mechanism like the one you describe when we detect that<br>a sp= lice transaction has been double-spent. But this isn't specific to<br>b= atched transactions, 2-party splice transactions can also be double<br>spen= t by either participant. So we need that mechanism anyway? The spec<br>does= n't have a way of aborting a splice after exchanging signatures, but<br= >you can always do it as an RBF operation (which actually just does a<br>co= mpletely different splice). This is what Greg mentioned in his answer.<br><= br>> part of the splice proposal is that while a channel is being splice= d,<br>> it should not be spliced again, which your proposal seems to vio= late.<br><br>The spec doesn't require that, I'm not sure what made = you think that.<br>While a channel is being spliced, it can definitely be s= pliced again as<br>an RBF attempt (this is actually a very important featur= e), which double<br>spends the other unconfirmed splice attempts.<br><br>ar= iard:<br><br>> It is uncertain to me if secure fee-bumping, even with fu= ture<br>> mechanisms like package relay and nversion=3D3, is robust enou= gh for<br>> multi-party transactions and covenant-enable constructions u= nder usual<br>> risk models.<br><br>I'm not entirely sure why you= 9;re bringing this up in this context...<br>I agree that we most likely can= not use RBF on those batched transactions<br>we will need to rely on CPFP a= nd potentially package relay. But why is<br>it different from non-multi-par= ty transactions here?<br><br>> See test here:<br>> <a href=3D"https:/= /github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72f1efcf"= >https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d7= 2f1efcf</a><br><br>I'd argue that this is quite different from the stan= dard replacement<br>cycling attack, because in this protocol wallet users c= an only<br>unilaterally double-spend with a commit tx, on which they cannot= set<br>the feerate. The only participant that can "easily" doubl= e-spend is<br>the exchange, and they wouldn't have an incentive to here= , users are<br>only withdrawing funds, there's no opportunity of steali= ng funds?<br><br>Thanks,<br>Bastien<br></div><br><div class=3D"gmail_quote"= ><div dir=3D"ltr" class=3D"gmail_attr">Le=C2=A0mar. 17 oct. 2023 =C3=A0=C2= =A021:10, Antoine Riard <<a href=3D"mailto:antoine.riard@gmail.com">anto= ine.riard@gmail.com</a>> a =C3=A9crit=C2=A0:<br></div><blockquote class= =3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg= b(204,204,204);padding-left:1ex"><div dir=3D"ltr">Hi Bastien,<div><br></div= ><div>> The naive way of enabling lightning withdrawals is to make the u= ser<br>> provide a lightning invoice that the exchange pays over lightni= ng. The<br>> issue is that in most cases, this simply shifts the burden = of making an<br>> on-chain transaction to the user's wallet provider= : if the user doesn't<br>> have enough inbound liquidity (which is l= ikely), a splice transaction<br>> will be necessary. If N users withdraw= funds from an exchange, we most<br>> likely will end up with N separate= splice transactions.<br></div><div><br></div><div>It is uncertain to me if= secure fee-bumping, even with future mechanisms like package relay and=C2= =A0nversion=3D3, is robust enough for multi-party transactions and covenant= -enable constructions under usual risk models.</div><div><br></div><div>See= test here:</div><div><a href=3D"https://github.com/ariard/bitcoin/commit/1= 9d61fa8cf22a5050b51c4005603f43d72f1efcf" target=3D"_blank">https://github.c= om/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72f1efcf</a><br></= div><div><br></div><div>Appreciated expert eyes of folks understanding both= lightning and core mempool on this.</div><div>There was a lot of back and = forth on nversion=3D3 design rules, though the test is normally built on gl= ozow top commit of the 3 Oct 2023.</div><div><br></div><div>Best,</div><div= >Antoine</div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class= =3D"gmail_attr">Le=C2=A0mar. 17 oct. 2023 =C3=A0=C2=A014:03, Bastien TEINTU= RIER <<a href=3D"mailto:bastien@acinq.fr" target=3D"_blank">bastien@acin= q.fr</a>> a =C3=A9crit=C2=A0:<br></div><blockquote class=3D"gmail_quote"= style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);p= adding-left:1ex"><div dir=3D"ltr">Good morning list,<br><br>I've been t= rying to design a protocol to let users withdraw funds from<br>exchanges di= rectly into their lightning wallet in an efficient way<br>(with the smalles= t on-chain footprint possible).<br><br>I've come to the conclusion that= this is only possible with some form of<br>covenants (e.g. `SIGHASH_ANYPRE= VOUT` would work fine in this case). The<br>goal of this post is to explain= why, and add this usecase to the list of<br>useful things we could do if w= e had covenants (insert "wen APO?" meme).<br><br>The naive way of= enabling lightning withdrawals is to make the user<br>provide a lightning = invoice that the exchange pays over lightning. The<br>issue is that in most= cases, this simply shifts the burden of making an<br>on-chain transaction = to the user's wallet provider: if the user doesn't<br>have enough i= nbound liquidity (which is likely), a splice transaction<br>will be necessa= ry. If N users withdraw funds from an exchange, we most<br>likely will end = up with N separate splice transactions.<br><br>Hence the idea of batching t= hose into a single transaction. Since we<br>don't want to introduce any= intermediate transaction, we must be able<br>to create one transaction tha= t splices multiple channels at once. The<br>issue is that for each of these= channels, we need a signature from the<br>corresponding wallet user, becau= se we're spending the current funding<br>output, which is a 2-of-2 mult= isig between the wallet user and the<br>wallet provider. So we run into the= usual availability problem: we need<br>signatures from N users who may not= be online at the same time, and if<br>one of those users never comes onlin= e or doesn't complete the protocol,<br>we must discard the whole batch.= <br><br>There is a workaround though: each wallet user can provide a signat= ure<br>using `SIGHASH_SINGLE | SIGHASH_ANYONECANPAY` that spends their curr= ent<br>funding output to create a new funding output with the expected amou= nt.<br>This lets users sign *before* knowing the final transaction, which t= he<br>exchange can create by batching pairs of inputs/outputs. But this has= <br>a fatal issue: at that point the wallet user has no way of spending the= <br>new funding output (since it is also a 2-of-2 between the wallet user<b= r>and the wallet provider). The wallet provider can now blackmail the user<= br>and force them to pay to get their funds back.<br><br>Lightning normally= fixes this by exchanging signatures for a commitment<br>transaction that s= ends the funds back to their owners *before* signing<br>the parent funding/= splice transaction. But here that is impossible,<br>because we don't kn= ow yet the `txid` of the batch transaction (that's<br>the whole point, = we want to be able to sign before creating the batch)<br>so we don't kn= ow the new `prevout` we should spend from. I couldn't find<br>a clever = way to work around that, and I don't think there is one (but<br>I would= be happy to be wrong).<br><br>With `SIGHASH_ANYPREVOUT`, this is immediate= ly fixed: we can exchange<br>anyprevout signatures for the commitment trans= action, and they will be<br>valid to spend from the batch transaction. We a= re safe from signature<br>reuse, because funding keys are rotated at each s= plice so we will never<br>create another output that uses the same 2-of-2 s= cript.<br><br>I haven't looked at other forms of covenants, but most of= them likely<br>address this problem as well.<br><br>Cheers,<br>Bastien<br>= </div> _______________________________________________<br> Lightning-dev mailing list<br> <a href=3D"mailto:Lightning-dev@lists.linuxfoundation.org" target=3D"_blank= ">Lightning-dev@lists.linuxfoundation.org</a><br> <a href=3D"https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev= " rel=3D"noreferrer" target=3D"_blank">https://lists.linuxfoundation.org/ma= ilman/listinfo/lightning-dev</a><br> </blockquote></div> </blockquote></div> --0000000000006f1e2b0607fe8e71--