public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
* [bitcoin-dev] Batch exchange withdrawal to lightning requires covenants
@ 2023-10-17 13:03 Bastien TEINTURIER
  2023-10-17 17:04 ` ZmnSCPxj
  2023-10-17 19:10 ` [bitcoin-dev] [Lightning-dev] " Antoine Riard
  0 siblings, 2 replies; 9+ messages in thread
From: Bastien TEINTURIER @ 2023-10-17 13:03 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion, lightning-dev\\@lists.linuxfoundation.org

[-- Attachment #1: Type: text/plain, Size: 3249 bytes --]

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

[-- Attachment #2: Type: text/html, Size: 3514 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [bitcoin-dev] Batch exchange withdrawal to lightning requires covenants
  2023-10-17 13:03 [bitcoin-dev] Batch exchange withdrawal to lightning requires covenants Bastien TEINTURIER
@ 2023-10-17 17:04 ` ZmnSCPxj
  2023-10-17 17:10   ` Greg Sanders
  2023-10-17 19:10 ` [bitcoin-dev] [Lightning-dev] " Antoine Riard
  1 sibling, 1 reply; 9+ messages in thread
From: ZmnSCPxj @ 2023-10-17 17:04 UTC (permalink / raw)
  To: Bastien TEINTURIER
  Cc: Bitcoin Protocol Discussion, lightning-dev\\\\@lists.linuxfoundation.org

Good morning Bastien,

I have not gotten around to posting it yet, but I have a write-up in my computer with the title:

> Batched Splicing Considered Risky

The core of the risk is that if:

* I have no funds right now in a channel (e.g. the LSP allowed me to have 0 reserve, or this is a newly-singlefunded channel from the LSP to me).
* I have an old state (e.g. for a newly-singlefunded channel, it could have been `update_fee`d, so that the initial transaction is old state).

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.

Thus, it is important for *any* batched splicing mechanism to have a backout, where if the batched splice transaction can no longer be confirmed due to some participant disrupting it by posting an old commitment transaction, either a subset of the splice is re-created or the channels revert back to pre-splice state (with knowledge that the post-splice state can no longer be confirmed).

I know that current splicing tech is to run both the pre-splice and post-splice state simultaneously until the splicing transaction is confirmed.
However we need to *also* check if the splicing transaction *cannot* be confirmed --- by checking if the other inputs to the splice transaction were already consumed by transactions that have deeply confirmed, and in that case, to drop the post-splice state and revert to the pre-splice state.
I do not know if existing splice implementations actually perform such a check.
Unless all splice implementations do this, then any kind of batched splicing is risky.

Regards,
ZmnSCPxj



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [bitcoin-dev] Batch exchange withdrawal to lightning requires covenants
  2023-10-17 17:04 ` ZmnSCPxj
@ 2023-10-17 17:10   ` Greg Sanders
  2023-10-17 17:17     ` ZmnSCPxj
  0 siblings, 1 reply; 9+ messages in thread
From: Greg Sanders @ 2023-10-17 17:10 UTC (permalink / raw)
  To: ZmnSCPxj, Bitcoin Protocol Discussion
  Cc: lightning-dev\\\\@lists.linuxfoundation.org

[-- Attachment #1: Type: text/plain, Size: 2454 bytes --]

> I do not know if existing splice implementations actually perform such a
check.
Unless all splice implementations do this, then any kind of batched
splicing is risky.

As long as the implementation decides to splice again at some point when a
prior
splice isn't confirming, it will self-resolve once any subsequent splice is
confirmed.

Cheers,
Greg

On Tue, Oct 17, 2023 at 1:04 PM ZmnSCPxj via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> Good morning Bastien,
>
> I have not gotten around to posting it yet, but I have a write-up in my
> computer with the title:
>
> > Batched Splicing Considered Risky
>
> The core of the risk is that if:
>
> * I have no funds right now in a channel (e.g. the LSP allowed me to have
> 0 reserve, or this is a newly-singlefunded channel from the LSP to me).
> * I have an old state (e.g. for a newly-singlefunded channel, it could
> have been `update_fee`d, so that the initial transaction is old state).
>
> 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.
>
> Thus, it is important for *any* batched splicing mechanism to have a
> backout, where if the batched splice transaction can no longer be confirmed
> due to some participant disrupting it by posting an old commitment
> transaction, either a subset of the splice is re-created or the channels
> revert back to pre-splice state (with knowledge that the post-splice state
> can no longer be confirmed).
>
> I know that current splicing tech is to run both the pre-splice and
> post-splice state simultaneously until the splicing transaction is
> confirmed.
> However we need to *also* check if the splicing transaction *cannot* be
> confirmed --- by checking if the other inputs to the splice transaction
> were already consumed by transactions that have deeply confirmed, and in
> that case, to drop the post-splice state and revert to the pre-splice state.
> I do not know if existing splice implementations actually perform such a
> check.
> Unless all splice implementations do this, then any kind of batched
> splicing is risky.
>
> Regards,
> ZmnSCPxj
>
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 3009 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [bitcoin-dev] Batch exchange withdrawal to lightning requires covenants
  2023-10-17 17:10   ` Greg Sanders
@ 2023-10-17 17:17     ` ZmnSCPxj
  0 siblings, 0 replies; 9+ messages in thread
From: ZmnSCPxj @ 2023-10-17 17:17 UTC (permalink / raw)
  To: Greg Sanders
  Cc: Bitcoin Protocol Discussion,
	lightning-dev\\\\\\\\@lists.linuxfoundation.org


Good morning Greg,


> > I do not know if existing splice implementations actually perform such a check.
> Unless all splice implementations do this, then any kind of batched splicing is risky.
> As long as the implementation decides to splice again at some point when a prior
> splice isn't confirming, it will self-resolve once any subsequent splice is confirmed.

Do note that there is a risk here that the reason for "not confirming" is because of an unexpected increase in mempool usage.

In particular, if the attack is not being performed, it is possible for the previous splice tx that was not confirming for a while, to be the one that confirms in the end, instead of the subsequent splice.
This is admittedly an edge case, but one that could potentially be specifically attacked and could lead to loss of funds if the implementations naively deleted the signatures for commitment transactions for the previously-not-confirming splice transaction.

Indeed, as I understood it, 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.

Regards,
ZmnSCPxj


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [bitcoin-dev] [Lightning-dev] Batch exchange withdrawal to lightning requires covenants
  2023-10-17 13:03 [bitcoin-dev] Batch exchange withdrawal to lightning requires covenants Bastien TEINTURIER
  2023-10-17 17:04 ` ZmnSCPxj
@ 2023-10-17 19:10 ` Antoine Riard
  2023-10-18 14:35   ` Bastien TEINTURIER
  1 sibling, 1 reply; 9+ messages in thread
From: Antoine Riard @ 2023-10-17 19:10 UTC (permalink / raw)
  To: Bastien TEINTURIER
  Cc: Bitcoin Protocol Discussion, lightning-dev\\@lists.linuxfoundation.org

[-- Attachment #1: Type: text/plain, Size: 4784 bytes --]

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=3, is robust enough for multi-party
transactions and covenant-enable constructions under usual risk models.

See test here:
https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72f1efcf

Appreciated expert eyes of folks understanding both lightning and core
mempool on this.
There was a lot of back and forth on nversion=3 design rules, though the
test is normally built on glozow top commit of the 3 Oct 2023.

Best,
Antoine

Le mar. 17 oct. 2023 à 14:03, Bastien TEINTURIER <bastien@acinq•fr> a
écrit :

> 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
>

[-- Attachment #2: Type: text/html, Size: 5667 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [bitcoin-dev] [Lightning-dev] Batch exchange withdrawal to lightning requires covenants
  2023-10-17 19:10 ` [bitcoin-dev] [Lightning-dev] " Antoine Riard
@ 2023-10-18 14:35   ` Bastien TEINTURIER
  2023-10-18 18:03     ` Antoine Riard
  0 siblings, 1 reply; 9+ messages in thread
From: Bastien TEINTURIER @ 2023-10-18 14:35 UTC (permalink / raw)
  To: Antoine Riard
  Cc: Bitcoin Protocol Discussion, lightning-dev\\@lists.linuxfoundation.org

[-- Attachment #1: Type: text/plain, Size: 7704 bytes --]

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=3, 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/19d61fa8cf22a5050b51c4005603f43d72f1efcf

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 à 21:10, Antoine Riard <antoine.riard@gmail•com> a
écrit :

> 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=3, is robust enough for multi-party
> transactions and covenant-enable constructions under usual risk models.
>
> See test here:
>
> https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72f1efcf
>
> Appreciated expert eyes of folks understanding both lightning and core
> mempool on this.
> There was a lot of back and forth on nversion=3 design rules, though the
> test is normally built on glozow top commit of the 3 Oct 2023.
>
> Best,
> Antoine
>
> Le mar. 17 oct. 2023 à 14:03, Bastien TEINTURIER <bastien@acinq•fr> a
> écrit :
>
>> 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
>>
>

[-- Attachment #2: Type: text/html, Size: 9046 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [bitcoin-dev] [Lightning-dev] Batch exchange withdrawal to lightning requires covenants
  2023-10-18 14:35   ` Bastien TEINTURIER
@ 2023-10-18 18:03     ` Antoine Riard
  2023-10-19  7:35       ` Bastien TEINTURIER
  0 siblings, 1 reply; 9+ messages in thread
From: Antoine Riard @ 2023-10-18 18:03 UTC (permalink / raw)
  To: Bastien TEINTURIER
  Cc: Bitcoin Protocol Discussion, lightning-dev\\@lists.linuxfoundation.org

[-- Attachment #1: Type: text/plain, Size: 9304 bytes --]

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=3
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/19d61fa8cf22a5050b51c4005603f43d72f1efcf

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 à 15:35, Bastien TEINTURIER <bastien@acinq•fr> a
écrit :

> 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=3, 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/19d61fa8cf22a5050b51c4005603f43d72f1efcf
>
> 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 à 21:10, Antoine Riard <antoine.riard@gmail•com> a
> écrit :
>
>> 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=3, is robust enough for multi-party
>> transactions and covenant-enable constructions under usual risk models.
>>
>> See test here:
>>
>> https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72f1efcf
>>
>> Appreciated expert eyes of folks understanding both lightning and core
>> mempool on this.
>> There was a lot of back and forth on nversion=3 design rules, though the
>> test is normally built on glozow top commit of the 3 Oct 2023.
>>
>> Best,
>> Antoine
>>
>> Le mar. 17 oct. 2023 à 14:03, Bastien TEINTURIER <bastien@acinq•fr> a
>> écrit :
>>
>>> 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
>>>
>>

[-- Attachment #2: Type: text/html, Size: 11166 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [bitcoin-dev] [Lightning-dev] Batch exchange withdrawal to lightning requires covenants
  2023-10-18 18:03     ` Antoine Riard
@ 2023-10-19  7:35       ` Bastien TEINTURIER
  2023-10-19 17:09         ` Antoine Riard
  0 siblings, 1 reply; 9+ messages in thread
From: Bastien TEINTURIER @ 2023-10-19  7:35 UTC (permalink / raw)
  To: Antoine Riard
  Cc: Bitcoin Protocol Discussion, lightning-dev\\@lists.linuxfoundation.org

[-- Attachment #1: Type: text/plain, Size: 10735 bytes --]

Hi Antoine,

> 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.

Yes, they can, and any user could also double-spend the batch using a
commit tx spending from the previous funding output. Participants must
expect that this may happen, that's what I mentioned previously that
you cannot use 0-conf on that splice transaction. But apart from that,
it acts as a regular splice: participants must watch for double-spends
(as discussed in the previous messages) while waiting for confirmations.

> If the batch withdrawal has been signed with 0-fee thanks to the
> nversion=3 policy exemption, it will be evicted out of the mempool.
> A variant of a replacement cycling attack.

I don't think this should use nVersion=3 and pay 0 fees. On the contrary
this is a "standard" transaction that should use a reasonable feerate
and nVersion=2, that's why I don't think this comment applies.

Cheers,
Bastien

Le mer. 18 oct. 2023 à 20:04, Antoine Riard <antoine.riard@gmail•com> a
écrit :

> 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=3 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/19d61fa8cf22a5050b51c4005603f43d72f1efcf
>
> 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 à 15:35, Bastien TEINTURIER <bastien@acinq•fr> a
> écrit :
>
>> 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=3, 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/19d61fa8cf22a5050b51c4005603f43d72f1efcf
>>
>> 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 à 21:10, Antoine Riard <antoine.riard@gmail•com> a
>> écrit :
>>
>>> 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=3, is robust enough for multi-party
>>> transactions and covenant-enable constructions under usual risk models.
>>>
>>> See test here:
>>>
>>> https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72f1efcf
>>>
>>> Appreciated expert eyes of folks understanding both lightning and core
>>> mempool on this.
>>> There was a lot of back and forth on nversion=3 design rules, though the
>>> test is normally built on glozow top commit of the 3 Oct 2023.
>>>
>>> Best,
>>> Antoine
>>>
>>> Le mar. 17 oct. 2023 à 14:03, Bastien TEINTURIER <bastien@acinq•fr> a
>>> écrit :
>>>
>>>> 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
>>>>
>>>

[-- Attachment #2: Type: text/html, Size: 12664 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [bitcoin-dev] [Lightning-dev] Batch exchange withdrawal to lightning requires covenants
  2023-10-19  7:35       ` Bastien TEINTURIER
@ 2023-10-19 17:09         ` Antoine Riard
  0 siblings, 0 replies; 9+ messages in thread
From: Antoine Riard @ 2023-10-19 17:09 UTC (permalink / raw)
  To: Bastien TEINTURIER
  Cc: Bitcoin Protocol Discussion, lightning-dev\\@lists.linuxfoundation.org

[-- Attachment #1: Type: text/plain, Size: 12666 bytes --]

Hi Bastien,

Thanks for your additional comments.

> Yes, they can, and any user could also double-spend the batch using a
> commit tx spending from the previous funding output. Participants must
> expect that this may happen, that's what I mentioned previously that
> you cannot use 0-conf on that splice transaction. But apart from that,
> it acts as a regular splice: participants must watch for double-spends
> (as discussed in the previous messages) while waiting for confirmations.

Understood better, it's like a regular splice where one participant might
be able to double-spend at any time with a previous commit tx. So yes,
usual liquidity griefing we're already aware of I think and where one
should wait for a few confirmations before using spawned channels.

> I don't think this should use nVersion=3 and pay 0 fees. On the contrary
> this is a "standard" transaction that should use a reasonable feerate
> and nVersion=2, that's why I don't think this comment applies.

Under this model where the splice should be a "standard" nVersion=2
transaction that is using a reasonable feerate for non-delayed broadcast,
yes my comment does not apply, agree here.

However for a hypothetical future, where the picked up feerate of the batch
splicing isn't compelling enough in face of mempool spikes, interactivity
to re-generate a bumped RBF might not be an option. Sadly re-broadcasting
the batch splice tx package with a bumped CPFP, might be affected by my
concern if it is correct. To be verified.

Best,
Antoine

Le jeu. 19 oct. 2023 à 08:35, Bastien TEINTURIER <bastien@acinq•fr> a
écrit :

> Hi Antoine,
>
> > 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.
>
> Yes, they can, and any user could also double-spend the batch using a
> commit tx spending from the previous funding output. Participants must
> expect that this may happen, that's what I mentioned previously that
> you cannot use 0-conf on that splice transaction. But apart from that,
> it acts as a regular splice: participants must watch for double-spends
> (as discussed in the previous messages) while waiting for confirmations.
>
> > If the batch withdrawal has been signed with 0-fee thanks to the
> > nversion=3 policy exemption, it will be evicted out of the mempool.
> > A variant of a replacement cycling attack.
>
> I don't think this should use nVersion=3 and pay 0 fees. On the contrary
> this is a "standard" transaction that should use a reasonable feerate
> and nVersion=2, that's why I don't think this comment applies.
>
> Cheers,
> Bastien
>
> Le mer. 18 oct. 2023 à 20:04, Antoine Riard <antoine.riard@gmail•com> a
> écrit :
>
>> 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=3 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/19d61fa8cf22a5050b51c4005603f43d72f1efcf
>>
>> 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 à 15:35, Bastien TEINTURIER <bastien@acinq•fr> a
>> écrit :
>>
>>> 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=3, 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/19d61fa8cf22a5050b51c4005603f43d72f1efcf
>>>
>>> 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 à 21:10, Antoine Riard <antoine.riard@gmail•com> a
>>> écrit :
>>>
>>>> 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=3, is robust enough for
>>>> multi-party transactions and covenant-enable constructions under usual risk
>>>> models.
>>>>
>>>> See test here:
>>>>
>>>> https://github.com/ariard/bitcoin/commit/19d61fa8cf22a5050b51c4005603f43d72f1efcf
>>>>
>>>> Appreciated expert eyes of folks understanding both lightning and core
>>>> mempool on this.
>>>> There was a lot of back and forth on nversion=3 design rules, though
>>>> the test is normally built on glozow top commit of the 3 Oct 2023.
>>>>
>>>> Best,
>>>> Antoine
>>>>
>>>> Le mar. 17 oct. 2023 à 14:03, Bastien TEINTURIER <bastien@acinq•fr> a
>>>> écrit :
>>>>
>>>>> 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
>>>>>
>>>>

[-- Attachment #2: Type: text/html, Size: 15058 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-10-19 17:10 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-17 13:03 [bitcoin-dev] Batch exchange withdrawal to lightning requires covenants Bastien TEINTURIER
2023-10-17 17:04 ` ZmnSCPxj
2023-10-17 17:10   ` Greg Sanders
2023-10-17 17:17     ` ZmnSCPxj
2023-10-17 19:10 ` [bitcoin-dev] [Lightning-dev] " Antoine Riard
2023-10-18 14:35   ` Bastien TEINTURIER
2023-10-18 18:03     ` Antoine Riard
2023-10-19  7:35       ` Bastien TEINTURIER
2023-10-19 17:09         ` Antoine Riard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox