Overview
The mempool (memory pool) is a critical component that stores valid but unconfirmed transactions. It serves as a staging area for transactions before they are included in blocks and plays a key role in transaction relay, fee estimation, and block template construction. Primary file:src/txmempool.cpp and src/txmempool.h
Core Concepts
CTxMemPool Class
The main mempool class stores and manages unconfirmed transactions:- Transaction validation and storage
- Dependency tracking (parent/child relationships)
- Fee-based ordering for mining
- Cluster linearization for optimal block building
- Eviction when size limits are reached
Transaction Entry
Each transaction in the mempool has associated metadata:Transaction Graph (TxGraph)
TheTxGraph component manages transaction dependencies and cluster analysis:
Purpose
Separates graph-theoretical aspects from Bitcoin-specific logic:- Track parent/child relationships
- Partition mempool into connected clusters
- Compute optimal transaction orderings
- Enforce cluster size limits
Cluster Formation
Transactions are grouped into clusters based on spending relationships: Cluster properties:- Connected component of the transaction graph
- Transactions in a cluster may depend on each other
- Different clusters are completely independent
- Mining can select transactions cluster-by-cluster
Cluster Limits
To prevent DoS and ensure efficient processing:Linearization Algorithm
The mempool uses sophisticated algorithms to order transactions for optimal fee collection.Feerate Diagram
Transactions are analyzed using “feerate diagrams” that plot cumulative size vs. fees:Ancestor-Based Sorting
Traditional approach (pre-cluster linearization):-
Calculate ancestor score for each transaction:
- Select transactions in descending ancestor score order
- Ensures CPFP (Child Pays For Parent) works correctly
- Doesn’t account for descendants
- May not find optimal orderings
- Complex dependency tracking
Cluster Linearization
Modern approach usingcluster_linearize.h:
- Partition cluster into “chunks” (sets of transactions)
- Use search algorithm to find high-feerate chunks
- Order chunks by feerate
- Linearization is concatenation of chunk orderings
- Considers both ancestors and descendants
- Finds provably better orderings
- Bounded computation time
- Enables Replace-By-Fee improvements
Search Cost Limiting
- Quick search for most clusters
- Deeper search after mempool changes
- Accept “good enough” solutions for complex clusters
Mempool Admission
AcceptToMemoryPool Flow
Policy Rules
Transactions must meet policy requirements: Size and Weight:- Minimum size: 82 bytes (to prevent spam)
- Maximum weight: 400,000 (consensus limit)
- Maximum sigop cost: 80,000
- Minimum relay fee: 1 sat/vB (default)
- Incremental relay fee: Used for RBF
- Dynamic minimum based on mempool fullness
- P2PKH (Pay to Public Key Hash)
- P2SH (Pay to Script Hash)
- P2WPKH (Pay to Witness Public Key Hash)
- P2WSH (Pay to Witness Script Hash)
- P2TR (Pay to Taproot)
- Multisig (up to 3-of-3)
- Topologically Restricted Until Confirmation (TRUC)
- Limited to 1 ancestor, 1 descendant
- Enables package RBF
- Supports Lightning Network penalty transactions
Replace-By-Fee (RBF)
RBF allows replacing mempool transactions with higher-fee versions.BIP125 Rules
A replacement transaction must:- Signal replaceability: Original tx has sequence number < 0xfffffffe
- Pay higher fee: New tx pays more absolute fee
- Pay for bandwidth: Additional fee ≥ relay fee for new tx size
- Pay for replaced: Fee rate ≥ replaced transactions’ fee rates
- Limit conflicts: ≤ 100 replaced transactions
Implementation
AcceptToMemoryPool:
- Identify all conflicts (transactions spending same inputs)
- Check RBF rules
- Remove conflicting transactions and descendants
- Add new transaction
- Update graph and linearization
Package Acceptance
Package relay allows submitting multiple transactions together.Motivation
Individual transactions may not meet minimum fees, but as a package they do:Package Validation
- Child-with-unconfirmed-parents: Most common for CPFP
- 2-transaction TRUC: Lightning Network use case
- Validate each transaction individually (may fail on fees)
- Calculate package feerate
- Re-validate low-fee transactions with package context
- Accept package if total meets requirements
Eviction Policy
When mempool exceeds size limit (default: 300 MB):Eviction Algorithm
- Calculate target: Evict to get below limit
- Sort by modified feerate: Lowest first
- Evict with descendants: Can’t keep orphans
- Update graph: Recompute after eviction
Priority Adjustment
Node operators can prioritize transactions:- Mining pool policies
- Out-of-band fee agreements
- Emergency transaction acceleration
Memory Management
Memory Usage Tracking
- Transaction data
- Boost multi-index overhead
- TxGraph structures
- UTXO view cache
Size Limits
-maxmempool=<n> (in MB).
Indexes and Lookups
The mempool uses Boost.MultiIndex for efficient queries:- By txid: O(1) lookup by transaction ID
- By wtxid: O(1) lookup by witness transaction ID
- By time: Chronological ordering
Orphan Transactions
Orphans are transactions whose inputs aren’t in mempool or UTXO set:- Store orphan temporarily (max 100 by default)
- When parent arrives, retry orphan validation
- Expire old orphans (20 minutes)
- Limit total orphan memory
Fee Estimation
The mempool tracks confirmation times to estimate fees:- Record when transactions enter mempool
- Record when they confirm (and at what fee rate)
- Build statistical model of confirmation time vs. fee rate
- Estimate fee for desired confirmation time
ZMQ Notifications
Mempool events can be published via ZeroMQ:Mempool Persistence
Mempool state is saved on shutdown:- All transactions
- Entry times
- Fee deltas (prioritization)
- Load saved transactions
- Re-validate against current chain tip
- Reject now-invalid transactions
Testing and Simulation
Test Framework
Mempool Stress Testing
Performance Optimization
Caching Strategies
- Witness hash calculation: Cached in
CTransaction - Signature verification: Shared signature cache
- Coins view: Mempool-specific UTXO cache
Batch Operations
- Block connection: Remove many transactions atomically
- Graph updates: Defer recomputation until needed
- Linearization: Amortize cost across multiple changes