Subject: [bitcoindev] Anyone can boost - a more efficient alternative to anchor outputs

From: Martin Habovštiak <[email-masked]>
Date: Tue, 19 Mar 2024 10:47:26 +0100

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.

-- 
You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email-masked].
To view this discussion on the web visit https://groups.google.com/d/msgid/bitcoindev/CALkkCJZWBTmWX_K0%2BERTs2_r0w8nVK1uN44u-sz5Hbb-SbjVYw%40mail.gmail.com.