The Blockchain Chief Bitcoin Book / Part III: Validation & Consensus
Chapter 11

Advanced Mempool & Policy

Cluster mempool, transaction linearization, TRUC (v3) transactions, ephemeral anchors, and the modern policy framework that enables Layer 2 protocols.

Cluster Mempool

Chapter 6 introduced the mempool as a pool of unconfirmed transactions. This chapter goes deeper into how the mempool actually orders those transactions for mining, eviction, and relay. The modern approach is called cluster mempool.

The Problem with Ancestor Sets

The traditional mempool tracked "ancestor fee rate" for each transaction: the combined fee rate of a transaction and all its unconfirmed ancestors. This had serious problems:

Clusters and Connected Components

The cluster mempool redesign groups transactions into clusters: connected components in the dependency graph. If transaction A is an ancestor or descendant of transaction B (through any chain of parent-child relationships), they belong to the same cluster.

💡 Key Insight

A cluster is a self-contained unit: all transactions within it depend on each other (directly or transitively), and no transaction outside the cluster depends on or is depended upon by any transaction inside. This means clusters can be analyzed independently.

Bitcoin Core enforces a cluster size limit (currently 64 transactions). This bounds the computational cost of optimizing transaction ordering within each cluster.

max MAX_CLUSTER_COUNT_LIMIT 64 transactions per cluster
property Connected Every tx reachable from every other through parent/child chains
property Independent No dependencies to transactions outside the cluster

Transaction Linearization

Once transactions are grouped into clusters, each cluster needs a linearization: a total ordering of its transactions that respects dependencies (parents before children) and optimizes for fee rate.

Why Linearization Matters

A miner filling a block wants to include the highest-fee-rate transactions first. But dependencies complicate this: you can't include a child without its parent. Linearization solves this by finding the best order to process transactions.

Chunks

A linearization is divided into chunks: groups of consecutive transactions that would be mined together. Each chunk has a fee rate (total fees / total size), and chunks are ordered by decreasing fee rate.

💡 Chunk Decomposition

Given a linearization, take the highest-fee-rate prefix (the longest prefix whose fee rate is at least as high as any sub-prefix). That's the first chunk. Remove it and repeat for the rest. Each chunk always consists of connected transactions.

The DepGraph Data Structure

The linearization algorithms work on a DepGraph (dependency graph): a template class in cluster_linearize.h that stores:

Using bitmasks (SetType) for ancestor/descendant sets allows extremely fast subset operations, intersections, and unions: all O(1) with bitwise operators.

The Search Algorithm

Finding the optimal linearization is NP-hard in general. Bitcoin Core uses a bounded search algorithm that:

  1. Starts with a seed: the highest individual fee rate transaction (plus its ancestors) as the initial "best" chunk candidate.
  2. Explores improvements: tries adding/removing transactions to find a higher fee rate subset.
  3. Respects a budget: the search is bounded by an iteration limit to keep it fast.
  4. Produces optimal or near-optimal results: for small clusters (≤ ~16 transactions), the search finds the true optimum; for larger clusters, it produces a good approximation.

TxGraph: The Mempool's Core Data Structure

TxGraph (defined in txgraph.h) is the data structure that manages all the clusters, their linearizations, and the transactions within them.

Key Design Features

Core Operations

AddTransaction(feerate) Create a new transaction with given fee/size
AddDependency(parent, child) Record that child spends an output of parent
GetMainChunkFeerate(ref) Get the chunk fee rate for a transaction's chunk
StartStaging() Begin a tentative set of changes
CommitStaging() Apply the staged changes to the main graph
AbortStaging() Discard the staged changes

TRUC (v3) Transactions

TRUC transactions (Topologically Restricted Until Confirmation), defined in BIP 431, are a special transaction version (nVersion = 3) with strict topology rules that make RBF replacements more predictable.

The Problem TRUC Solves

Lightning Network and other Layer 2 protocols need to broadcast "commitment transactions" that can be fee-bumped reliably. With normal transactions, complex dependency chains (parent-child-grandchild) make RBF unpredictable and sometimes impossible. TRUC constrains the topology to make fee-bumping always work.

TRUC Rules

rule 1-Parent-1-Child At most 1 unconfirmed parent and 1 unconfirmed child
limit TRUC_MAX_VSIZE Parent tx max 10,000 vbytes
limit TRUC_CHILD_MAX_VSIZE Child tx max 1,000 vbytes
rule Version Matching TRUC parents can only have TRUC children, and vice versa

How TRUC Enables Fee Bumping

Because a TRUC transaction can only have one child, replacing that child (via RBF) is simple and always works:

Alice broadcasts TRUC parentHer Lightning commitment tx enters the mempool
Fees are too lowThe transaction isn't getting mined
Alice creates TRUC childA small (≤ 1 kvB) child that CPFP-bumps the parent
Still not enough?Alice replaces the child with a higher-fee version. Always possible because there's only one child.

Sibling Eviction

If a TRUC parent already has a child, and a new higher-fee child arrives, the mempool can evict the existing child to make room for the new one. This "sibling eviction" is safe because TRUC guarantees only one child exists.

Ephemeral Anchors

Ephemeral anchors build on TRUC to enable a powerful fee-bumping pattern for Layer 2 protocols. The idea is simple: a parent transaction can have zero fees and a dust output, as long as a child immediately spends that dust.

How It Works

  1. Parent transaction (0 fee): creates a dust output (the "anchor") using an OP_TRUE or anyone-can-spend script. The parent has no fee, making it unmineable on its own.
  2. Child transaction (brings fee): spends the anchor output, providing all the fees for both transactions. The child must spend ALL dust outputs from the parent.
💡 Why Ephemeral Anchors?

In Lightning, both channel parties need the ability to fee-bump a commitment transaction. Ephemeral anchors let the commitment tx be fee-free, and whichever party broadcasts it adds fees via the anchor child. This eliminates the need to pre-guess fees when creating the commitment transaction.

Safety Guarantees

Package RBF

Package RBF extends Replace-By-Fee from single transactions to packages (parent + child submitted together). This solves the problem where a parent transaction's fee is too low to enter the mempool on its own.

How Package RBF Works

  1. Submit parent + child as a package: the parent may be below the minimum relay fee, but the child's fee compensates.
  2. Evaluate as a unit: the package fee rate (combined fee / combined size) is checked against what it replaces.
  3. Replace existing conflicts: if the package fee rate is high enough, it replaces conflicting transactions.
⚠️ Package Limits

Package relay currently supports only 1-parent-1-child (CPFP) packages. Multi-parent or multi-generation packages are not yet supported. TRUC transactions are the primary users of package relay.

Why This Matters for Layer 2

TRUC + ephemeral anchors + package relay together solve one of the hardest problems in Layer 2 protocol design: reliable fee bumping for pre-signed transactions.

Lightning Network

Commitment transactions can use TRUC + ephemeral anchors. Either party can fee-bump unilateral closes without pre-guessing fee levels.

🔗

Cluster Mempool

TRUC's 1-parent-1-child rule guarantees small clusters, keeping linearization fast and RBF checks simple.

📦

Package Relay

Zero-fee TRUC parents couldn't enter the mempool alone. Package relay lets them arrive with their fee-paying child.