Return-Path: Received: from smtp1.osuosl.org (smtp1.osuosl.org [IPv6:2605:bc80:3010::138]) by lists.linuxfoundation.org (Postfix) with ESMTP id 11F1FC0032; Wed, 18 Oct 2023 18:04:04 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id DD28983022; Wed, 18 Oct 2023 18:04:03 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org DD28983022 Authentication-Results: smtp1.osuosl.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=Sfw/dpxj X-Virus-Scanned: amavisd-new at osuosl.org X-Spam-Flag: NO X-Spam-Score: -2.098 X-Spam-Level: X-Spam-Status: No, score=-2.098 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, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id vCiuQ6iczqDW; Wed, 18 Oct 2023 18:04:01 +0000 (UTC) Received: from mail-io1-xd34.google.com (mail-io1-xd34.google.com [IPv6:2607:f8b0:4864:20::d34]) by smtp1.osuosl.org (Postfix) with ESMTPS id 725738301D; Wed, 18 Oct 2023 18:04:01 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 725738301D Received: by mail-io1-xd34.google.com with SMTP id ca18e2360f4ac-79fe6da0095so288134939f.0; Wed, 18 Oct 2023 11:04:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1697652240; x=1698257040; 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=Ee6/BBHokm/hqDgyNQjYHAwWwD6hgl0uJc36QC9xoKM=; b=Sfw/dpxjUcK5u6nVfjCl8xoMfapj0J4O+GGrFj4OhEfX/e5ksgd3PhbXOs03fpaA8/ g/wHFDa3msJdXesl/7LVGIpuLbXJrrKJw2I/WzAIcx129labHocxud0NYfqq6xcQ4Z0t nl57M51t0hPL1BTkoS/3S1lGQFtmsdwQ8QceC8W6XTyXJSeiQaarLIBzU+zZKFldxlR2 slPto8aR0ZFWf4IUOUOYV37cjZ6epB7Zi3meQ/DqBdefedenr9cN4ezYaxb9CXhH3hRt BqeoJjrsy9aVDcd1w0332naRKkmzPnWrF0m3j80jcAIBi6W9Sz7OlZ+NOuMMth5WonUO Q4Uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697652240; x=1698257040; 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=Ee6/BBHokm/hqDgyNQjYHAwWwD6hgl0uJc36QC9xoKM=; b=HhlwxwjfO9U+RbTP+YkN0L5357/OLr3fjoRnosRkTOJKqdJDhUGmOGjAmmFUvF0xHU UokXdKmSZRflW1QJrHxB2x3wEbi6SCzl0GVXRVBraRZVKe1y0pdRFunDV0fQUNVfMPtq wPBussFBNUo2hoXkhK1UWLLSzP3J2fnpCAZP0pzBZnP/app/8CFBZKUy1VSJWYlC2A7f qFY+yhd+DmDm/VxDO1ox8atxwUjVj2KkHCmBc+wwr25ngcX7kMx2xmjQd3Mnnv97vAIn esG/xO/gyq/VZf5ZOcjVO2ssVAKR5n6YW9eKEhd+wDYNzcR3/nXaoRGZaX9/rn+OpHn5 yxgQ== X-Gm-Message-State: AOJu0YyFfPn/vlplhxy2lSCDl7RXZgh1tmoJpTQWuVyxmeMwwR8jM7Q8 7aCe0sLO8DO2+fOtQMabAUQLiLGsmoyVuNaLZpg= X-Google-Smtp-Source: AGHT+IGg1B4dRsdFwf4YH2jMgH0l40i3EM4CEQwhcGHCcftXjrkw+sMUb6Rvf60hGBcq1hYAAy99L2NEiG2x91heDfM= X-Received: by 2002:a05:6602:2b0b:b0:787:34d:f1ea with SMTP id p11-20020a0566022b0b00b00787034df1eamr23571iov.8.1697652240286; Wed, 18 Oct 2023 11:04:00 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Antoine Riard Date: Wed, 18 Oct 2023 19:03:48 +0100 Message-ID: To: Bastien TEINTURIER Content-Type: multipart/alternative; boundary="000000000000bc09890608017642" X-Mailman-Approved-At: Wed, 18 Oct 2023 19:05:13 +0000 Cc: Bitcoin Protocol Discussion , "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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 18 Oct 2023 18:04:04 -0000 --000000000000bc09890608017642 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Bastien, Thanks for the answer. If I understand correctly the protocol you're describing you're aiming to enable batched withdrawals where a list of users are being sent funds from an exchange directly in a list of channel funding outputs ("splice-out"). Those channels funding outputs are 2-of-2, between two lambda users or e.g a lambda user and a LSP. If I'm correct, two users can cooperate maliciously against the batch withdrawal transactions by re-signing a CPFP from 2-of-2 and broadcasting the batch withdrawal as a higher-feerate package / high fee package and then evicting out the CPFP. If the batch withdrawal has been signed with 0-fee thanks to the nversion= =3D3 policy exemption, it will be evicted out of the mempool. A variant of a replacement cycling attack. I think this more or less matches the test I'm pointing to you which is on non-deployed package acceptance code: https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72= f1efcf Please correct me if I'm wrong or missing assumptions. Agree with you on the assumptions that the exchange does not have an incentive to double-spend its own withdrawal transactions, or if all the batched funding outputs are shared with a LSP, malicious collusion is less plausible. Best, Antoine Le mer. 18 oct. 2023 =C3=A0 15:35, Bastien TEINTURIER a =C3=A9crit : > 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/19d61fa8cf22a5050b51c4005603f43d= 72f1efcf > > 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 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 a= n >> > 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/19d61fa8cf22a5050b51c4005603f43= d72f1efcf >> >> 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 t= he >> 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 = 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 o= f >>> 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 o= f >>> 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 use= r >>> 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 fin= d >>> 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 >>> >> --000000000000bc09890608017642 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Bastien,

Thanks for the answer.

If I understand correctly the protocol=C2=A0you're= describing=C2=A0you're aiming to enable batched withdrawals where a li= st of users are being sent funds from an exchange directly in a list of cha= nnel funding outputs ("splice-out"). Those channels funding outpu= ts are 2-of-2, between two lambda users or e.g a lambda user and a LSP.

If I'm correct, two users can cooperate malicious= ly against the batch withdrawal transactions by re-signing a CPFP from 2-of= -2 and broadcasting the batch withdrawal as a higher-feerate package / high= fee package and then evicting out the CPFP.=C2=A0

If the batch withdrawal has been signed with 0-fee thanks to the nversion= =3D3 policy exemption, it will be evicted out of the=C2=A0mempool. A varian= t of a replacement cycling attack.

I think this mo= re or less=C2=A0matches the test I'm pointing to you which is on non-de= ployed package acceptance code:

Please correct me if I'm wrong or missing ass= umptions. Agree with you on the assumptions that the exchange does not have= an incentive to double-spend its own withdrawal transactions, or if all th= e batched funding outputs are shared with a LSP, malicious collusion is les= s plausible.

Best,
Antoine
Le=C2=A0= mer. 18 oct. 2023 =C3=A0=C2=A015:35, Bastien TEINTURIER <bastien@acinq.fr> a =C3=A9crit=C2=A0:
=
Hey Z-man, Antoine,

Thank you for = your feedback, responses inline.

z-man:

> Then if I partic= ipate in a batched splice, I can disrupt the batched
> splice by broa= dcasting the old state and somehow convincing miners to
> confirm it = before the batched splice.

Correct, I didn't mention it in my po= st but batched splices cannot use
0-conf, the transaction must be confir= med to remove the risk of double
spends using commit txs associated with= the previous funding tx.

But interestingly, with the protocol I dra= fted, the LSP can finalize and
broadcast the batched splice transaction = while users are offline. With a
bit of luck, when the users reconnect, t= hat transaction will already be
confirmed so it will "feel 0-conf&q= uot;.

Also, we need a mechanism like the one you describe when we de= tect 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 s= ignatures, 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 channe= l is being spliced,
> it should not be spliced again, which your prop= osal seems to violate.

The spec doesn't require that, I'm no= t sure what made you think that.
While a channel is being spliced, it ca= n definitely be spliced again as
an RBF attempt (this is actually a very= important feature), which double
spends the other unconfirmed splice at= tempts.

ariard:

> It is uncertain to me if secure fee-bump= ing, even with future
> mechanisms like package relay and nversion=3D= 3, is robust enough for
> multi-party transactions and covenant-enabl= e constructions under usual
> risk models.

I'm not entirel= y sure why you're bringing this up in this context...
I agree that w= e 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 f= rom non-multi-party transactions here?

> See test here:
> <= a href=3D"https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c400= 5603f43d72f1efcf" target=3D"_blank">https://github.com/ariard/bitcoin/commi= t/19d61fa8cf22a5050b51c4005603f43d72f1efcf

I'd argue that th= is is quite different from the standard replacement
cycling attack, beca= use in this protocol wallet users can only
unilaterally double-spend wit= h a commit tx, on which they cannot set
the feerate. The only participan= t that can "easily" double-spend is
the exchange, and they wou= ldn't have an incentive to here, users are
only withdrawing funds, t= here's no opportunity of stealing funds?

Thanks,
Bastien
<= /div>
L= e=C2=A0mar. 17 oct. 2023 =C3=A0=C2=A021:10, Antoine Riard <antoine.riard@gmail.com= > a =C3=A9crit=C2=A0:
Hi Ba= stien,

> The naive way of enabling lightning withdraw= als is to make the user
> provide a lightning invoice that the exchan= ge pays over lightning. The
> issue is that in most cases, this simpl= y shifts the burden of making an
> on-chain transaction to the user&#= 39;s wallet provider: if the user doesn't
> have enough inbound l= iquidity (which is likely), a splice transaction
> will be necessary.= If N users withdraw funds from an exchange, we most
> likely will en= d up with N separate splice transactions.

It i= s uncertain to me if secure fee-bumping, even with future mechanisms like p= ackage relay and=C2=A0nversion=3D3, is robust enough for multi-party transa= ctions and covenant-enable constructions under usual risk models.

See test here:

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 the test is n= ormally built on glozow top commit of the 3 Oct 2023.

<= div>Best,
Antoine

Le=C2=A0mar. 17 oct. 2023 =C3=A0=C2=A014:0= 3, Bastien TEINTURIER <bastien@acinq.fr> a =C3=A9crit=C2=A0:
Good morning list,

I've been trying to design = a protocol to let users withdraw funds from
exchanges directly into thei= r lightning wallet in an efficient way
(with the smallest on-chain footp= rint possible).

I've come to the conclusion that this is only po= ssible 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 th= is usecase to the list of
useful things we could do if we had covenants = (insert "wen APO?" meme).

The naive way of enabling lightn= ing withdrawals is to make the user
provide a lightning invoice that the= exchange pays over lightning. The
issue is that in most cases, this sim= ply 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 w= ithdraw funds from an exchange, we most
likely will end up with N separa= te splice transactions.

Hence the idea of batching those into a sing= le transaction. Since we
don't want to introduce any intermediate tr= ansaction, we must be able
to create one transaction that splices multip= le channels at once. The
issue is that for each of these channels, we ne= ed a signature from the
corresponding wallet user, because we're spe= nding 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 availabil= ity problem: we need
signatures from N users who may not be online at th= e 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 `SI= GHASH_SINGLE | SIGHASH_ANYONECANPAY` that spends their current
funding o= utput to create a new funding output with the expected amount.
This lets= users sign *before* knowing the final transaction, which the
exchange c= an create by batching pairs of inputs/outputs. But this has
a fatal issu= e: 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 the= m to pay to get their funds back.

Lightning normally fixes this by e= xchanging signatures for a commitment
transaction that sends the funds b= ack to their owners *before* signing
the parent funding/splice transacti= on. 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 ab= le to sign before creating the batch)
so we don't know the new `prev= out` we should spend from. I couldn't find
a clever way to work arou= nd 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 sig= nature
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/ma= ilman/listinfo/lightning-dev
--000000000000bc09890608017642--