4

One of the rule for the transaction replacement (RBF) is that the number of original transactions (directly conflicting transactions + their descendants) can't exceed 100. However, in presence of overlapping transactions, "wrong counting" of transactions may occur.

For example, consider situation where transactions A, B and C are ancestors of transaction D. If replacement transaction R replaces A, B and C, then, according to the rule/condition above, they count as 6 and not as 4.

A  B  C
\  |  /
 \ | /
   D

What interests me is how transactions are calculated in the following example. In the example, A and B are ancestors of C, but A is also an ancestor of B. If R replaces A and B, how is the number of transactions calculated in this case?

   A  
 / |
 B |
 \ |
   C

I would say the number of transactions is 6.

I came to that conclusion (number) in the following way:

1. start from A; count A (1)  
  1.1. from A go to B; count B (2)    
    1.1.1 from B go to C; count C (3)  
  1.2. from A go to C; count C (4)  
2. start from B; count B (5)  
  2.1. from B go to C; count C (6)  

Am I right?

Thanks!

LeaBit
  • 930
  • 1
  • 13

2 Answers2

6

The rule implemented in Bitcoin Core today (as of version 26.0) is that the sum of the number of descendants, counted over all conflicted transactions, cannot exceed 100.

In your example, that number is 5. The descendant set of A is {A,B,C}. The descendant set of B is {B,C}. If R conflicts with A and B, then those set counts are added up, and 3+2=5.

Note that this overestimate only matters for determining the maximum conflict set size. Once the number is calculated and verified to not exceed 100, the exact (properly deduplicated) conflict set is calculated (set {A,B,C} in your example) and used for further checks (including fee-based conditions).

Pieter Wuille
  • 105,497
  • 9
  • 194
  • 308
  • So in each descendant set, each transaction can appear only once, and the descendant set is calculated for each directly conflicting transaction. The sum of the sizes of the descendant sets must not exceed 100. Did I understand correctly? – LeaBit Dec 07 '23 at 18:34
  • 1
    You look up each conflicting transaction’s mempool entry. You read the "descendant count" field from that entry. You sum those up across the direct conflicts of your replacement. That sum cannot be greater than 100. Basically, it is a potential overestimate, but that way you don’t have to look up all of the descendants and deduplicate. – Murch Dec 07 '23 at 18:35
  • 1
    Yes, descendants are calculated correctly (i.e., deduplicated) for transactions already in the mempool. They're just not re-deduplicated in the construction of the conflict set size. – Pieter Wuille Dec 07 '23 at 18:36
  • @Murch Thank you, now I understand why there is a potential overestimate. Just one more question. When it comes to the rule for fee calculation (the rule that says that the fee of the replacement transaction must be greater than the total fee of all transactions it replaces - direct conflicting transactions + their descendants), is each transaction in that case calculated only once or some overlaps may occur as in this case? – LeaBit Dec 07 '23 at 18:41
  • @PieterWuille Thanks. Are such overlaps possible when it comes to fee calculation? – LeaBit Dec 07 '23 at 18:42
  • 1
    @LeaBit No, the actual conflict set is calculated exactly (and properly deduplicated) after counting its size, and further analysis is done using that exact conflict set. The "sum of descendant set sizes of conflicts cannot exceed 100" is just a quick check before actually constructing the set, to make sure it won't grow too big. – Pieter Wuille Dec 07 '23 at 18:43
  • @PieterWuille So that check to see if it exceeds 100 is just a quick check based on the descendant fields of each direct conflicting transaction (as Murch said). It must not exceed 100, although overlaps and overestimation may occur. In that case, the conflicting sets are {A, B, C} and {B, C}, and the sum is 5. However, when it comes to further checks, then the real conflicting set does not have any duplicates, so it is actually {A, B, C}. Further checks are being made on this conflicting set, including the calculation of the correct fee. Did I understand correctly? – LeaBit Dec 07 '23 at 18:50
  • @LeaBit That is correct. – Pieter Wuille Dec 07 '23 at 18:51
  • @PieterWuille And just one more question. It only matters that direct conflicting transactions signal replaceability (some nSequence smaller than 0xffffffff-1). If one of the direct conflicting transactions included in the replacement does not signal replaceability, replacement will not occur. Descendant transactions do not have to signal replaceability (all nSequence can be 0xffffffff), they will be replaced if one of their ancestors is replaced? – LeaBit Dec 07 '23 at 18:55
  • 1
    According to BIP125, transactions are to be considered replaceable if they either explicitly signal replacement, or if they descend from an unconfirmed transaction that does (look for "inherited signalling"). – Pieter Wuille Dec 07 '23 at 18:57
  • I am asking because here they said that the inherited signalling is not implemented in Bitcoin Core. – LeaBit Dec 07 '23 at 18:59
  • That's possible, I'm not familiar with the details there. – Pieter Wuille Dec 07 '23 at 19:01
  • 2
    I believe the implementation bug referenced there is that an attempt to replace a non-replaceable transaction descending from a replaceable transaction would fail, even though the descendant transaction would be supposed to inherit replaceability. It is possible to replace a descendant by conflicting with its ancestor, regardless of whether the descendant signals replaceability or finality, though. – Murch Dec 07 '23 at 19:33
  • @Murch Thanks.. – LeaBit Dec 07 '23 at 20:56
5

One of the rule for the transaction replacement (RBF) is that the number of original transactions (directly conflicting transactions + their descendants) can't exceed 100.

This is a non-equivalent restatement of the implementation description. Your (reasonable) misunderstanding appears to be that you expect every replaced transaction to be collected and then this deduplicated set to be counted.

Instead, the rule is that "the sum of the directly conflicting transaction’s descendant counts cannot exceed 100". Specifically, this prescribes a different behavior, namely only iterating over the direct conflicts, reading their "descendant count" fields, and summing those up. This may overestimate the count of replaced transactions but does not require actually enumerating all descendants in order to deduplicate them.

So, in your example, the direct conflicts are A and B. The descendant count of A is 3 ({A, B, C}), and the descendant count of B is 2 ({B, C}), therefore in the context of the check, they would count as 5 towards the 100 limit, even though the descendant sets overlap.

Murch
  • 75,206
  • 34
  • 186
  • 622