Anyone can boost - a more efficient alternative to anchor outputs

Anyone can boost - a more efficient alternative to anchor outputs
2024-03-19 14:10 ` 'Fabian' via Bitcoin Development Mailing List
  2024-03-19 14:24 ` Peter Todd
  
From: Martin Habovštiak @ 2024-03-19  9:47 UTC (permalink / raw)
  To: bitcoindev

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

Hello everyone,

For a while I was thinking that anchor outputs/CPFP are wasteful and I
believe I have finally found a better way of doing them. I wrote up a
document describing the solution here:
https://gist.github.com/Kixunil/6ae6f787db36d0d5ed3220f5bcece7f7

Here's a copy of the proposal for your convenience:

# Anyone can boost - a more efficient alternative to anchor outputs

## Abstract

Bitcoin protocols using presigned transactions (e.g. Lightning Network,
Firefish etc) face a problem with predicting fees of the presigned
transactions.
One possibility is to guess the future fee rate but that risks that the
transaction will not be included in a block fast enough and it also risks
wasting satoshis on fees.
Another possibility is to use CPFP which may require adding more outputs -
so called "anchor outputs".
The drawbacks of anchor outputs are increased transaction size and
potentially decreased privacy since the anchor outputs usually use
"suspiciously low" amounts.
Further, anchor outputs may pollute UTXO set if the presigned transaction
confirms anyway (because it also had high enough fee) but the outputs are
uneconomical to spend.
This document proposes a new solution that could not only solve these
issues but bring even more efficiency gains in the future.

## Solution

As stated in the abstract, anchor outputs increase the size and thus the
cost of transaction.
So starting from the ideal (no additional data in the boosted transaction),
we would like to boost any arbitrary transaction.
We observe that this is actually already possible by paying big mining
pools directly.
However this is detrimental to mining decentralization, not very accessible
to general public and the expected confirmation time is worse than in case
of CPFP, when the whole network mines the transaction.
A simple way to allow anyone boosting any transaction is to put the TXID of
the boosted transaction into the boosting transaction's annex and have a
consensus rule that the boosting transaction is only valid if the boosted
tranation is in the same block.
Let's call this "anyone can boost".

At first sight this looks broken because of the pinning problem.
Today, if ANYONECANSPEND output is used an attacker could boost a
transaction of someone else in a way that would make it stuck in the
mempool.
This is because of policy rules protecting the network against DoS attacks,
so apparently the rules cannot be relaxed.
The rules are designed specifically to impose cost on attackers.

The reason why anyone can boost is not actually broken is that multiple
independent transactions can boost the same transaction.
This brings another resource into the picture: new UTXOs.
Thus when a transaction is boosted and a new transaction appears that is
boosting it too, it can be considered by the anti-DoS rules separately.
An attacker can't use this to DoS the network because it requires having
multiple UTXOs which is already costly.
When a transaction is boosted by two transactions the fees simply add up.
It's also possible for a miner to ignore low-fee boosting transactions
(presumably created by an attacker) and only include the high fee ones.

In other words, adding the boosting transaction to the mempool is
equivalent to adding any other transaction to the mempool provided it pays
sufficient fee. It's just a bit larger and its fee rate is computed
differently.

## Efficient fee boosting service

A simplistic chain analysis would assume that the boosted and boosting
transactions are related because nobody would boost a transaction of
someone else.
This heuritic can be trivially broken by having an external service that
boosts arbitrary transactions and gets paid via other means (LN).
But this can be further improved by allowing boosting multiple transactions
simply by putting more TXIDs into the boosting transaction.
If two people are trying to boost two transactions at the same time they
can almost halve the cost of the boosting transaction.
An efficient boosting service would presumably collect orders and batch the
boosts. Further it could RBF the boosts if some didn't confirm yet and new
orders arrived in the meantime.
Because of significant cost reduction use of such services would be highly
incentivized undermining the heuristic.

Notably, such boosting service would *not* be trustless but non-delivery
could be easily proven using LN invoice and preimage.
Perhaps it is possible to make the service trustless but that's probably
not worth the effort given how low the amounts are.

As an aside, there was recently a post in the local community that someone
made a low-fee transaction without RBF enabled and the receiver couldn't
CPFP.
I assume such cases happen more than once.
If this service existed the transaction could've been trivially boosted by
anyone.

Another interesting example is someone saying that figuring out how to
boost a transaction took him a while. (IIRC it was an LN channel open.)
Having such service could greatly simplify fee boosting in many cases since
one would only have to copy-paste the txid, which probably all wallets
provide.

## Known downsides

### This requires a soft fork

Soft forks can be contentious and difficult to deploy.
This rule is also unusual because it causes interaction between transaction
within the same block.
However the code should be pretty simple: put all tx ids into a set and
then for each boosting transaction check that all of its txids are in the
set.
This allows loops but that shouldn't be a problem.
The loops can be also disabled by simply progressively iterating over
transactions and adding the txid to the set *after* its annexes were
checked.

It may be possible to relax the RBF rules in some other way to enable
external boosting for transactions that opt-into it. A vague idea was to
allow replacing when each input of a transaction has ANYONECANPAY flag but
its interaction with other rules is questionable. Perhaps this can be
developed further but not needing an additional output is both more
efficient and more user-friendly.

### This requires having a special output

Unfortunately annex cannot be added to any signature but only to script
spend taproot signatures.
Since this feature is most useful for presigned transactions the entities
performing them could simply prepare the outputs beforehand. (e.g. LN
implementations could make it built-in)
And for those who did not prepare the boosting services would provide an
option.

Future witness versions could be designed with this in mind and enable
annex regardless of spend type which would make things simpler and save
even more space (key spend is cheaper).

### This destroys fee betting

Currently it is possible for two people to bet on the height of the fees in
the future: they make a transaction that moves their satoshis into 2-of-2
multisig and then pre-sign two transactions with different fee rates and
lock times.
However this is already vulnerable to miner collusion and to my knowledge
nobody uses this.
It could be preserved by requiring that the boosted transactions opt-in to
boosting by using version 3 but that could decrease privacy and would
reintroduce potential for stuck transactions that cannot be boosted.

## Disclosure

I'm a contractor who wrote the core of Firefish smart contract, a protocol
which would benefit from this feature.
I was not paid to come up with this idea, I just believe this would be a
generally useful feature.

-- 


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

 permalink raw reply	[|nested]
2024-03-19  9:47 [bitcoindev] Anyone can boost - a more efficient alternative to anchor outputs Martin Habovštiak

  2024-03-19 14:24 ` Peter Todd
  
From: 'Fabian' via Bitcoin Development Mailing List @ 2024-03-19 14:10 UTC (permalink / raw)
  To: Martin Habovštiak;  bitcoindev

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

Hello Martin,

at first glance your idea sounds fairly similar to Jeremy Rubin's transactions sponsoring from 2020, though he proposed a different structure for referencing the sponsored transaction and not the annex [0]. The concept was discussed further discussed in a long mailing list thread in 2022 [1].

Whether your idea is indeed similar or if there are substantial differences that I have missed, I think it would be interesting if you could reference the prior suggestions and contrast them to your solution, i.e. explicitly tell us what makes your proposal a better idea. Thanks a lot!

Best,
Fabian

[0]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2020-September/018168.html
[1]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019879.html
On Tuesday, March 19th, 2024 at 10:47 AM, Martin Habovštiak <martin.habovstiak@gmail•com> wrote:

> Hello everyone,
>
> For a while I was thinking that anchor outputs/CPFP are wasteful and I believe I have finally found a better way of doing them. I wrote up a document describing the solution here: https://gist.github.com/Kixunil/6ae6f787db36d0d5ed3220f5bcece7f7
>
> Here's a copy of the proposal for your convenience:
>
> # Anyone can boost - a more efficient alternative to anchor outputs
>
> ## Abstract
>
> Bitcoin protocols using presigned transactions (e.g. Lightning Network, Firefish etc) face a problem with predicting fees of the presigned transactions.
> One possibility is to guess the future fee rate but that risks that the transaction will not be included in a block fast enough and it also risks wasting satoshis on fees.
> Another possibility is to use CPFP which may require adding more outputs - so called "anchor outputs".
> The drawbacks of anchor outputs are increased transaction size and potentially decreased privacy since the anchor outputs usually use "suspiciously low" amounts.
> Further, anchor outputs may pollute UTXO set if the presigned transaction confirms anyway (because it also had high enough fee) but the outputs are uneconomical to spend.
> This document proposes a new solution that could not only solve these issues but bring even more efficiency gains in the future.
>
> ## Solution
>
> As stated in the abstract, anchor outputs increase the size and thus the cost of transaction.
> So starting from the ideal (no additional data in the boosted transaction), we would like to boost any arbitrary transaction.
> We observe that this is actually already possible by paying big mining pools directly.
> However this is detrimental to mining decentralization, not very accessible to general public and the expected confirmation time is worse than in case of CPFP, when the whole network mines the transaction.
> A simple way to allow anyone boosting any transaction is to put the TXID of the boosted transaction into the boosting transaction's annex and have a consensus rule that the boosting transaction is only valid if the boosted tranation is in the same block.
> Let's call this "anyone can boost".
>
> At first sight this looks broken because of the pinning problem.
> Today, if ANYONECANSPEND output is used an attacker could boost a transaction of someone else in a way that would make it stuck in the mempool.
> This is because of policy rules protecting the network against DoS attacks, so apparently the rules cannot be relaxed.
> The rules are designed specifically to impose cost on attackers.
>
> The reason why anyone can boost is not actually broken is that multiple independent transactions can boost the same transaction.
> This brings another resource into the picture: new UTXOs.
> Thus when a transaction is boosted and a new transaction appears that is boosting it too, it can be considered by the anti-DoS rules separately.
> An attacker can't use this to DoS the network because it requires having multiple UTXOs which is already costly.
> When a transaction is boosted by two transactions the fees simply add up.
> It's also possible for a miner to ignore low-fee boosting transactions (presumably created by an attacker) and only include the high fee ones.
>
> In other words, adding the boosting transaction to the mempool is equivalent to adding any other transaction to the mempool provided it pays sufficient fee. It's just a bit larger and its fee rate is computed differently.
>
> ## Efficient fee boosting service
>
> A simplistic chain analysis would assume that the boosted and boosting transactions are related because nobody would boost a transaction of someone else.
> This heuritic can be trivially broken by having an external service that boosts arbitrary transactions and gets paid via other means (LN).
> But this can be further improved by allowing boosting multiple transactions simply by putting more TXIDs into the boosting transaction.
> If two people are trying to boost two transactions at the same time they can almost halve the cost of the boosting transaction.
> An efficient boosting service would presumably collect orders and batch the boosts. Further it could RBF the boosts if some didn't confirm yet and new orders arrived in the meantime.
> Because of significant cost reduction use of such services would be highly incentivized undermining the heuristic.
>
> Notably, such boosting service would *not* be trustless but non-delivery could be easily proven using LN invoice and preimage.
> Perhaps it is possible to make the service trustless but that's probably not worth the effort given how low the amounts are.
>
> As an aside, there was recently a post in the local community that someone made a low-fee transaction without RBF enabled and the receiver couldn't CPFP.
> I assume such cases happen more than once.
> If this service existed the transaction could've been trivially boosted by anyone.
>
> Another interesting example is someone saying that figuring out how to boost a transaction took him a while. (IIRC it was an LN channel open.) Having such service could greatly simplify fee boosting in many cases since one would only have to copy-paste the txid, which probably all wallets provide.
>
> ## Known downsides
>
> ### This requires a soft fork
>
> Soft forks can be contentious and difficult to deploy.
> This rule is also unusual because it causes interaction between transaction within the same block.
> However the code should be pretty simple: put all tx ids into a set and then for each boosting transaction check that all of its txids are in the set.
> This allows loops but that shouldn't be a problem.
> The loops can be also disabled by simply progressively iterating over transactions and adding the txid to the set *after* its annexes were checked.
>
> It may be possible to relax the RBF rules in some other way to enable external boosting for transactions that opt-into it. A vague idea was to allow replacing when each input of a transaction has ANYONECANPAY flag but its interaction with other rules is questionable. Perhaps this can be developed further but not needing an additional output is both more efficient and more user-friendly.
>
> ### This requires having a special output
>
> Unfortunately annex cannot be added to any signature but only to script spend taproot signatures.
> Since this feature is most useful for presigned transactions the entities performing them could simply prepare the outputs beforehand. (e.g. LN implementations could make it built-in)
> And for those who did not prepare the boosting services would provide an option.
>
> Future witness versions could be designed with this in mind and enable annex regardless of spend type which would make things simpler and save even more space (key spend is cheaper).
>
> ### This destroys fee betting
>
> Currently it is possible for two people to bet on the height of the fees in the future: they make a transaction that moves their satoshis into 2-of-2 multisig and then pre-sign two transactions with different fee rates and lock times.
> However this is already vulnerable to miner collusion and to my knowledge nobody uses this.
> It could be preserved by requiring that the boosted transactions opt-in to boosting by using version 3 but that could decrease privacy and would reintroduce potential for stuck transactions that cannot be boosted.
>
> ## Disclosure
>
> I'm a contractor who wrote the core of Firefish smart contract, a protocol which would benefit from this feature.
> I was not paid to come up with this idea, I just believe this would be a generally useful feature.
>
> --
> 

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

 permalink raw reply	[|nested]
2024-03-19  9:47 [bitcoindev] Anyone can boost - a more efficient alternative to anchor outputs Martin Habovštiak
  2024-03-19 14:10 ` 'Fabian' via Bitcoin Development Mailing List

  2024-03-25  1:36   ` David A. Harding
  
From: Peter Todd @ 2024-03-19 14:24 UTC (permalink / raw)
  To: Martin Habovštiak;  bitcoindev

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

On Tue, Mar 19, 2024 at 10:47:26AM +0100, Martin Habovštiak wrote:
> Hello everyone,
> 
> For a while I was thinking that anchor outputs/CPFP are wasteful and I
> believe I have finally found a better way of doing them. I wrote up a
> document describing the solution here:
> https://gist.github.com/Kixunil/6ae6f787db36d0d5ed3220f5bcece7f7

FYI I believe that Jeremy Rubin proposed essentially the same idea before on
this mailing list, using the term "Transaction Sponsorship" to describe it.

> At first sight this looks broken because of the pinning problem.
> Today, if ANYONECANSPEND output is used an attacker could boost a
> transaction of someone else in a way that would make it stuck in the
> mempool.

To be clear, this issue exists because we don't currently do
replace-by-fee-rate with a reasonably low minimum fee-rate ratio.

Correct me if I'm wrong, but I believe at the moment the only significant
transaction pinning attack remaining for ANYONECANSPEND, spending confirmed
outputs, is Rule #3 pinning.

> This is because of policy rules protecting the network against DoS attacks,
> so apparently the rules cannot be relaxed.
> The rules are designed specifically to impose cost on attackers.

I disagree re: DoS attacks. We already have plenty of free-relay attacks. RBFR
does not significantly change that situation.

RBFR is running live right now on Libre Relay nodes on mainnet. If these
free-relay attacks were actually serious, I'd suggest that people demonstrate
them!

> The reason why anyone can boost is not actually broken is that multiple
> independent transactions can boost the same transaction.

Note that introducing this mechanism with a soft-fork will also create entirely
new smart contracting facilities, unrelated to boosting/sponsorship.

For example, I believe that Ark could make use of this mechanism to more
efficiently replace their connector output scheme.

> Notably, such boosting service would *not* be trustless but non-delivery
> could be easily proven using LN invoice and preimage.
> Perhaps it is possible to make the service trustless but that's probably
> not worth the effort given how low the amounts are.

To reduce trust you could do an automated, multiple round, signing scheme where
the service signs transations with higher and higher fee-rates in exchange for
most funds over LN. The minimum amount the sender would need to front would be
the cost of the additional ~32 bytes required. Though arranging this idea with
multiple people at once could be tricky.

> ## Known downsides
> 
> ### This requires a soft fork
> 
> Soft forks can be contentious and difficult to deploy.

I'd suggest you find other use-cases for this mechanism, eg Ark, and present it
as a solution to a bunch of problems at once. I'm not sure that the fee payment
alone is sufficient incentive.

You don't mention it below. But another downside is you provide an easy way for
arbitrary third parties to get a particular transaction mined. I raised this
issue the last time it was discussed on this list, giving the example of my
OpenTimestamps calendars: it would be annoying if people could easily get
out-of-date timestamp txs mined by just paying a bit of money. While this is
always *possible*, implementing a mechanism that makes doing this easy has
downsides. On balance though, if it enables things like Ark, you'll help make
the argument that the upsides are worth it.

-- 
https://petertodd.org 'peter'[:-1]@petertodd.org

-- 
asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

 permalink raw reply	[|nested]
2024-03-19 14:24 ` Peter Todd

  2024-03-27 12:20     ` Peter Todd
  
From: David A. Harding @ 2024-03-25  1:36 UTC (permalink / raw)
  To: Peter Todd;  Martin Habovštiak, bitcoindev

On 2024-03-19 04:24, Peter Todd wrote:
> To reduce trust you could do an automated, multiple round, signing 
> scheme where
> the service signs transations with higher and higher fee-rates in 
> exchange for
> most funds over LN.

When the service thinks the user has paid all that they're going to pay, 
what stops them from replacing their transaction one more time with a 
version that does not sponsor the user's transaction?  Also, what stops 
the service from selling the same space in a sponsor transaction to 
multiple users at once, e.g. customers Alice and Bob each iterate with 
the service many times until they get a sponsor with as much fee as they 
want, but when they go to broadcast, they discover that their 
transactions conflict, so one of them paid for nothing?

I had thought about using a simple pay-for-signature scheme using 
signature adaptors and a hoped-for LN that supports PTLCs, but I think 
it suffers from the same problems.  I haven't been able to think of a 
way to significantly reduce trust for outsourced sponsorship without 
also significantly reducing the efficiency of sponsor transactions.

-Dave

P.S. related discussion about efficient sponsors may be found in this 
thread: 
https://delvingbitcoin.org/t/improving-transaction-sponsor-blockspace-efficiency/696

-- 



 permalink raw reply	[|nested]
2024-03-25  1:36   ` David A. Harding

  
From: Peter Todd @ 2024-03-27 12:20 UTC (permalink / raw)
  To: David A. Harding;  Martin Habovštiak, bitcoindev

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

On Sun, Mar 24, 2024 at 03:36:30PM -1000, David A. Harding wrote:
> On 2024-03-19 04:24, Peter Todd wrote:
> > To reduce trust you could do an automated, multiple round, signing
> > scheme where
> > the service signs transations with higher and higher fee-rates in
> > exchange for
> > most funds over LN.
> 
> When the service thinks the user has paid all that they're going to pay,
> what stops them from replacing their transaction one more time with a
> version that does not sponsor the user's transaction?

That at least is mitigated a bit by the fact that the earlier versions existed
and were valid; it's still a potentially useful reduction in trust as the
service needs to be able to do something economically useful with the high-fee
transaction for it to be a profitable attack.

As I said, I'm suggesting a way to reduce trust. Not eliminate it.

> Also, what stops the
> service from selling the same space in a sponsor transaction to multiple
> users at once, e.g. customers Alice and Bob each iterate with the service
> many times until they get a sponsor with as much fee as they want, but when
> they go to broadcast, they discover that their transactions conflict, so one
> of them paid for nothing?

That might actually be a weaker attack than the first: you can watch a mempool,
unknown to the service, to see if you recieve the transaction you paid for. If
you don't, there's a reasonable chance they're trying to rip you off.

-- 
https://petertodd.org 'peter'[:-1]@petertodd.org

-- 
asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

 permalink raw reply	[|nested]