<p>TL;DR: Due to the two asymmetric sets of rules for replacement, a total of five transactions is sufficient to make a cycle of replacements that beat each other in turn. This allows an attacker to rebroadcast the same transactions over and over while at most paying for one small transaction per block.</p>
<hr />
<p><em>In all of the graphics an arrow points from child to parent, while a dotted line with a socket and ball points from original to replacement with socket and ball at the side of the replacement. A socket without ball (see Step 4) indicates an indirect conflict with the socket on the side of the replacement.</em></p>
<p>You have three confirmed UTXOs <code>c1</code>, <code>c2</code> and <code>c3</code>. Let’s say 20 s/vB is the bottom of the first block.</p>
<ol>
<li>You create <code>tx_LL</code>, a large low-feerate transaction with 100,000 vB at 1 s/vB (fee: 100,000 s). It spends the confirmed output <code>c1</code> and has an output <code>tx_LL:0</code>.</li>
<li>You attach a small low-feerate transaction <code>tx_LS</code> as a child with 100 vB at 1 s/vB (fee: 100 s) by spending <code>tx_LL:0</code>.</li>
</ol>
<p><a href="https://i.sstatic.net/ofXVo.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ofXVo.png" alt="RBFr LL_LS.png" /></a></p>
<ol start="3">
<li>You replace <code>tx_LS</code> with <code>tx_HS</code> a high-feerate transaction that spends <code>c2</code> and <code>tx_LL:0</code>. <code>tx_HS</code> has 5000 vB and pays 21 s/vB, but since it spends an output of a low-feerate parent, its mining score is only 1.95 s/vB.</li>
</ol>
<p><a href="https://i.sstatic.net/5ZTp7.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/5ZTp7.png" alt="RBFr LL_HS.png" /></a></p>
<ol start="4">
<li>You replace <code>tx_LL</code> with <code>tx_LM</code> that has 100,000 vB and pays 3.05 s/vB (fee: 305,000 s) by spending the outputs <code>c1</code> and <code>c3</code>. <code>tx_LM</code> also indirectly replaces <code>tx_HS</code> even while <code>tx_HS</code> has a higher individual feerate. This is permitted, since <code>tx_LM</code> pays a higher total fee than the replaced transactions and because it only conflicts directly with <code>tx_LL</code> it only has to beat the feerate of <code>tx_LL</code> but not the feerate of <code>tx_HS</code>.</li>
</ol>
<p><a href="https://i.sstatic.net/VabZL.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/VabZL.png" alt="RBFr LM.png" /></a></p>
<ol start="5">
<li>You use the new RBFr rules to replace <code>tx_LM</code> with a small high feerate transaction <code>tx_RBFr</code> with 200 vB paying 20 s/vB (fee: 4000 s) that spends <code>c3</code> and makes it into the top block of the mempool. <code>tx_LM</code> was not going to be in the next block, and <code>tx_RBFr</code> pays more than 1.25× the feerate of <code>tx_LM</code>. So this is permitted under the new rules.</li>
</ol>
<p><a href="https://i.sstatic.net/XYetF.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/XYetF.png" alt="RBFr RBFr.png" /></a></p>
<ol start="6">
<li>As no transaction in the mempool spends <code>c1</code>, you then rebroadcast <code>tx_LL</code> and <code>tx_LS</code>.</li>
</ol>
<p><a href="https://i.sstatic.net/bdp1R.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/bdp1R.png" alt="RBFr rebroadcast LL_LS.png" /></a></p>
<ol start="7">
<li>You immediately replace both <code>tx_LS</code> and <code>tx_RBFr</code> with <code>tx_HS</code>. <code>tx_HS</code> has a feerate of 21 s/vB which is higher than <code>tx_RBFr</code> (20 s/vB) and <code>tx_LS</code> (1 s/vB), and pays more absolute fees than both (105,000 s vs 2000 s + 100 s). But since it’s a child of <code>tx_LL</code> it only has a mining score of 1.95 s/vB.</li>
</ol>
<p><a href="https://i.sstatic.net/hhuSC.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/hhuSC.png" alt="RBFr HS.png" /></a></p>
<p>Repeat 4.–7. to make every node on the network cycle the same five transactions ad nauseam. Roll the locktimes or sequences to make the transaction have a new TXIDs in each iteration, while spending the same UTXOs. The only transaction that is ever in any danger of getting mined is <code>tx_RBFr</code> which costs you 4000 sats. If it it does get included in a block, just start over with two new confirmed UTXOs as your <code>c2'</code> and <code>c3'</code>.</p>

CC BY-SA 4.0
2024-01-22T16:57:38.553Z
2024-01-29T21:09:08.467Z
2024-01-29T21:09:08.467Z
Murch
<p>There recently was a proposal to allow replacements that <a href="https://petertodd.org/2024/one-shot-replace-by-fee-rate" rel="nofollow noreferrer">only beat the original by feerate, instead of by both the feerate and absolute fee</a>.</p>
<blockquote>
<h1>One-Shot Replace-by-Fee-Rate</h1>
<p>We can mitigate Rule #3 transaction pinning in a miner-incentive
compatible way by replacing transactions (or alternatively,
transaction packages) that do not qualify for replacement based on the
existing rules, if they qualify under these alternative rules:</p>
<ol>
<li>The new transaction (package) has a fee-rate more than <em>r</em> times higher than the fee-rate of the transactions it replaces.</li>
<li>The new transaction (package) has a sufficiently high fee-rate to place it into the upper <em>N</em> blocks worth of the mempool.</li>
<li>The highest mineable replaced fee-rate is not high enough to place the replaced transactions in the upper <em>N</em> blocks of the mempool.
Highest mineable replaced fee-rate in this context refers to the
fee-rate a miner can obtain by mining one or more of the replaced
transactions, taking unconfirmed parents into account.</li>
</ol>
<p>Setting <em>r=1.25</em> and <em>N=1</em> would be reasonable.</p>
</blockquote>
<p>I saw a claim that this proposal introduces an infinite relay DOS vector. How would this attack vector work?</p>

<mempool><attack><replace-by-fee>
What is the problem with the recent "One-Shot Replace-by-Fee-Rate" Proposal?
Murch
# What is the problem with the recent "One-Shot Replace-by-Fee-Rate" Proposal?

(Asked by: username_0 on 2024-01-22)

There recently was a proposal to allow replacements that [only beat the original by feerate, instead of by both the feerate and absolute fee](https://petertodd.org/2024/one-shot-replace-by-fee-rate).

> # One-Shot Replace-by-Fee-Rate
>
> We can mitigate Rule #3 transaction pinning in a miner-incentive
> compatible way by replacing transactions (or alternatively,
> transaction packages) that do not qualify for replacement based on the
> existing rules, if they qualify under these alternative rules:
>
> 1. The new transaction (package) has a fee-rate more than *r* times higher than the fee-rate of the transactions it replaces.
> 2. The new transaction (package) has a sufficiently high fee-rate to place it into the upper *N* blocks worth of the mempool.
> 3. The highest mineable replaced fee-rate is not high enough to place the replaced transactions in the upper *N* blocks of the mempool.
>    Highest mineable replaced fee-rate in this context refers to the
>    fee-rate a miner can obtain by mining one or more of the replaced
>    transactions, taking unconfirmed parents into account.
>
> Setting *r=1.25* and *N=1* would be reasonable.

I saw a claim that this proposal introduces an infinite relay DOS vector. How would this attack vector work?

**Tags:** mempool, attack, replace-by-fee


---

## 1 answers

### Answer by username_0 on 2024-01-22. Score: 7 | Accepted answer

TL;DR: Due to the two asymmetric sets of rules for replacement, a total of five transactions is sufficient to make a cycle of replacements that beat each other in turn. This allows an attacker to rebroadcast the same transactions over and over while at most paying for one small transaction per block.

---

*In all of the graphics an arrow points from child to parent, while a dotted line with a socket and ball points from original to replacement with socket and ball at the side of the replacement. A socket without ball (see Step 4) indicates an indirect conflict with the socket on the side of the replacement.*

You have three confirmed UTXOs `c1`, `c2` and `c3`. Let’s say 20 s/vB is the bottom of the first block.

1. You create `tx_LL`, a large low-feerate transaction with 100,000 vB at 1 s/vB (fee: 100,000 s). It spends the confirmed output `c1` and has an output `tx_LL:0`.
2. You attach a small low-feerate transaction `tx_LS` as a child with 100 vB at 1 s/vB (fee: 100 s) by spending `tx_LL:0`.

[![RBFr LL_LS.png](https://i.sstatic.net/ofXVo.png)](https://i.sstatic.net/ofXVo.png)

3. You replace `tx_LS` with `tx_HS` a high-feerate transaction that spends `c2` and `tx_LL:0`. `tx_HS` has 5000 vB and pays 21 s/vB, but since it spends an output of a low-feerate parent, its mining score is only 1.95 s/vB.

[![RBFr LL_HS.png](https://i.sstatic.net/5ZTp7.png)](https://i.sstatic.net/5ZTp7.png)

4. You replace `tx_LL` with `tx_LM` that has 100,000 vB and pays 3.05 s/vB (fee: 305,000 s) by spending the outputs `c1` and `c3`. `tx_LM` also indirectly replaces `tx_HS` even while `tx_HS` has a higher individual feerate. This is permitted, since `tx_LM` pays a higher total fee than the replaced transactions and because it only conflicts directly with `tx_LL` it only has to beat the feerate of `tx_LL` but not the feerate of `tx_HS`.

[![RBFr LM.png](https://i.sstatic.net/VabZL.png)](https://i.sstatic.net/VabZL.png)

5. You use the new RBFr rules to replace `tx_LM` with a small high feerate transaction `tx_RBFr` with 200 vB paying 20 s/vB (fee: 4000 s) that spends `c3` and makes it into the top block of the mempool. `tx_LM` was not going to be in the next block, and `tx_RBFr` pays more than 1.25× the feerate of `tx_LM`. So this is permitted under the new rules.

[![RBFr RBFr.png](https://i.sstatic.net/XYetF.png)](https://i.sstatic.net/XYetF.png)

6. As no transaction in the mempool spends `c1`, you then rebroadcast `tx_LL` and `tx_LS`.

[![RBFr rebroadcast LL_LS.png](https://i.sstatic.net/bdp1R.png)](https://i.sstatic.net/bdp1R.png)

7. You immediately replace both `tx_LS` and `tx_RBFr` with `tx_HS`. `tx_HS` has a feerate of 21 s/vB which is higher than `tx_RBFr` (20 s/vB) and `tx_LS` (1 s/vB), and pays more absolute fees than both (105,000 s vs 2000 s + 100 s). But since it’s a child of `tx_LL` it only has a mining score of 1.95 s/vB.

[![RBFr HS.png](https://i.sstatic.net/hhuSC.png)](https://i.sstatic.net/hhuSC.png)

Repeat 4.–7. to make every node on the network cycle the same five transactions ad nauseam. Roll the locktimes or sequences to make the transaction have a new TXIDs in each iteration, while spending the same UTXOs. The only transaction that is ever in any danger of getting mined is `tx_RBFr` which costs you 4000 sats. If it it does get included in a block, just start over with two new confirmed UTXOs as your `c2'` and `c3'`.


---

