Return-Path: Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 846F4C000B for ; Thu, 27 Jan 2022 13:42:25 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 659A84014E for ; Thu, 27 Jan 2022 13:42:25 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org X-Spam-Flag: NO X-Spam-Score: -2.098 X-Spam-Level: X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no Authentication-Results: smtp2.osuosl.org (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id P51t2MA42KSy for ; Thu, 27 Jan 2022 13:42:22 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.8.0 Received: from mail-yb1-xb2a.google.com (mail-yb1-xb2a.google.com [IPv6:2607:f8b0:4864:20::b2a]) by smtp2.osuosl.org (Postfix) with ESMTPS id 16E4F400F8 for ; Thu, 27 Jan 2022 13:42:21 +0000 (UTC) Received: by mail-yb1-xb2a.google.com with SMTP id i62so8792928ybg.5 for ; Thu, 27 Jan 2022 05:42:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:from:date:message-id:subject:to; bh=QvYAtpOqRtNMPJT2NB/iNb8B7MfcfleqsH4mhqKGQOk=; b=OcEPVrdS54Su5ag1tQm7UgA1umyXzS5zKPWNihYlKIxKJ6hdwn8N3xttmR72g+uOmJ Ax9/C+aMhLExGOu1wZVoVhWO7V59IXWhgaKiCNIl/nOpJ3nmtvwICKRhu+Z7i65K4lm3 8rhIE5avN//nQmfr2eq4cog8mDq4pNftJ1+YBENujWB1Xtq4AhENCVTvlt7PQ/2WKETp DJo9Q8niOECI2mqTRFt4Sn1hCakS1dpVQ9vedLaae5FoWjyutF7HIWZ4/D/R6UV7UM7/ JXSzo3oSGEDGGDTns4duCQEXF3IV6aBruQbzPaGeQDPPkqMOMco2X9fJvGQLM9u8mTB1 114A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=QvYAtpOqRtNMPJT2NB/iNb8B7MfcfleqsH4mhqKGQOk=; b=b3Jn868f8Wb/VsUQ6OftJLGGn22kRCXuw3LcVNTfJDcEGzN97EVjZOFsAwUV83067X eCcr8zPBmR0rGNZHQJKhnyxbAb791txVQpJc6hgsYLqSk/3Sbu1pOp8HtLSjY8hTgojC GHcB9ilP20pxceuNq3SlSxpJf7i4jwU9mg7PG5qBA2Ev7q9xrJkRH1cqKhKNoy0mh4eU UIgbmyf0tJ3K+DWN9Zb7xE7FN8qEnofURptvm/jX0IjO4RBzWfVj0YFjVq/ViBY0kzXs VujeYANXWq18bnteFLGAaju4vNiVJB0DDzmuKPtzI4T8qFe/qyq7SuSXz57zJglYU0sJ bCYw== X-Gm-Message-State: AOAM5302jwftd5+U4LmaSoXmkvD6jZcChckgAptq0clPxozae5nMHusd hbkBchCnSBAQstyMMNncm0URdqLycwtiKM593LgEIpZw1oA= X-Google-Smtp-Source: ABdhPJzQ1Lk/2jM548eHdTC2SBJU5gZzxyGdPRmm/DFKD3pjUed7BZ+AJhWPFRo4XVZ+2g/5Esf1tDmE3oqV/G1yzJo= X-Received: by 2002:a5b:548:: with SMTP id r8mr5526385ybp.717.1643290940270; Thu, 27 Jan 2022 05:42:20 -0800 (PST) MIME-Version: 1.0 From: Gloria Zhao Date: Thu, 27 Jan 2022 13:42:09 +0000 Message-ID: To: Bitcoin Protocol Discussion Content-Type: multipart/alternative; boundary="000000000000c1ea3e05d6907cff" X-Mailman-Approved-At: Thu, 27 Jan 2022 14:09:28 +0000 Subject: [bitcoin-dev] Improving RBF Policy X-BeenThere: bitcoin-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Bitcoin Protocol Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Jan 2022 13:42:25 -0000 --000000000000c1ea3e05d6907cff Content-Type: text/plain; charset="UTF-8" Hi everyone, This post discusses limitations of current Bitcoin Core RBF policy and attempts to start a conversation about how we can improve it, summarizing some ideas that have been discussed. Please reply if you have any new input on issues to be solved and ideas for improvement! Just in case I've screwed up the text wrapping again, another copy can be found here: https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff ## Background Please feel free to skip this section if you are already familiar with RBF. Nodes may receive *conflicting* unconfirmed transactions, aka "double spends" of the same inputs. Instead of always keeping the first transaction, since v0.12, Bitcoin Core mempool policy has included a set of Replace-by-Fee (RBF) criteria that allows the second transaction to replace the first one and any descendants it may have. Bitcoin Core RBF policy was previously documented as BIP 125. The current RBF policy is documented [here][1]. In summary: 1. The directly conflicting transactions all signal replaceability explicitly. 2. The replacement transaction only includes an unconfirmed input if that input was included in one of the directly conflicting transactions. 3. The replacement transaction pays an absolute fee of at least the sum paid by the original transactions. 4. The additional fees pays for the replacement transaction's bandwidth at or above the rate set by the node's *incremental relay feerate*. 5. The sum of all directly conflicting transactions' descendant counts (number of transactions inclusive of itself and its descendants) does not exceed 100. We can split these rules into 3 categories/goals: - **Allow Opting Out**: Some applications/businesses are unable to handle transactions that are replaceable (e.g. merchants that use zero-confirmation transactions). We (try to) help these businesses by honoring BIP125 signaling; we won't replace transactions that have not opted in. - **Incentive Compatibility**: Ensure that our RBF policy would not accept replacement transactions which would decrease fee profits of a miner. In general, if our mempool policy deviates from what is economically rational, it's likely that the transactions in our mempool will not match the ones in miners' mempools, making our fee estimation, compact block relay, and other mempool-dependent functions unreliable. Incentive-incompatible policy may also encourage transaction submission through routes other than the p2p network, harming censorship-resistance and privacy of Bitcoin payments. - **DoS Protection**: Limit two types of DoS attacks on the node's mempool: (1) the number of times a transaction can be replaced and (2) the volume of transactions that can be evicted during a replacement. Even more abstract: our goal is to make a replacement policy that results in a useful interface for users and safe policy for node operators. ## Motivation There are a number of known problems with the current RBF policy. Many of these shortcomings exist due to mempool limitations at the time RBF was implemented or result from new types of Bitcoin usage; they are not criticisms of the original design. ### Pinning Attacks The most pressing concern is that attackers may take advantage of limitations in RBF policy to prevent other users' transactions from being mined or getting accepted as a replacement. #### SIGHASH_ANYONECANPAY Pinning BIP125#2 can be bypassed by creating intermediary transactions to be replaced together. Anyone can simply split a 1-input 1-output transaction off from the replacement transaction, then broadcast the transaction as is. This can always be done, and quite cheaply. More details in [this comment][2]. In general, if a transaction is signed with SIGHASH\_ANYONECANPAY, anybody can just attach a low feerate parent to this transaction and lower its ancestor feerate. Even if you require SIGHASH\_ALL which prevents an attacker from changing any outputs, the input can be a very low amount (e.g. just above the dust limit) from a low-fee ancestor and still bring down the ancestor feerate of the transaction. TLDR: if your transaction is signed with SIGHASH\_ANYONECANPAY and signals replaceability, regardless of the feerate you broadcast at, an attacker can lower its mining priority by adding an ancestor. #### Absolute Fee The restriction of requiring replacement transactions to increase the absolute fee of the mempool has been described as "bonkers." If the original transaction has a very large descendant that pays a large amount of fees, even if it has a low feerate, the replacement transaction must now pay those fees in order to meet Rule #3. #### Package RBF There are a number of reasons why, in order to enable Package RBF, we cannot use the same criteria. For starters, the absolute fee pinning attack is especially problematic if we apply the same rules (i.e. Rule #3 and #4) in Package RBF. Imagine that Alice (honest) and Bob (adversary) share a LN channel. The mempool is rather full, so their pre-negotiated commitment transactions' feerates would not be considered high priority by miners. Bob broadcasts his commitment transaction and attaches a very large child (100KvB with 100,000sat in fees) to his anchor output. Alice broadcasts her commitment transaction with a fee-bumping child (200vB with 50,000sat fees which is a generous 250sat/vB), but this does not meet the absolute fee requirement. She would need to add another 50,000sat to replace Bob's commitment transaction. Disallowing new unconfirmed inputs (Rule #2) in Package RBF would be broken for packages containing transactions already in the mempool, explained [here][7]. Note: I originally [proposed][6] Package RBF using the same Rule #3 and #4 before I realized how significant this pinning attack is. I'm retracting that proposal, and a new set of Package RBF rules would follow from whatever the new individual RBF rules end up being. #### Same Txid Different Witness Two transactions with the same non-witness data but different witnesses have the same txid but different wtxid, and the same fee but not necessarily the same feerate. Currently, if we see a transaction that has the same txid as one in the mempool, we reject it as a duplicate, even if the feerate is much higher. It's unclear to me if we have a very strong reason to change this, but noting it as a limitation of our current replacement policy. See [#24007][12]. ### User Interface #### Using Unconfirmed UTXOs to Fund Replacements The restriction of only allowing confirmed UTXOs for funding a fee-bump (Rule #2) can hurt users trying to fee-bump their transactions and complicate wallet implementations. If the original transaction's output value isn't sufficient to fund a fee-bump and/or all of the user's other UTXOs are unconfirmed, they might not be able to fund a replacement transaction. Wallet developers also need to treat self-owned unconfirmed UTXOs as unusable for fee-bumping, which adds complexity to wallet logic. For example, see BDK issues [#144][4] and [#414][5]. #### Interface Not Suitable for Coin Selection Currently, a user cannot simply create a replacement transaction targeting a specific feerate or meeting a minimum fee amount and expect to meet the RBF criteria. The fee amount depends on the size of the replacement transaction, and feerate is almost irrelevant. Bitcoin Core's `bumpfee` doesn't use the RBF rules when funding the replacement. It [estimates][13] a feerate which is "wallet incremental relay fee" (a conservative overestimation of the node's incremental relay fee) higher than the original transaction, selects coins for that feerate, and hopes that it meets the RBF rules. It never fails Rule #3 and #4 because it uses all original inputs and refuses to bump a transaction with mempool descendants. This is suboptimal, but is designed to work with the coin selection engine: select a feerate first, and then add fees to cover it. Following the exact RBF rules would require working the other way around: based on how much fees we've added to the transaction and its current size, calculate the feerate to see if we meet Rule #4. While this isn't completely broken, and the user interface is secondary to the safety of the mempool policy, we can do much better. A much more user-friendly interface would depend *only* on the fee and size of the original transactions. ### Updates to Mempool and Mining Since RBF was first implemented, a number of improvements have been made to mempool and mining logic. For example, we now use ancestor feerates in mining (allowing CPFP), and keep track of ancestor packages in the mempool. ## Ideas for Improvements ### Goals To summarize, these seem to be desired changes, in order of priority: 1. Remove Rule #3. The replacement should not be *required* to pay higher absolute fees. 2. Make it impossible for a replacement transaction to have a lower mining score than the original transaction(s). This would eliminate the `SIGHASH\_ANYONECANPAY` pinning attack. 3. Remove Rule #2. Adding new unconfirmed inputs should be allowed. 4. Create a more helpful interface that helps wallet fund replacement transactions that aim for a feerate and fee. ### A Different Model for Fees For incentive compatibility, I believe there are different formulations we should consider. Most importantly, if we want to get rid of the absolute fee rule, we can no longer think of it as "the transaction needs to pay for its own bandwidth," since we won't always be getting additional fees. That means we need a new method of rate-limiting replacements that doesn't require additional fees every time. While it makes sense to think about monetary costs when launching a specific type of attack, given that the fees are paid to the miner and not to the mempool operators, maybe it doesn't make much sense to think about "paying for bandwidth". Maybe we should implement transaction validation rate-limiting differently, e.g. building it into the P2P layer instead of the mempool policy layer. Recently, Suhas gave a [formulation][8] for incentive compatibility that made sense to me: "are the fees expected to be paid in the next (N?) blocks higher or lower if we process this transaction?" I started by thinking about this where N=1 or `1 + p`. Here, a rational miner is looking at what fees they would collect in the next block, and then some proportion `p` of the rest of the blocks based on their hashrate. We're assuming `p` isn't *so high* that they would be okay with lower absolute fees in the next 1 block. We're also assuming `p` isn't *so low* that the miner doesn't care about what's left of the mempool after this block. A tweak to this formulation is "if we process this transaction, would the fees in the next 1 block higher or lower, and is the feerate density of the rest of the mempool higher or lower?" This is pretty similar, where N=1, but we consider the rest of the mempool by feerate rather than fees. ### Mining Score of a Mempool Transaction We are often interested in finding out what the "mining score" of a transaction in the mempool is. That is, when the transaction is considered in block template building, what is the feerate it is considered at? Obviously, it's not the transaction's individual feerate. Bitcoin Core [mining code sorts][14] transactions by their ancestor feerate and includes them packages at a time, keeping track of how this affects the package feerates of remaining transactions in the mempool. *ancestor feerate*: Ancestor feerate is easily accessible information, but it's not accurate either, because it doesn't take into account the fact that subsets of a transaction's ancestor set can be included without it. For example, ancestors may have high feerates on their own or we may have [high feerate siblings][8]. TLDR: *Looking at the current ancestor feerate of a transaction is insufficient to tell us what feerate it will be considered at when building a block template in the future.* *min(individual feerate, ancestor feerate)*: Another heuristic that is simple to calculate based on current mempool tooling is to use the [minimum of a transaction's individual score and its ancestor score][10] as a conservative measure. But this can overestimate as well (see the example below). *min ancestor feerate(tx + possible ancestor subsets)* We can also take the minimum of every possible ancestor subset, but this can be computationally expensive since there can be lots and lots of ancestor subsets. *max ancestor feerate(tx + possible descendant subsets)*: Another idea is to use the [maximum ancestor score of the transaction + each of its descendants][9]. This doesn't work either; it has the same blindspot of ancestor subsets being mined on their own. #### Mining Score Example Here's an example illustrating why mining score is tricky to efficiently calculate for mempool transactions: Let's say you have same-size transactions A (21sat/vB), B (1sat/vB), C(9sat/vB), D(5sat/vB). The layout is: grandparent A, parent B, and two children C and D. ``` A ^ B ^ ^ C D ``` A miner using ancestor packages to build block templates will first include A with a mining score of 21. Next, the miner will include B and C with a mining score of 6. This leaves D, with a mining score of 5. Note: in this case, mining by ancestor feerate results in the most rational decisions, but [a candidate set-based approach][10] which makes ancestor feerate much less relevant could be more advantageous in other situations. Here is a chart showing the "true" mining score alongside the values calculating using imperfect heuristics described above. All of them can overestimate or underestimate. ``` A B C D mining score | 21 | 6 | 6 | 5 | ancestor feerate | 21 | 11 | 10.3 | 9 | min(individual, ancestor) | 21 | 1 | 9 | 5 | min(tx + ancestor subsets) | 21 | 1 | 5 | 3 | max(tx + descendants subsets) | 21 | 9 | 9 | 5 | ``` Possibly the best solution for finding the "mining score" of a transaction is to build a block template, see what feerate each package is included at. Perhaps at some cutoff, remaining mempool transactions can be estimated using some heuristic that leans {overestimating, underestimating} depending on the situation. Mining score seems to be relevant in multiple places: Murch and I recently [found][3] that it would be very important in "ancestor-aware" funding of transactions (the wallet doesn't incorporate ancestor fees when using unconfirmed transactions in coin selection, which is a bug we want to fix). In general, it would be nice to know the exact mining priority of one's unconfirmed transaction is. I can think of a few block/mempool explorers who might want to display this information for users. ### RBF Improvement Proposals After speaking to quite a few people, here are some suggestions for improvements that I have heard: * The ancestor score of the replacement must be {5, 10, N}% higher than that of every original transaction. * The ancestor score of the replacement must be 1sat/vB higher than that of every original transaction. * If the original transaction is in the top {0.75MvB, 1MvB} of the mempool, apply the current rules (absolute fees must increase and pay for the replacement transaction's new bandwidth). Otherwise, use a feerate-only rule. * If fees don't increase, the size of the replacement transaction must decrease by at least N%. * Rate-limit how many replacements we allow per prevout. * Rate-limit transaction validation in general, per peer. Perhaps some others on the mailing list can chime in to throw other ideas into the ring and/or combine some of these rules into a sensible policy. #### Replace by Feerate Only I don't think there's going to be a single-line feerate-based rule that can incorporate everything we need. On one hand, a feerate-only approach helps eliminate the issues associated with Rule #3. On the other hand, I believe the main concern with a feerate-only approach is how to rate limit replacements. We don't want to enable an attack such as: 1. Attacker broadcasts large, low-feerate transaction, and attaches a chain of descendants. 2. The attacker replaces the transaction with a smaller but higher feerate transaction, attaching a new chain of descendants. 3. Repeat 1000 times. #### Fees in Next Block and Feerate for the Rest of the Mempool Perhaps we can look at replacements like this: 1. Calculate the directly conflicting transactions and, with their descendants, the original transactions. Check signaling. Limit the total volume (e.g. can't be more than 100 total or 1MvB or something). 2. Find which original transactions would be in the next ~1 block. The replacement must pay at least this amount + X% in absolute fees. This guarantees that the fees of the next block doesn't decrease. 3. Find which transactions would be left in the mempool after that ~1 block. The replacement's feerate must be Y% higher than the maximum mining score of these transactions. This guarantees that you now have only *better* candidates in your after-this-block mempool than you did before, even if the size and fees the transactions decrease. 4. Now you have two numbers: a minimum absolute fee amount and a minimum feerate. Check to see if the replacement(s) meet these minimums. Also, a wallet would be able to ask the node "What fee and feerate would I need to put on a transaction replacing this?" and use this information to fund a replacement transaction, without needing to guess or overshoot. Obviously, there are some magic numbers missing here. X and Y are TBD constants to ensure we have some kind of rate limiting for the number of replacements allowed using some set of fees. What should they be? We can do some arithmetic to see what happens if you start with the biggest/lowest feerate transaction and do a bunch of replacements. Maybe we end up with values that are high enough to prevent abuse and make sense for applications/users that do RBF. ### Mempool Changes Need for Implementation As described in the mining score section above, we may want additional tooling to more accurately assess the economic gain of replacing transactions in our mempool. A few options have been discussed: * Calculate block templates on the fly when we need to consider a replacement. However, since replacements are [quite common][11] and the information might be useful for other things as well, it may be worth it to cache a block template. * Keep a persistent block template so that we know what transactions we would put in the next block. We need to remember the feerate at which each transaction was included in the template, because an ancestor package may be included in the same block template in multiple subsets. Transactions included earlier alter the ancestor feerate of the remaining transactions in the package. We also need to keep track of the new feerates of transactions left over. * Divide the mempool into two layers, "high feerate" and "low feerate." The high feerate layer contains ~1 block of packages with the highest ancestor feerates, and the low feerate layer contains everything else. At the edge of a block, we have a Knapsacky problem where the next highest ancestor feerate package might not fit, so we would probably want the high feerate layer ~2MvB or something to avoid underestimating the fees. ## Acknowledgements Thank you to everyone whose RBF-related suggestions, grievances, criticisms and ideas were incorporated in this document: Andrew Chow, Matt Corallo, Suhas Daftuar, Christian Decker, Mark Erhardt, Lloyd Fournier, Lisa Neigut, John Newbery, Antoine Poinsot, Antoine Riard, Larry Ruane, S3RK and Bastien Teinturier. Thanks for reading! Best, Gloria [1]: https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md [2]: https://github.com/bitcoin/bitcoin/pull/23121#issuecomment-929475999 [3]: https://github.com/Xekyo/bitcoin/commit/d754b0242ec69d42c570418aebf9c1335af0b8ea [4]: https://github.com/bitcoindevkit/bdk/issues/144 [5]: https://github.com/bitcoindevkit/bdk/issues/414 [6]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019464.html [7]: https://gist.github.com/glozow/dc4e9d5c5b14ade7cdfac40f43adb18a#new-unconfirmed-inputs-rule-2 [8]: https://github.com/bitcoin/bitcoin/pull/23121#discussion_r777131366 [9]: https://github.com/bitcoin/bitcoin/pull/22290#issuecomment-865887922 [10]: https://gist.github.com/Xekyo/5cb413fe9f26dbce57abfd344ebbfaf2#file-candidate-set-based-block-building-md [11]: https://github.com/bitcoin/bitcoin/pull/22539#issuecomment-885763670 [12]: https://github.com/bitcoin/bitcoin/pull/24007 [13]: https://github.com/bitcoin/bitcoin/blob/1a369f006fd0bec373b95001ed84b480e852f191/src/wallet/feebumper.cpp#L114 [14]: https://github.com/bitcoin/bitcoin/blob/cf5bb048e80d4cde8828787b266b7f5f2e3b6d7b/src/node/miner.cpp#L310-L320 --000000000000c1ea3e05d6907cff Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi everyone,

This post discusses limitations of cur= rent Bitcoin Core RBF policy and
attempts to start a conversation about = how we can improve it,
summarizing some ideas that have been discussed. = Please reply if you
have any new input on issues to be solved and ideas = for improvement!

Just in case I've screwed up the text wrapping = again, another copy can be
found here: https://gist.github.com/glozow/2= 5d9662c52453bd08b4b4b1d3783b9ff

## Background

Please feel= free to skip this section if you are already familiar
with RBF.

= Nodes may receive *conflicting* unconfirmed transactions, aka
"doub= le spends" of the same inputs. Instead of always keeping the
first = transaction, since v0.12, Bitcoin Core mempool policy has
included a set= of Replace-by-Fee (RBF) criteria that allows the second
transaction to = replace the first one and any descendants it may have.

Bitcoin Core = RBF policy was previously documented as BIP 125.
The current RBF policy = is documented [here][1]. In summary:

1. The directly conflicting tra= nsactions all signal replaceability
=C2=A0 =C2=A0explicitly.

2. T= he replacement transaction only includes an unconfirmed input if
=C2=A0 = =C2=A0that input was included in one of the directly conflicting
transac= tions.

3. The replacement transaction pays an absolute fee of at lea= st the
=C2=A0 =C2=A0sum paid by the original transactions.

4. The= additional fees pays for the replacement transaction's
=C2=A0 =C2= =A0bandwidth at or above the rate set by the node's *incremental relay<= br>feerate*.

5. The sum of all directly conflicting transactions'= ; descendant counts
=C2=A0 =C2=A0(number of transactions inclusive of it= self and its descendants)
does not exceed 100.

We can split these= rules into 3 categories/goals:

- **Allow Opting Out**: Some applica= tions/businesses are unable to
=C2=A0 handle transactions that are repla= ceable (e.g. merchants that use
zero-confirmation transactions). We (try= to) help these businesses by
honoring BIP125 signaling; we won't re= place transactions that have not
opted in.

- **Incentive Compatib= ility**: Ensure that our RBF policy would not
=C2=A0 accept replacement = transactions which would decrease fee profits
=C2=A0 of a miner. In gene= ral, if our mempool policy deviates from what is
economically rational, = it's likely that the transactions in our
mempool will not match the = ones in miners' mempools, making our
fee estimation, compact block r= elay, and other mempool-dependent
functions unreliable. Incentive-incomp= atible policy may also
encourage transaction submission through routes o= ther than the p2p
network, harming censorship-resistance and privacy of = Bitcoin payments.

- **DoS Protection**: Limit two types of DoS attac= ks on the node's
=C2=A0 mempool: (1) the number of times a transacti= on can be replaced and
(2) the volume of transactions that can be evicte= d during a
replacement.

Even more abstract: our goal is to make a= replacement policy that
results in a useful interface for users and saf= e policy for
node operators.

## Motivation

There are a num= ber of known problems with the current RBF policy.
Many of these shortco= mings exist due to mempool limitations at the
time RBF was implemented o= r result from new types of Bitcoin usage;
they are not criticisms of the= original design.

### Pinning Attacks

The most pressing conce= rn is that attackers may take advantage of
limitations in RBF policy to = prevent other users' transactions from
being mined or getting accept= ed as a replacement.

#### SIGHASH_ANYONECANPAY Pinning

BIP125= #2 can be bypassed by creating intermediary transactions to be
replaced = together. Anyone can simply split a 1-input 1-output
transaction off fro= m the replacement transaction, then broadcast the
transaction as is. Thi= s can always be done, and quite cheaply. More
details in [this comment][= 2].

In general, if a transaction is signed with SIGHASH\_ANYONECANPA= Y,
anybody can just attach a low feerate parent to this transaction and<= br>lower its ancestor feerate.=C2=A0 Even if you require SIGHASH\_ALL which=
prevents an attacker from changing any outputs, the input can be a
v= ery low amount (e.g. just above the dust limit) from a low-fee
ancestor = and still bring down the ancestor feerate of the transaction.

TLDR: = if your transaction is signed with SIGHASH\_ANYONECANPAY and
signals rep= laceability, regardless of the feerate you broadcast at, an
attacker can= lower its mining priority by adding an ancestor.

#### Absolute Fee<= br>
The restriction of requiring replacement transactions to increase th= e
absolute fee of the mempool has been described as "bonkers."= If the
original transaction has a very large descendant that pays a lar= ge
amount of fees, even if it has a low feerate, the replacement
tran= saction must now pay those fees in order to meet Rule #3.

#### Packa= ge RBF

There are a number of reasons why, in order to enable Package= RBF, we
cannot use the same criteria.

For starters, the absolute= fee pinning attack is especially
problematic if we apply the same rules= (i.e. Rule #3 and #4) in
Package RBF. Imagine that Alice (honest) and B= ob (adversary) share a
LN channel. The mempool is rather full, so their = pre-negotiated
commitment transactions' feerates would not be consid= ered high
priority by miners.=C2=A0 Bob broadcasts his commitment transa= ction and
attaches a very large child (100KvB with 100,000sat in fees) t= o his
anchor output. Alice broadcasts her commitment transaction with a<= br>fee-bumping child (200vB with 50,000sat fees which is a generous
250s= at/vB), but this does not meet the absolute fee requirement. She
would n= eed to add another 50,000sat to replace Bob's commitment
transaction= .

Disallowing new unconfirmed inputs (Rule #2) in Package RBF would = be
broken for packages containing transactions already in the mempool,explained [here][7].

Note: I originally [proposed][6] Package RBF = using the same Rule #3
and #4 before I realized how significant this pin= ning attack is. I'm
retracting that proposal, and a new set of Packa= ge RBF rules would
follow from whatever the new individual RBF rules end= up being.

#### Same Txid Different Witness

Two transactions = with the same non-witness data but different
witnesses have the same txi= d but different wtxid, and the same fee but
not necessarily the same fee= rate. Currently, if we see a transaction
that has the same txid as one i= n the mempool, we reject it as a
duplicate, even if the feerate is much = higher. It's unclear to me if
we have a very strong reason to change= this, but noting it as a
limitation of our current replacement policy. = See [#24007][12].

### User Interface

#### Using Unconfirmed U= TXOs to Fund Replacements

The restriction of only allowing confirmed= UTXOs for funding a
fee-bump (Rule #2) can hurt users trying to fee-bum= p their
transactions and complicate wallet implementations. If the origi= nal
transaction's output value isn't sufficient to fund a fee-bu= mp and/or
all of the user's other UTXOs are unconfirmed, they might = not be able
to fund a replacement transaction. Wallet developers also ne= ed to
treat self-owned unconfirmed UTXOs as unusable for fee-bumping, wh= ich
adds complexity to wallet logic. For example, see BDK issues [#144][= 4]
and [#414][5].

#### Interface Not Suitable for Coin Selection<= br>
Currently, a user cannot simply create a replacement transaction
= targeting a specific feerate or meeting a minimum fee amount and
expect = to meet the RBF criteria. The fee amount depends on the size of
the repl= acement transaction, and feerate is almost irrelevant.

Bitcoin Core&= #39;s `bumpfee` doesn't use the RBF rules when funding the
replaceme= nt. It [estimates][13] a feerate which is "wallet incremental
relay= fee" (a conservative overestimation of the node's incremental
= relay fee) higher than the original transaction, selects coins for
that = feerate, and hopes that it meets the RBF rules. It never fails
Rule #3 a= nd #4 because it uses all original inputs and refuses to
bump a transact= ion with mempool descendants.

This is suboptimal, but is designed to= work with the coin selection
engine: select a feerate first, and then a= dd fees to cover it.
Following the exact RBF rules would require working= the other way
around: based on how much fees we've added to the tra= nsaction and its
current size, calculate the feerate to see if we meet R= ule #4.

While this isn't completely broken, and the user interfa= ce is
secondary to the safety of the mempool policy, we can do much bett= er.
A much more user-friendly interface would depend *only* on the
fe= e and size of the original transactions.

### Updates to Mempool and = Mining

Since RBF was first implemented, a number of improvements hav= e been
made to mempool and mining logic. For example, we now use ancesto= r
feerates in mining (allowing CPFP), and keep track of ancestor
pack= ages in the mempool.

## Ideas for Improvements

### Goals
<= br>To summarize, these seem to be desired changes, in order of priority:
1. Remove Rule #3. The replacement should not be *required* to pay
= higher absolute fees.

2. Make it impossible for a replacement transa= ction to have a lower
mining score than the original transaction(s). Thi= s would eliminate
the `SIGHASH\_ANYONECANPAY` pinning attack.

3. = Remove Rule #2. Adding new unconfirmed inputs should be allowed.

4. = Create a more helpful interface that helps wallet fund replacement
trans= actions that aim for a feerate and fee.

### A Different Model for Fe= es

For incentive compatibility, I believe there are different
for= mulations we should consider.=C2=A0 Most importantly, if we want to get
= rid of the absolute fee rule, we can no longer think of it as "the
= transaction needs to pay for its own bandwidth," since we won't al= ways
be getting additional fees. That means we need a new method of
r= ate-limiting replacements that doesn't require additional fees everytime.

While it makes sense to think about monetary costs when launc= hing a
specific type of attack, given that the fees are paid to the mine= r and
not to the mempool operators, maybe it doesn't make much sense= to
think about "paying for bandwidth". Maybe we should implem= ent
transaction validation rate-limiting differently, e.g. building itinto the P2P layer instead of the mempool policy layer.

Recently, = Suhas gave a [formulation][8] for incentive compatibility
that made sens= e to me: "are the fees expected to be paid in the next
(N?) blocks = higher or lower if we process this transaction?"

I started by t= hinking about this where N=3D1 or `1 + p`.
Here, a rational miner is loo= king at what fees they would
collect in the next block, and then some pr= oportion `p` of the rest of
the blocks based on their hashrate. We'r= e assuming `p` isn't *so high*
that they would be okay with lower ab= solute fees in the next 1 block.
We're also assuming `p` isn't *= so low* that the miner doesn't care
about what's left of the mem= pool after this block.

A tweak to this formulation is "if we pr= ocess this transaction, would
the fees in the next 1 block higher or low= er, and is the feerate
density of the rest of the mempool higher or lowe= r?" This is pretty
similar, where N=3D1, but we consider the rest o= f the mempool by feerate
rather than fees.

### Mining Score of a = Mempool Transaction

We are often interested in finding out what
t= he "mining score" of a transaction in the mempool is. That is, wh= en
the transaction is considered in block template building, what is the=
feerate it is considered at?

Obviously, it's not the transac= tion's individual feerate. Bitcoin Core
[mining code sorts][14] tran= sactions by their ancestor feerate and
includes them packages at a time,= keeping track of how this affects the
package feerates of remaining tra= nsactions in the mempool.

*ancestor feerate*: Ancestor feerate is ea= sily accessible information,
but it's not accurate either, because i= t doesn't take into account the
fact that subsets of a transaction&#= 39;s ancestor set can be included
without it. For example, ancestors may= have high feerates on their own
or we may have [high feerate siblings][= 8].

TLDR: *Looking at the current ancestor feerate of a transaction = is
insufficient to tell us what feerate it will be considered at whenbuilding a block template in the future.*

*min(individual feerate, = ancestor feerate)*: Another
heuristic that is simple to calculate based = on current mempool tooling
is to use the [minimum of a transaction's= individual score and its
ancestor score][10] as a conservative measure.= =C2=A0 But this can
overestimate as well (see the example below).
*min ancestor feerate(tx + possible ancestor subsets)* We can also
tak= e the minimum of every possible ancestor subset, but this can be
computa= tionally expensive since there can be lots and lots of ancestor
subsets.=

*max ancestor feerate(tx + possible descendant subsets)*: Another i= dea
is to use the [maximum ancestor score of the transaction + each of i= ts
descendants][9]. This doesn't work either; it has the same blinds= pot
of ancestor subsets being mined on their own.

#### Mining Sco= re Example

Here's an example illustrating why mining score is tr= icky to
efficiently calculate for mempool transactions:

Let's= say you have same-size transactions A (21sat/vB), B (1sat/vB),
C(9sat/v= B), D(5sat/vB).
The layout is: grandparent A, parent B, and two children= C and D.

```
=C2=A0 =C2=A0 A
=C2=A0 =C2=A0 ^
=C2=A0 =C2=A0= B
=C2=A0 =C2=A0^ ^
=C2=A0 =C2=A0C D
```

A miner using ance= stor packages to build block templates will first
include A with a minin= g score of 21. Next, the miner will include B and
C with a mining score = of 6. This leaves D, with a mining score of 5.

Note: in this case, m= ining by ancestor feerate results in the most
rational decisions, but [a= candidate set-based approach][10] which
makes ancestor feerate much les= s relevant could
be more advantageous in other situations.

Here i= s a chart showing the "true" mining score alongside the valuescalculating using imperfect heuristics described above. All of them
can= overestimate or underestimate.

```
=C2=A0 =C2=A0A =C2=A0 = =C2=A0 B =C2=A0 =C2=A0 =C2=A0 C =C2=A0 =C2=A0 D
mining score | =C2=A0= 21 =C2=A0 | =C2=A0 6 =C2=A0 | =C2=A0 6 =C2=A0 | =C2=A0 5 =C2=A0 |
ances= tor feerate =C2=A0 | =C2=A0 21 =C2=A0 | =C2=A011 =C2=A0 | 10.3 =C2=A0| =C2= =A0 9 =C2=A0 |
min(individual, ancestor) | =C2=A0 21 =C2=A0 | =C2=A0 1 = =C2=A0 | =C2=A0 9 =C2=A0 | =C2=A0 5 =C2=A0 |
min(tx + ancestor subsets) = =C2=A0 =C2=A0 =C2=A0| =C2=A0 21 =C2=A0 | =C2=A0 1 =C2=A0 | =C2=A0 5 =C2=A0 = | =C2=A0 3 =C2=A0 |
max(tx + descendants subsets) | =C2=A0 21 =C2=A0 | = =C2=A0 9 =C2=A0 | =C2=A0 9 =C2=A0 | =C2=A0 5 =C2=A0 |

```

Pos= sibly the best solution for finding the "mining score" of a
tr= ansaction is to build a block template, see what feerate each
package is= included at. Perhaps at some cutoff, remaining mempool
transactions can= be estimated using some heuristic that leans
{overestimating, underesti= mating} depending on the situation.

Mining score seems to be relevan= t in multiple places: Murch and I
recently [found][3] that it would be v= ery important in
"ancestor-aware" funding of transactions (the= wallet doesn't
incorporate ancestor fees when using unconfirmed tra= nsactions in coin
selection, which is a bug we want to fix).

In g= eneral, it would be nice to know the exact mining priority of
one's = unconfirmed transaction is.=C2=A0 I can think of a few block/mempool
exp= lorers who might want to display this information for users.

### RBF= Improvement Proposals

After speaking to quite a few people, here ar= e some suggestions
for improvements that I have heard:

* The ance= stor score of the replacement must be {5, 10, N}% higher
=C2=A0 than tha= t of every original transaction.

* The ancestor score of the replace= ment must be 1sat/vB higher than
=C2=A0 that of every original transacti= on.

* If the original transaction is in the top {0.75MvB, 1MvB} of t= he
=C2=A0 mempool, apply the current rules (absolute fees must increase = and
pay for the replacement transaction's new bandwidth). Otherwise,= use a
feerate-only rule.

* If fees don't increase, the size = of the replacement transaction must
=C2=A0 decrease by at least N%.
<= br>* Rate-limit how many replacements we allow per prevout.

* Rate-l= imit transaction validation in general, per peer.

Perhaps some other= s on the mailing list can chime in to throw other
ideas into the ring an= d/or combine some of these rules into a sensible
policy.

#### Rep= lace by Feerate Only

I don't think there's going to be a sin= gle-line feerate-based
rule that can incorporate everything we need.
= On one hand, a feerate-only approach helps eliminate the issues
associat= ed with Rule #3. On the other hand, I believe the main concern
with a fe= erate-only approach is how to rate limit replacements. We
don't want= to enable an attack such as:

1. Attacker broadcasts large, low-feer= ate transaction, and attaches a
chain of descendants.

2. The atta= cker replaces the transaction with a smaller but higher
feerate transact= ion, attaching a new chain of descendants.

3. Repeat 1000 times.
=
#### Fees in Next Block and Feerate for the Rest of the Mempool

= Perhaps we can look at replacements like this:

1. Calculate the dire= ctly conflicting transactions and, with their
descendants, the original = transactions. Check signaling. Limit the
total volume (e.g. can't be= more than 100 total or 1MvB or something).

2. Find which original t= ransactions would be in the next ~1 block. The
replacement must pay at l= east this amount + X% in absolute fees. This
guarantees that the fees of= the next block doesn't decrease.

3. Find which transactions wou= ld be left in the mempool after that ~1
block. The replacement's fee= rate must be Y% higher than the maximum
mining score of these transactio= ns. This guarantees that you now have
only *better* candidates in your a= fter-this-block mempool than you did
before, even if the size and fees t= he transactions decrease.

4. Now you have two numbers: a minimum abs= olute fee amount and a
minimum feerate. Check to see if the replacement(= s) meet these
minimums. Also, a wallet would be able to ask the node &qu= ot;What fee and
feerate would I need to put on a transaction replacing t= his?" and use
this information to fund a replacement transaction, w= ithout needing to
guess or overshoot.

Obviously, there are some m= agic numbers missing here. X and Y are
TBD constants to ensure we have s= ome kind of rate limiting for the
number of replacements allowed using s= ome set of fees.

What should they be? We can do some arithmetic to s= ee what happens if
you start with the biggest/lowest feerate transaction= and do a bunch
of replacements. Maybe we end up with values that are hi= gh enough to
prevent abuse and make sense for applications/users that do= RBF.

### Mempool Changes Need for Implementation

As describe= d in the mining score section above,
we may want additional tooling to m= ore accurately assess
the economic gain of replacing transactions in our= mempool.

A few options have been discussed:

* Calculate bloc= k templates on the fly when we need to consider a
=C2=A0 replacement. Ho= wever, since replacements are [quite common][11]
=C2=A0 and the informat= ion might be useful for other things as well,
=C2=A0 it may be worth it= to cache a block template.

* Keep a persistent block template so th= at we know what transactions
=C2=A0 we would put in the next block. We n= eed to remember the feerate
at which each transaction was included in th= e template, because an
ancestor package may be included in the same bloc= k template in
multiple subsets. Transactions included earlier alter the = ancestor
feerate of the remaining transactions in the package. We also n= eed
to keep track of the new feerates of transactions left over.
* Divide the mempool into two layers, "high feerate" and "l= ow
=C2=A0 feerate." The high feerate layer contains ~1 block of pac= kages with
the highest ancestor feerates, and the low feerate layer cont= ains
everything else. At the edge of a block, we have a Knapsacky proble= m
where the next highest ancestor feerate package might not fit, so wewould probably want the high feerate layer ~2MvB or something to avoidunderestimating the fees.

## Acknowledgements

Thank you to e= veryone whose RBF-related suggestions, grievances,
criticisms and ideas = were incorporated in this document:
Andrew Chow, Matt Corallo, Suhas Daf= tuar, Christian Decker,
Mark Erhardt, Lloyd Fournier, Lisa Neigut, John = Newbery,
Antoine Poinsot, Antoine Riard, Larry Ruane,
S3RK and B= astien Teinturier.

Thanks for reading!
<= br>
Best,
Gloria

[1]: https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replac= ements.md
[2]: https://github.com/bitcoin/bitcoin/pull/23121#i= ssuecomment-929475999
[3]: https://github.com/Xeky= o/bitcoin/commit/d754b0242ec69d42c570418aebf9c1335af0b8ea
[4]: https://github.com/b= itcoindevkit/bdk/issues/144
[5]: https://github.com/bitcoindevkit/bdk/issues/414
[6]:
https://lists.linuxfoundation.org/pipermail/b= itcoin-dev/2021-September/019464.html
[7]: https://gist.github.com/glozow/dc4e9d5c5b14ade7cdfac40f43adb18a#new-u= nconfirmed-inputs-rule-2
[8]: https://github.com/bitcoin/bitcoi= n/pull/23121#discussion_r777131366
[9]: https://github.com/bit= coin/bitcoin/pull/22290#issuecomment-865887922
[10]: https://gist.github.com/Xekyo/5cb413fe9f26dbce5= 7abfd344ebbfaf2#file-candidate-set-based-block-building-md
[11]: https://github.com/bitcoin/bitcoin/pull/22539#issuecomment-885763670=
[12]: https:/= /github.com/bitcoin/bitcoin/pull/24007
[13]: https://github.com/bitcoin/bitcoin/blob/1a369f006f= d0bec373b95001ed84b480e852f191/src/wallet/feebumper.cpp#L114
--000000000000c1ea3e05d6907cff--