2

I wonder how Bitcoin Core chooses which transactions are added to the template of a block when you call getblocktemplate. Is the mempool sorted by fee rate in sat/vB and selects transactions in an orderly sequence until the block is full or does it use some kind of algorithm to select the transactions?

2
  • 1
    There's several questions here about transaction selection which seem relevant,. Do they not answer your question? Mar 11 at 8:16
  • Thanks @RedGrittyBrick! It helps to see that effectively only the fee is now prioritised and not the priority model. But I still don't know if there is any algorithm for selecting transactions or if they are simply taken sequentially in order of fee rate. Mar 11 at 8:45

1 Answer 1

3

As of Bitcoin Core v26.1, the mempool tracks each transaction in the context of its ancestor set and prioritizes their inclusion on basis of their ancestor set feerate. Let’s assume a cluster of five unconfirmed transactions: Grandparent (GP), Parent1 (P1), Parent2 (P2), Child (C), and Grandchild (GC)

GP
  \
   P1   P2
     \ /
      C
     /
    GC
  • The ancestor set of Grandparent is { GP }, its ancestor set queues at the feerate GP.fee / GP.weight.
  • The ancestor set of Parent1 is { GP, P1 }, its ancestor set queues at the feerate (GP.fee + P1.fee) / (GP.weight + P1.weight).
  • The ancestor set of Parent2 is { P2 }, its ancestor set queues at the feerate P2.fee / P2.weight.
  • The ancestor set of Child is { GP, P1, P2, C }, its ancestor set queues at the feerate (GP.fee + P1.fee + P2.fee + C.fee) / (GP.weight + P1.weight + P2.weight + C.weight).
  • The ancestor set of Grandchild is { GP, P1, P2, C , GC }, its ancestor set queues at the feerate
    (GP.fee + P1.fee + P2.fee + C.fee + GC.fee) / (GP.weight + P1.weight + P2.weight + C.weight + GC.weight).

When getblocktemplate is called, the node greedily picks the ancestor set with the highest ancestor set feerate into the blocktemplate, updates the ancestor set information of all the remaining transactions in the affected cluster, then picks the next remaining ancestor set with the highest ancestor set feerate. If for example the ancestor set of Child had the highest ancestor set feerate, the blocktemplate assembling process might pick the four transactions { GP, P1, P2, C } into the block template together, and then update the ancestor set of Grandchild to just { GC } and its new ancestor set feerate to GC.fee / GC.weight.

This process continues until either the block is full or all transactions in the mempool have been picked. If an ancestor set is too big to fit in the block, it gets skipped in favor of a smaller ancestor set with a lower ancestor set feerate.

There is currently work on a project called Cluster Mempool which proposes to improve upon the ancestor set-based approach by assigning an order to all transactions within their cluster. This would allow to track segments in each cluster’s linearization that should be picked into a block template together in a way that would do away with the need to update the remainder of a cluster whenever something from it gets picked into the block template, and would allow for transaction sets with more complex topologies to be picked into a template together. You can find an overview of the Cluster Mempool proposal on Delving Bitcoin.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.