Mempool Specification
The Zebra mempool handles unmined Zcash transactions: collecting them from peers, verifying them, storing them in memory, providing APIs for other components to access them, and gossiping transactions to peers. This document specifies the architecture, behavior, and interfaces of the mempool.
Overview
The mempool is a fundamental component of the Zebra node, responsible for managing the lifecycle of unmined transactions. It provides an in-memory storage for valid transactions that haven't yet been included in a block, and offers interfaces for other components to interact with these transactions.
Key responsibilities of the mempool include:
- Accepting new transactions from the network
- Verifying transactions against a subset of consensus rules
- Storing verified transactions in memory
- Managing memory usage and transaction eviction
- Providing transaction queries to other components
- Gossiping transactions to peers
Architecture
The mempool is comprised of several subcomponents:
-
Mempool Service (
Mempool
): The main service that handles requests from other components, manages the active state of the mempool, and coordinates the other subcomponents. -
Transaction Storage (
Storage
): Manages the in-memory storage of verified transactions and rejected transactions, along with their rejection reasons. -
Transaction Downloads (
Downloads
): Handles downloading and verifying transactions, coordinating with the network and verification services. -
Crawler (
Crawler
): Periodically polls peers for new transactions to add to the mempool. -
Queue Checker (
QueueChecker
): Regularly checks the transaction verification queue to process newly verified transactions. -
Transaction Gossip (
gossip
): Broadcasts newly added transactions to peers. -
Pending Outputs (
PendingOutputs
): Tracks requests for transaction outputs that haven't yet been seen.
For a visual representation of the architecture and transaction flow, see the Mempool Architecture Diagram.
Activation
The mempool is activated when:
- The node is near the blockchain tip (determined by
SyncStatus
) - OR when the current chain height reaches a configured debug height (
debug_enable_at_height
)
When activated, the mempool creates transaction download and verify services, initializes storage, and starts background tasks for crawling and queue checking.
Configuration
The mempool has the following configurable parameters:
-
Transaction Cost Limit (
tx_cost_limit
): The maximum total serialized byte size of all transactions in the mempool, defaulting to 80,000,000 bytes as required by ZIP-401. -
Eviction Memory Time (
eviction_memory_time
): The maximum time to remember evicted transaction IDs in the rejection list, defaulting to 60 minutes. -
Debug Enable At Height (
debug_enable_at_height
): An optional height at which to enable the mempool for debugging, regardless of sync status.
State Management
The mempool maintains an ActiveState
which can be either:
Disabled
: Mempool is not activeEnabled
: Mempool is active and contains:storage
: The Storage instance for transactionstx_downloads
: Transaction download and verification streamlast_seen_tip_hash
: Hash of the last chain tip the mempool has seen
The mempool responds to chain tip changes:
- On new blocks: Updates verification context, removes mined transactions
- On reorgs: Clears tip-specific rejections, retries all transactions
Transaction Processing Flow
-
Transaction Arrival:
- From peer gossip (inv messages)
- From direct submission (RPC)
- From periodic peer polling (crawler)
-
Transaction Download:
- Checks if transaction exists in mempool or rejection lists
- Queues transaction for download if needed
- Downloads transaction data from peers
-
Transaction Verification:
- Checks transaction against consensus rules
- Verifies transaction against the current chain state
- Manages dependencies between transactions
-
Transaction Storage:
- Stores verified transactions in memory
- Tracks transaction dependencies
- Enforces size limits and eviction policies
-
Transaction Gossip:
- Broadcasts newly verified transactions to peers
Transaction Rejection
Transactions can be rejected for multiple reasons, categorized into:
-
Exact Tip Rejections (
ExactTipRejectionError
):- Failures in consensus validation
- Only applies to exactly matching transactions at the current tip
-
Same Effects Tip Rejections (
SameEffectsTipRejectionError
):- Spending conflicts with other mempool transactions
- Missing outputs from mempool transactions
- Applies to any transaction with the same effects at the current tip
-
Same Effects Chain Rejections (
SameEffectsChainRejectionError
):- Expired transactions
- Duplicate spends already in the blockchain
- Transactions already mined
- Transactions evicted due to memory limits
- Applies until a rollback or network upgrade
Rejection reasons are stored alongside rejected transaction IDs to prevent repeated verification of invalid transactions.
Memory Management
The mempool employs several strategies for memory management:
-
Transaction Cost Limit: Enforces a maximum total size for all mempool transactions.
-
Random Eviction: When the mempool exceeds the cost limit, transactions are randomly evicted following the ZIP-401 specification.
-
Eviction Memory: Remembers evicted transaction IDs for a configurable period to prevent re-verification.
-
Rejection List Size Limit: Caps rejection lists at 40,000 entries per ZIP-401.
-
Automatic Cleanup: Removes expired transactions and rejections that are no longer relevant.
Service Interface
The mempool exposes a service interface with the following request types:
-
Query Requests:
TransactionIds
: Get all transaction IDs in the mempoolTransactionsById
: Get transactions by their unmined IDsTransactionsByMinedId
: Get transactions by their mined hashesFullTransactions
: Get all verified transactions with fee informationRejectedTransactionIds
: Query rejected transaction IDsTransactionWithDepsByMinedId
: Get a transaction and its dependencies
-
Action Requests:
Queue
: Queue transactions or transaction IDs for download and verificationCheckForVerifiedTransactions
: Check for newly verified transactionsAwaitOutput
: Wait for a specific transparent output to become available
Interaction with Other Components
The mempool interacts with several other Zebra components:
-
Network Service: For downloading transactions and gossiping to peers.
-
State Service: For checking transaction validity against the current chain state.
-
Transaction Verifier: For consensus validation of transactions.
-
Chain Tip Service: For tracking the current blockchain tip.
-
RPC Services: To provide transaction data for RPC methods.
Implementation Constraints
-
Correctness:
- All transactions in the mempool must be verified
- Transactions must be re-verified when the chain tip changes
- Rejected transactions must be properly tracked to prevent DoS attacks
-
Performance:
- Transaction processing should be asynchronous
- Memory usage should be bounded
- Critical paths should be optimized for throughput
-
Reliability:
- The mempool should recover from crashes and chain reorganizations
- Background tasks should be resilient to temporary failures
ZIP-401 Compliance
The mempool implements the requirements specified in ZIP-401:
- Implements
mempooltxcostlimit
configuration (default: 80,000,000) - Implements
mempoolevictionmemoryminutes
configuration (default: 60 minutes) - Uses random eviction when the mempool exceeds the cost limit
- Caps eviction memory lists at 40,000 entries
- Uses transaction IDs (txid) for version 5 transactions in eviction lists
Error Handling
The mempool employs a comprehensive error handling strategy:
-
Temporary Failures: For network or resource issues, transactions remain in the queue for retry.
-
Permanent Rejections: For consensus or semantic failures, transactions are rejected with specific error reasons.
-
Dependency Failures: For missing inputs or dependencies, transactions may wait for dependencies to be resolved.
-
Recovery: On startup or after a crash, the mempool is rebuilt from scratch.
Metrics and Diagnostics
The mempool provides metrics for monitoring:
- Transaction Count: Number of transactions in the mempool
- Total Cost: Total size of all mempool transactions
- Queued Count: Number of transactions pending download or verification
- Rejected Count: Number of rejected transactions in memory
- Background Task Status: Health of crawler and queue checker tasks