nVersion=3 and Package RBF (tx fees and policy)


Host: glozow  -  PR author: glozow

The PR branch HEAD was c27864f at the time of this review club meeting.



Attendees should familiarize themselves with Bitcoin Core’s Replace by Fee (RBF) policy. These notes will refer to Bitcoin Core’s rules (not BIP125’s rules) by number.

A package is an ordered list of transactions, representable by a connected Directed Acyclic Graph (a directed edge exists between a transaction that spends the output of another transaction).

Package CPFP describes a policy enabling a child transaction to pay for a parent transaction when submitted together as a package, even if the parent does not meet all fee requirements on its own. Package CPFP allows L2 protocols to sign transactions with a low (or zero) feerate, and then add fees at broadcast time, even if the mempool minimum feerate rises above the presigned transaction’s feerate. Package CPFP was discussed in a previous review club meeting.

Package RBF describes a policy enabling a child to pay for replacing transactions its parent conflicts with when they are submitted as a package. (Package CPFP is a prerequisite for this). The main use case of Package RBF is to allow LN commitment transactions (which conflict with each other but whose fees cannot be changed) to replace each other in mempools using fees added at broadcast time using children attached to anchor outputs.

A Pinning Attack is a type of transaction relay censorship in which the attacker takes advantage of mempool policy to prevent a transaction from being mined or entering a mempool. An introduction to mempool policy and pinning attacks is transcribed here.

A “v3 transaction” refers to a transaction that has its nVersion field set to 3. These types of transactions are currently nonstandard in Bitcoin Core.

PR #25038 originally only implemented package RBF based on a simple extension of Bitcoin Core’s replacement policy. However, after the realization that the utility of package RBF would be nullified by RBF’s pinning problems, development effort shifted to fixing RBF in general. As such, the scope of the PR grew to include v3 as well.

The v3 commits include 44fcc4d3db3e45. The package RBF commits include 58e811ec27864f.


The high-level goal is to make competition for block space a purely fee-based market. More specifically, if two parties are trying to get their conflicting transactions confirmed, the one who broadcasts the transactions that are most profitable to mine should win, not the one who broadcasts first or adds some specially-crafted, low-fee garbage transactions. Here are some of the worst RBF limitations today:

  • Pinning through absolute fee rules (aka “Rule 3” or “Rule 4” Pinning): RBF rules require the replacement transaction pay a higher absolute fee than the aggregate fees paid by all original transactions. This rule seems to be the most headache-causing.

    • Suppose Alice and Mallory have presigned transactions A and M, respectively, which conflict with one another (e.g. commitment transactions for an LN channel together). Mallory broadcasts M first and can increase the fees required for Alice to replace M by:

      (1) Attaching transaction(s) that descend from M and pay a feerate too low to fee-bump M through CPFP. For example, assuming the default descendant size limit is 101KvB and M is 1KvB paying a feerate of 2sat/vB, adding a 100KvB, 2sat/vB child increases the cost to replace M by 200Ksat.

      (2) Adding a high-fee descendant of M that also spends from a large, low-feerate mempool transaction, C. The child may pay a very large fee but not actually be fee-bumping M if its overall ancestor feerate is still lower than M’s individual feerate. For example, assuming the default ancestor size limit is 101KvB, M is 1KvB paying 2sat/vB, and C is 99KvB paying 1sat/vB, adding a 1KvB child of M and C increases the cost to replace M by 101Ksat.

  • Pinning through package limits: All transactions admitted to the mempool must stay within package limits; no ancestor set or descendant set may exceed 25 transactions. Additionally, Rule 5 prohibits a replacement that would cause the eviction of more than 100 entries.

    • When a candidate transaction would replace mempool transactions, it may also decrease the descendant count of other mempool entries. Since ancestor/descendant limits are calculated prior to removing the would-be-replaced transactions, they may be overestimated. Also see Single-Conflict RBF Carve Out.

    • If a transaction conflicts with multiple mempool entries, even if each entry is within the 25-descendant package limit, it is possible to reach the Rule 5 limit. For example, conflicting with 6 transactions with 20 descendants each.

  • No increase in incentive compatibility required: Theoretically, any replacement transaction should confirm faster than the one it replaced; a rational user would not intentionally pay more fees to have their transaction confirm later. However, there is currently no rule to enforce this. As a result, all transactions signed with SIGHASH_ANYONECANPAY are vulnerable to being replaced by a transaction that will confirm later than the original.

    • Rule 6 was originally enforcing this, as the “incentive compatibility score” was previously just the feerate of the transaction. However, with the current ancestor set-based selection algorithm and possible package topologies, it isn’t possible to implement a DoS-resistant way of calculating these scores (it potentially requires using every entry in the mempool, see this explanation if you are interested in more details).
  • Ancestor BIP125 signaling transactions does not imply replaceability: Any descendant of an in-mempool transaction which signals replaceability is also replaceable because it will be evicted if its ancestor is replaced. However, if the descendant is not signaling BIP125 explicitly, it cannot be directly replaced. A transaction that only conflicts with the descendant, and not the BIP125-signaling ancestor, will be rejected.

  • Transactions must meet RBF fee rules on their own: Package RBF (see definition above) is not currently possible. Package RBF would enable, for example, conflicting LN commitment transactions (which tend to have fees that are too similar to replace one another) to replace each other utilizing fees from a fee-bumping child.

  • Further reading on L2 pinning grievances:

A larger list of RBF limitations was discussed last year on this mailing list post and gist. Various proposals to amend or rewrite RBF policy were discussed on those threads. The discussions resulted in this v3 proposal to address most issues. Additional RBF improvements (which do not conflict with v3) are also being considered.

V3 Policy

Package limits exist to limit the worst-case computational complexity of mempool operations such as block template assembly and new transaction validation. However, current limits still allow huge clusters of transactions to exist in the mempool. For example, Xekyo has tweeted clusters of 219 and 881 transactions found in a default mempool:

One diagnosis of these RBF limitations is that current mempool policy is far too permissive in the possible package topologies it accepts. The reason we cannot add an RBF rule comparing incentive compatibility scores is that calculating them involves, at minimum, looking at its cluster (since any transaction in the cluster may impact its incentive compatibility score), and there are no limits on how large a cluster can be. In fact, the entire mempool could be one cluster. Additionally, Rule 3 pinning is possible precisely because a counterparty has the freedom to attach transactions to impact the incentive compatibility of the shared transaction.

The simplest mempool policy would be to never allow transactions spending unconfirmed UTXOs, i.e., a maximum package size of 1. This doesn’t work because L2 protocols require the ability to spend unconfirmed outputs, but a package of 1 parent and 1 child is enough: the presigned transaction plus a child attaching fees at broadcast time.

Why allow such crazy clusters of transactions into our mempool if we cannot properly track them or assess their incentive compatibility afterward, especially if there is no use case beyond pinning attacks?

The philosophy behind v3 is to equalize what transactions the mempool permits with what it can feasibly handle, while enabling L2 use cases. In a v3 world, cluster size is limited to 2. This fact enables us to, for example, add an incentive compatibility rule to RBF without potentially needing to iterate through more than 2 transactions.

V3 rules (see docs for rationale) are as follows:

  • A v3 transaction signals replaceability, even if it does not signal BIP125 replaceability.
  • Any descendant of an unconfirmed V3 transaction must also be V3.
  • A V3 transaction’s unconfirmed ancestors must all be V3.
  • A V3 transaction cannot have more than 1 unconfirmed descendant.
  • A V3 transaction that has an unconfirmed V3 ancestor cannot be larger than 1,000 virtual bytes.
  • A V3 transaction cannot have more than 1 unconfirmed ancestor.

Notice a few nice properties of v3 packages and transactions (from most obvious to least obvious):

  • A v3 transaction in mempool cannot have more than 1 descendant.
  • A v3 transaction in mempool cannot have more than 1 ancestor.
  • When a v3 transaction is being replaced, it has at most 1 descendant. That descendant adds no more than 1,000vB to what needs to be evicted.
  • When the descendant of a v3 transaction is being replaced, there must be exactly 1 replacement transaction and 1 to-be-replaced transaction.
  • When a v3 transaction is being replaced, it is the sponsor of either 0 or 1 0-fee parents.
  • There is no difference between a v3 transaction having “explicit” and “inherited” replaceability signaling.
  • The incentive compatibility score of a transaction is equal to the minimum between its ancestor feerate and individual feerate.
  • When the descendant of a parent v3 transaction is being replaced, the parent’s descendant count does not change, and its descendant size changes by the difference between the replacement and to-be-replaced transactions.
  • RBF carve out is not needed.
  • Given an unconfirmed v3 transaction of size s paying fees f, a maximum-size child paying the same feerate pays f/s * 1,000 in fees.

Further work that may enable more benefits:

  • The Ephemeral Outputs proposal builds on top of v3, offering an alternative to SIGHASH_GROUP, with most of the features and a policy-only changeset.
  • Ephemeral outputs may be used to enable Eltoo, which also hinges on the resolution of these RBF limitations.
  • As v3 and package RBF would allow counterparties to replace each others’ commitment transactions, just a single anchor output per commitment transaction could be sufficient. This may eventually allow the removal of CPFP carve out.


  1. Did you review the PR? Concept ACK, approach ACK, tested ACK, or NACK? What was your review approach?


  1. What is the difference between a transaction that “explicitly” signals BIP125 and one that “inherits” BIP125 signaling? Why is it impossible for a v3 transaction to be one but not the other?

  2. Why should there be a rule to check whether a replacement transation is more incentive compatible to mine?

  3. Is min(package feerate, individual feerate) an accurate incentive compatibility score for v3 transactions? What about in general? (See CheckMinerScores() implementation).

  4. Imagine that there are two conflicting transactions, txA and txB, both 2,000vB. We really need one of them to confirm immediately, but it doesn’t matter which one. A malicious counterparty has already broadcast transaction txB which pays 10,000sat in fees (5sat/vB). We also know that it’s guaranteed (just pretend, ok?) that anything above 20sat/vB will be mined immediately, while anything below 20sat/vB will not.
    • Let’s say txA and txB are non-v3 transactions. What fee can we put on txA to guarantee that either txA or txB will reach a package feerate of 20sat/vB? (Hint: txA needs to replace txB and any descendants it may have. In the non-v3 world, txA can have up to 99KvB of descendants. What is the maximum fee the counterparty can attach to descendants of txB without bumping it to 20sat/vB?)
    • Now imagine txA and txB are both v3 transactions. What fee can we put on txA to guarantee that either txA or txB will reach a package feerate of 20sat/vB? (Hint: in the v3 world, txA cannot have more than 1,000vB of descendants).
  5. If all mining nodes on the network are running with this v3 policy, while none of the non-mining nodes are, what happens?

  6. If 10% of nodes on the network are running with this v3 policy, while we haven’t upgraded our node yet, what happens? What about 99% of nodes?

  7. If we were running a business that accepted unconfirmed transactions as payments, what changes should we make so that our wallet correctly tracks v3 transactions?

  8. Who might be interested in using v3 transactions? Who probably wouldn’t be interested?

  9. If there are some wallets/users/applications that use v3 while others don’t, is there a privacy issue (i.e. people can fingerprint which wallet likely created a transaction by looking at its version)?

  10. After the addition of v3, all non-v3 transactions are still subject to the existing limitations and pinning attacks. Wouldn’t it be safer to enforce these rules for all transactions on the network?

  11. V3 limits each transaction to 1 parent or 1 child (2 generations only), and perhaps that seems restrictive. Let’s consider an alternative set of rules that allows each transaction to have 2 parents or 2 children (a transaction may have up to 2 children or up to 2 parents. They cannot have both an unconfirmed parent and an unconfirmed child, so 2 generations only) - what would be the maximum cluster size?

  12. Why not limit the size of all v3 transactions to 1,000vB or something similarly small (Hint: what property of LN channels depends on standard transaction weight)?


  1. Why does ApplyV3Rules check whether the transaction conflicts with any of its ancestors’ children? What happens if you remove this check?

  2. V3 ancestor/descendant limits are stricter than the default mempool limits. Do we need to call both ApplyV3Rules (which enforces v3 ancestor/descendant limits) and CalculateMemPoolAncestors() (which enforces ancestor/descendant limits)? Why or why not?

  3. V3 rules are added to the filtering function passed to removeForReorg() in Chainstate::MaybeUpdateMempoolForReorg. Why do we need to check v3 rules in a reorg?

  4. Is CTxMemPool::removeForReorg() the appropriate place for this check? Can you think of an alternative place to add this check?

  5. How does CheckMinerScores determine whether one transaction or package is more incentive compatible to mine than another? Is this function 100% accurate for v3 transactions? What about for non-v3 transactions?

  6. Why is it necessary to evict all transactions below minimum relay feerate in TrimToSize()? (Hint: what does this test check)?

  7. Why must PackageMempoolChecks never be called with only 1 transaction? (Hint: an explanation can be found in this commit).

Rabbit Holes

  1. V3 restrictions suck! Why can’t we just replace RBF Rules 3 and 4 with a better rule based on feerate? For example, “replacement tx must have a feerate 2x higher than each of the transactions it’s replacing.”

  2. Why not allow packages with multiple parents and 1 child in v3?

  3. Theoretically, if the mempool is not full, the maximum number of transactions that may be removed in a replacement is 100 (due to Rule 5). After this commit, what is the new limit?

Also feel free to bring your own questions.

Meeting Log

  117:00 <glozow> #startmeeting
  217:00 <glozow> Hi everyone, welcome to PR Review Club! Feel free to say hi so we know who's here.
  317:00 <LarryRuane> hi!
  417:00 <Tobses> Hi
  517:00 <svav> Hi!
  617:00 <codo> hi
  717:00 <theStack> hi
  817:00 <d33r_gee> hello
  917:00 <michaelfolkson> hi
 1017:00 <glozow> We're looking at #25038 today, focusing on the v3 transaction relay policy commits. Notes are here: https://bitcoincore.reviews/25038
 1117:01 <stickies-v> hi
 1217:01 <pakaro> hi
 1317:01 <glozow> I wrote up questions but it's highly unlikely we'll get through all of them. Also the goal here is to learn, so please feel free to ask your own questions whenever you like.
 1417:01 <glozow> To get a sense of where everyone's at, did y'all get a chance to read through some of the notes or take a look at the PR?
 1517:02 <pakaro> y, read notes & some history
 1617:02 <codo> Using the notes as a guide I spent a lot of time catching up on background knowlegde (what are pinning attacks, watch old presentation, read doc/policy/* on master, what is nVersion, broaden git knowledge, ...). I will lurk and see how much of the conversation I understand.
 1717:02 <svav> Read the notes
 1817:02 <LarryRuane> Hey really quick meta github type question, if I may ... Does a PR being in "draft" status mean it's going to change a lot so hold off reviewing? Or does it tell the maintainers not to merge it yet (but what's there is good to review)? I've seen both interpretations
 1917:02 <stickies-v> y notes
 2017:02 <theStack> read the notes, didn't look too far into the code yet
 2117:02 <LarryRuane> y notes, referenced materials
 2217:02 <glozow> Wonderful to hear how much preparation y'all have done! :)
 2317:02 <d33r_gee> read the notes and watch your presentation glozow
 2417:03 <stickies-v> LarryRuane: I always interpret it as looking for concept/approach ack but nothing further
 2517:03 <glozow> larryruane: I think "draft" means "not mergeable" and sometimes "not reviewable." I put PRs in draft when the depend on other PRs, or if there's a bug in it I haven't fixed yet
 2617:03 <glozow> when they*
 2717:03 <LarryRuane> glozow: stickies-v: thanks!
 2817:04 <michaelfolkson> y notes
 2917:04 <jamesob> hi
 3017:04 <glozow> and yes, like stickies-v mentioned, I think usually reviewing it = concept and approach. I wouldn't leave a comment like "hey you should rename this variable" on a draft PR
 3117:04 <glozow> hi jamesob!
 3217:05 <abubakar> hi new here
 3317:05 <glozow> Would anybody like to summarize what problems we're trying to solve, and how V3 might be a solution?
 3417:05 <glozow> abubakar: welcome!
 3517:06 <LarryRuane> at a very high level, I would say that without V3 (as things are currently), there are a lot of DoS potentials; V3 is trying to close them
 3617:06 <LarryRuane> but V3 is strictly policy (not consensus), so only affects mempool acceptance and relay
 3717:06 <d33r_gee> mitigate pinning attacks (?)
 3817:07 <stickies-v> we're trying to make it easier for (mostly) off-chain protocols to ensure being able to quickly confirm on-chain if necessary, and v3 does that by reducing the complexity of allowed (unconfirmed) transaction clusters
 3917:07 <abubakar> v3 will enable rbf without signaling opting into rbf
 4017:08 <glozow> LarryRuane: d33r_gee: stickies-v: yep, I agree with these descriptions. The goal is to create a policy that's DoS-resistant and makes it more feasible to assess the incentive-compatibility of transactions. If adopted by most nodes, it should close pinning attacks which grief l2 protocols.
 4117:08 <pakaro> currently when LN-transactions settle on chain, the fee-rate is set when the anchor tx was first signed but unpublished. rbf is a solution, but currently vulnerable to tx-pinning attacks. v3's are non-standard txs that preclude tx-pinning [hopefully]
 4217:09 <glozow> abubakar: I think you're thinking of Full Rbf. V3 is another way of opting in to replaceability. It does not change the fact that RBF policy requires opt-in.
 4317:09 <LarryRuane> curious about one thing, I was initially surprised that we could even bump the version number! Are we doing that because we already used `nSequence` "hack" for BIP125 indication? Another way to ask, could RBF BIP125 have bumped the version number instead of using `nSequence`?
 4417:11 <LarryRuane> pakaro: "v3's are non-standard txs" -- well, that changes if / when this and related PRs get merged
 4517:11 <pakaro> Thanks LarryRuane: i was wondering v3s would propogate through the network, so if merged, v3s will become standard then
 4617:12 <pakaro> wondering how v3s**
 4717:12 <glozow> LarryRuane: good question. I used nVersion instead of nSequence because I could use something that was currently non-standard. It's hard to ensure apps/protocols aren't already reserving nSequence numbers for things.
 4817:13 <glozow> abubakar's point, though, brings us to Question #1: What is the difference between a transaction that “explicitly” signals BIP125 and one that “inherits” BIP125 signaling? Why is it impossible for a v3 transaction to be one but not the other?
 4917:14 <svav> What's an nSequence number?
 5017:14 <theStack> "explicit" signaling: one of the tx's inputs have an nSequence < 0xfffffffe (see `SignalsOptInRBF`); "inherited" signaling: one of the tx's ancestors txs shows "explicit" signaling; in v3 world we just always signal replacability
 5117:14 <LarryRuane> glozow: makes sense... and if old (pre- these PRs) see a v3 tx in a block, they consider it valid (probably don't even care about the version number?)
 5217:14 <LarryRuane> *old nodes
 5317:14 <theStack> should say "one of the tx's _unconfirmed_ ancestors" i guess
 5417:15 <glozow> svav: it's one of the fields in a tx input. https://github.com/bitcoin/bitcoin/blob/8b4dc94734a2472a201296376bfb18f982e6d92f/src/primitives/transaction.h#L79
 5517:15 <glozow> We use it for timelocks and signaling BIP125
 5617:15 <stickies-v> svav: see https://bitcoin.stackexchange.com/questions/87372/what-does-the-sequence-in-a-transaction-input-mean for a nice overview
 5717:16 <svav> Thanks guys
 5817:16 <abubakar> glowzow: the non v3 transaction opt in via the nsequence whereas ancestor of v3 transaction inherits BIP125 signaling
 5917:16 <Jim51> Thanks x2
 6017:17 <glozow> theStack: correct! And yes, in v3, you can't spend from an unconfirmed v3 without also being v3. So there is no way to inherit but not explicitly signal.
 6117:19 <glozow> LarryRuane: yes, there is no change in consensus. But in policy we want to strictly loosen rules. Otherwise we could accidentally censor transaction relay for an application. So either we really really make sure nobody is using it currently, or just pick something that's nonstandard today. In a sense, we always want consensus changes to be soft forks, but policy changes to be "hard forks."
 6217:20 <glozow> stickies-v: ahh nice link!
 6317:21 <LarryRuane> let's say someone submits a NON-v3 that spends an unconfirmed v3 ... it's not accepted into the mempool, but depending on timing, if its unconfirmed parent happens to get mined, then this non-v3 can be accepted -- that's interesting i think
 6417:21 <LarryRuane> glozow: very interesting!! thanks!
 6517:21 <michaelfolkson> Ha that's interesting. Policy is being loosened over time and consensus is being unloosened over time. Going in opposite directions
 6617:22 <glozow> abubakar: yes, a non-v3 transaction opts in by setting one of is nSequence numbers to a BIP125-signaling number. A v3 transaction is free to do this too. Ancestors do not inherit anything.
 6717:22 <LarryRuane> michaelfolkson: +1
 6817:23 <glozow> I'm going to throw out the next question but again feel free continue asking your own. Why should there be a rule to check whether a replacement transation is more incentive compatible to mine?
 6917:24 <LarryRuane> because if we don't do that, miners may run custom software that IS incentive compat, and then miners' mempools and the rest of the full nodes mempools would diverge?
 7017:24 <glozow> LarryRuane: yes, it's normal for mempool acceptance to depend on the chainstate. Similar to a transaction that spends 25 just-confirmed transactions. Or even a transaction that spends a 1-block relative timelocked output that just confirmed.
 7117:25 <LarryRuane> glozow: yes, good point!
 7217:25 <d33r_gee> q2:  it is important to ensure that the replacement transaction that replaces an existing unconfirmed transaction offers a higher fee so that it is more attractive to miners and has a higher chance of being included in the next block.
 7317:26 <stickies-v> glozow: "A v3 transaction is free to do this too." - it's allowed, but pointless, right?
 7417:26 <LarryRuane> and in the scenarios both of us mentioned, if a tx is currently non-standard but MAY become standard soon, we don't hold onto it in an orphanage or something, do we? We just drop it immediately?
 7517:27 <LarryRuane> stickies-v: (if i may attempt an answer), yes, pointless, but doesn't make the tx invalid
 7617:28 <glozow> stickies-v: yeah, it would be redundant to be both v3 and signal, but harmless. I imagine it would happen because wallets are automatically setting their nSequence to signal BIP125, and then they add support for v3 and there's no reason to change the former default
 7717:29 <glozow> and signal BIP125*
 7817:30 <abubakar> why is it that descendant of v3 transaction sizes are restricted to 1000vb
 7917:31 <pakaro> abubakar: 1000vb is enough so that many inputs are allowed, but not so high that you aren't abusing the network. iirc.
 8017:31 <glozow> d33r_gee: yes, that's part of the answer! but, rewording the question a bit, assuming the replacement tx always increases the overall fee and feerate of the mempool, would it be ok if the replacer would be selected later than the replacee?
 8117:32 <glozow> hint: see the "No increase in incentive compatibility required" pinning attack in the notes
 8217:32 <stickies-v> abubakar: in addition to pakaro 's answer - replacement rules require the new transaction to pay for all descendants too, so the more descendants allowed, the more expensive it can become to replace a transaction
 8317:32 <glozow> abubakar: you may want to take a look at "Pinning through absolute fee rules" in the notes
 8417:33 <abubakar> will do thanks..
 8517:34 <glozow> We can answer this question by asking "is there ever a scenario where you would want to pay *more* fees for a transaction to confirm *slower*?"
 8617:35 <pakaro> stickies-v how do descendants and unconfirmed parents relate? In my understanding, a v3 tx can only have 1 unconfirmed parents...To me that means that, inversely, a parent can only have 1 descendant..so how do we get multiple descendants? Is it that multiple-descendants exist in situations where the v3 was not included, and then the design is that v3 transactions come in later, and _those_ can only have 1 descendant?
 8717:36 <LarryRuane> glozow: if you're an attacker, trying to pin?
 8817:36 <glozow> pakaro: in the non-v3 world, a transaction can have multiple descendants. A transaction can also have an up-to-100KvB descendant.
 8917:36 <michaelfolkson> glozow: You mean like ensuring a child transaction was in a different block to its parent rather than in the same one? Probably but can't think of a scenario...
 9017:37 <pakaro> glozow: so the multiple descendants were already there, in this hypthetical case?
 9117:37 <stickies-v> pakaro: I was talking about "descendants" in terms of total size (vbytes) here, not count. sorry for the confusion. if we allow only a single descendant, but it can be a very large descendant, that can become costly again
 9217:37 <pakaro> stickies-v: hadn't thought about v.large single descendants, thanks!
 9317:38 <michaelfolkson> Maybe if you wanted to wait and see what other parties did and then depending on that RBFing the parent so the child was no longer valid...
 9417:38 <glozow> LarryRuane: bingo! Since we don't require the replacer to be more incentive compatible to mine than the replacee, attackers can pin transactions by replacing them and adding low-feerate ancestors. Of course, they have to be able to edit the transaction and bring in more inputs. But this is the case with SIGHASH_ANYONECANPAY transactions (of which there are thousands every day).
 9517:39 <d33r_gee> glozow hmmm... yes the replacer could be selected later than the replaccee if the replacee is time-sensitive (e.g. it is a transaction needed for a time-sensitive application), it may be important to prioritize the replacee over the replacer even if the replacer has a higher fee and feerate (still wrapping my head around those use cases)
 9617:39 <michaelfolkson> (Ha I was thinking honest non-attacker use cases)
 9717:41 <stickies-v> d33r_gee: the network can't have an understanding about what's time-sensitive or honest etc, so I think in practice we only really have the fees to look at
 9817:41 <glozow> yeah my point here is the only use case is pinning attacks haha
 9917:43 <d33r_gee> glozow makes sense... so being aware of the attacker use case would be the thing to look for (?)
10017:45 <glozow> d33r_gee: the hope is we get rid of this pinning attack
10117:46 <d33r_gee> glozow got it
10217:46 <glozow> Is min(package feerate, individual feerate) an accurate incentive compatibility score for v3 transactions? What about non-v3?
10317:47 <michaelfolkson> d33r_gee: Depending on the protocol (Lightning, vaults etc) part of security model is you watch the chain for an attacker broadcasting a transaction they shouldn't and respond. Being pinned prevents your a speedy response
10417:47 <LarryRuane> glozow: I think it is, at least for v3, because it recognizes that children can pay for parents, but parents can NOT pay for children!
10517:48 <glozow> Ah I just realized my question is a bit ambiguously worded. More precisely, is `CheckMinerScores` an accurate assessment for v3 https://github.com/bitcoin-core-review-club/bitcoin/commit/58e811ecb1e1977422ecda2af62460e8efc057be
10617:49 <glozow> But yes the idea is, in v3, it's accurate. In non-v3, it's not accurate. You need to look further than your ancestor set or descendant set.
10717:50 <LarryRuane> you have to look at your entire cluster (cousins, etc)
10817:50 <LarryRuane> *siblings, actually, and beyond
10917:51 <glozow> LarryRuane: yep. If you're a child, min(child, parent+child) is correct since your parent can get selected without you.
11017:51 <glozow> LarryRuane: yes :D
11117:52 <glozow> What's the maximum cluster size for a v3 transaction? What's the maximum cluster size for a non-v3?
11217:52 <codo> 2 resp. 101?
11317:52 <pakaro> 1000vb and 100,000vb ?
11417:52 <d33r_gee> michaelfolkson thanks for clarifying and here a response is to remove the tx from our mempool?
11517:53 <glozow> codo: 2 is correct for v3
11617:53 <theStack> maximum cluster size for non-v3 seems to be basically unlimited?
11717:53 <glozow> I'm looking for an answer where the unit is number of transactions
11817:53 <stickies-v> theStack: +1
11917:53 <glozow> theStack: stickies-v: bingo 💯
12017:54 <glozow> frequent review club attendees and people who have been around me for more than 10 minutes know: there is currently no limit on cluster size
12117:54 <glozow> If all mining nodes on the network are running with this v3 policy, while none of the non-mining nodes are, what happens?
12217:55 <michaelfolkson> d33r_gee: No your response is to broadcast a pre-signed transaction remedying the situation (assuming you can and you aren't pinned)
12317:55 <theStack> no v3 txs would ever reach a miner, since all non-mining nodes reject those form the mempool. so i guess the answer to that question would be "nothing" :p
12417:55 <theStack> *from
12517:56 <pakaro> +1 thestack
12617:56 <LarryRuane> glozow: I'd say the v3 stuff still gets mined, but the non-mining mempools would have a lot of junk that can't get mined
12717:56 <abubakar_> does cluster size means the descendant and ancestors altogether?
12817:56 <d33r_gee> michaelfolkson ah good to know... this attack vector is tricky indeed
12917:57 <LarryRuane> abubakar_: yes, but "THERE'S MORE!" ... also all siblings, uncles, cousins, 2nd cousins, etc.
13017:57 <glozow> theStack: correct! also, if a miner mines v3 transactions, everybody would still accept them. the point of this question is "it's policy, not consensus"
13117:58 <LarryRuane> oh I forgot that v3 is currently non-standard ... right glozow: and @theStack
13217:58 <pakaro> is a sibling just another unconfirmed tx that spends the same inputs as _its_ sibling?
13317:59 <glozow> pakaro: sibling is a tx that spends another output from your parent tx
13417:59 <stickies-v> abubakar_: see the notes in https://bitcoincore.reviews/26152 for more info about ancestors vs clusters
13517:59 <LarryRuane> pakaro: simplest example of a sibling is one that has a parent that's also our own parent
13617:59 <pakaro> ofc, thx glozow larryruane
13718:00 <abubakar_> stickies-v:thanks!
13818:00 <glozow> We're out of time but I'm around for a bit longer to answer any questions anybody has
13918:00 <glozow> #endmeeting
14018:00 <codo> For LN to profit from this, a large part of the network should see V3 as standard, right? If so: won't it take some time (like a year) before LN channels based on V3 will be opened?
14118:00 <LarryRuane> glozow: any chance we could have a part 2 next week? there's a lot we didn't get to, and this is great stuff!
14218:01 <michaelfolkson> LarryRuane: +1
14318:01 <stickies-v> 🥇 to glozow for probably the most elaborate notes and questions in the history and future of the review club - thank you!
14418:01 <LarryRuane> (or part 2 could be later, but then people might forget part 1)
14518:01 <Jim51> +1
14618:01 <d33r_gee> LarryRuane +1
14718:01 <glozow> last time I did a part 2, nobody really showed up to the second one 😅
14818:01 <abubakar_> glowzow :the 2 clusters of v3, is it helpful to LN
14918:01 <LarryRuane> stickies-v: 💯
15018:01 <LarryRuane> oh sorry to hear that
15118:01 <theStack> thanks for hosting glozow! really interesting topic, would also love to see a part 2 :)
15218:01 <abubakar_> LarryRuane:+1
15318:02 <michaelfolkson> The +1s promise to attend a second one
15418:02 <glozow> closing pinning attacks and adding package RBF would be helpful to LN yes, and adopting this set of policies would be one way of doing that
15518:02 <pakaro> +1
15618:02 <pakaro> i had a [hopefully quick] meta-question -> the _v3_ refers to v0=p2pkh, v1-p2sh-p2wpkh, v2=p2wpkh, v3=anti-pinning-tx.?
15718:02 <LarryRuane> is there much controversy about adding v3?
15818:02 <abubakar_> +1
15918:03 <ranemirus> thanks everyone, first time here!
16018:03 <LarryRuane> pakaro: no, all of those are v2
16118:03 <d33r_gee> thanks glozow and every1! See yall next time
16218:03 <glozow> LarryRuane: well v3 isn't perfect. It'll also take time, as codo points out
16318:03 <LarryRuane> ranemirus: great to have you here!
16418:03 <theStack> i have one question regarding the actual code, on the very first commit ( https://github.com/bitcoin/bitcoin/pull/25038/commits/5d0a0ca44aea14b9e907114daef15106a9311c95 ) ... was getting very confused about the naming "poor" and "rich" there. the tx_poor pays a fee, while the tx_rich pays zero fee. shouldn't it be the other way round?
16518:04 <Tobses> Thank you, everyone... really learnt alot.. First time here also.
16618:04 <LarryRuane> theStack: +1 - i was wondering that too
16718:04 <LarryRuane> Tobses: so glad you could be here!
16818:05 <pakaro> LarryRuane what are v0, v1 transactions? i was thinking v0 segwit & v1 segwit.
16918:06 <glozow> requires some patience. here's a podcast painting a picture of a Whole New World with v3, ephemeral anchors, eltoo, etc.: https://podcast.chaincode.com/2023/02/15/greg-sanders.html
17018:06 <LarryRuane> glozow: ty!
17118:06 <glozow> theStack: haha I suppose the naming is weird, though notice that tx_rich has a high modified fee
17218:06 <glozow> tx_poor pays minrelay fee
17318:07 <glozow> L94: `node.prioritisetransaction(tx_rich["txid"], 0, int(DEFAULT_FEE * COIN))`
17418:08 <glozow> pakaro: those are output witness versions. here, we're talking about the value of the transaction's nVersion field
17518:08 <theStack> glozow: oh, i see. should have looked further
17618:09 <theStack> IIUC then the comment "another has 0 fees but is bumped by child" should probably be "another has minrelay fee but is bumped by child"?
17718:09 <pakaro> glozow thanks!
17818:10 <glozow> theStack: yes, that comment is not very accurate, apologies
17918:17 <theStack> no worries, just wanted to check that my assumption of "poor"/"rich" refering to the fees paid by that tx and not something else
18018:17 <theStack> do you still have time for q4? (or would that be better for part2? :p)
18118:18 <glozow> I guess part 2 is happening 😂 y'all better be here
18218:18 <theStack> :D
18318:18 <glozow> yes, I'm free for Q4 if you have an answer!
18418:18 <glozow> Imagine that there are two conflicting transactions, txA and txB, both 2,000vB. We really need one of them to confirm immediately, but it doesn’t matter which one. A malicious counterparty has already broadcast transaction txB which pays 10,000sat in fees (5sat/vB). We also know that it’s guaranteed (just pretend, ok?) that anything above 20sat/vB will be mined immediately, while anything below 20sat/vB will not.
18518:18 <glozow> Let’s say txA and txB are non-v3 transactions. What fee can we put on txA to guarantee that either txA or txB will reach a package feerate of 20sat/vB?
18618:20 <theStack> struggled a bit at first on this... ended up with answer 2010000 sats (solved equation `(10000 + x) / (2000 + 99000) = 20` for x)
18718:20 <glozow> Yes wonderful answer!
18818:21 <Tobses> wow
18918:21 <glozow> Idea being, you might need to replace a 99KvB descendant
19018:21 <glozow> But if that 99KvB descendant pays enough to bump to 20sat/vB, then you win even if you didn't RBF
19118:22 <glozow> Now imagine txA and txB are both v3 transactions. What fee can we put on txA to guarantee that either txA or txB will reach a package feerate of 20sat/vB?
19218:23 <theStack> in this case the descendant can only have a max size of 1KvB
19318:23 <glozow> Yep, so (10000 + x) / (2000 + 1000) = 20
19418:23 <theStack> so i got the result 50000 sats... (solving `(10000 + x) / (2000 + 1000) = 20` for x)
19518:24 <glozow> Yep, much more reasonable!
19618:25 <theStack> indeed... txA's fee-rate would then be 25 sats/vbyte instead of 1005 sats/vbyte
19718:25 <glozow> I suppose the *exact* fee also depends on the size of txB in order to meet Rule 4, but that'd be a few hundred sats different
19818:26 <theStack> ah, interesting point, didn't think of that
19918:27 <glozow> So yes :) this addresses "Rule 3 pinning" by effectively setting a more reasonable upper bound on what you might need to pay if they try to pin you this way
20018:27 <pakaro> 40x more reasonable!