Skip to main content

Overview

This guide provides step-by-step instructions for integrating the EVM mempool into your Cosmos EVM chain. For conceptual information about mempool design and architecture, see the Mempool Concepts page.

Step 1: Add EVM Mempool to App Struct

Step 2: Configure Mempool in NewApp Constructor

The mempool must be initialized after the antehandler has been set in the app.
Add the following configuration in your NewApp constructor:
Breaking Change from v0.4.x: The global mempool registry (SetGlobalEVMMempool) has been removed. Mempool is now passed directly to the JSON-RPC server during initialization.

Configuration Options

The EVMMempoolConfig struct provides several configuration options for customizing the mempool behavior:
For most use cases, the minimal configuration is sufficient:

Defaults and Fallbacks

  • If BlockGasLimit is 0, the mempool uses a fallback of 100_000_000 gas.
  • If LegacyPoolConfig is not provided, defaults from legacypool.DefaultConfig are used.
  • If CosmosPoolConfig is not provided, a default PriorityNonceMempool is created with:
    • Priority = (fee_amount / gas_limit) in the chain bond denom
    • Comparator = big-int comparison (higher is selected first)
    • MinValue = 0
  • If BroadcastTxFn is not provided, a default is created that uses the app clientCtx/txConfig to broadcast EVM transactions when they are promoted from queued → pending.
  • MinTip is optional. If unset, selection uses the effective tip from each tx (min(gas_tip_cap, gas_fee_cap - base_fee)).

v0.4.x to v0.5.0 Migration

Breaking Change: Pre-built pools replaced with configuration objects PR #496 replaced pre-built pools with configs in EVMMempoolConfig:
  • Removed: TxPool *txpool.TxPool, CosmosPool sdkmempool.ExtMempool
  • Added: LegacyPoolConfig *legacypool.Config, CosmosPoolConfig *sdkmempool.PriorityNonceMempoolConfig[math.Int]

Minimal Setups: Nothing to Change

If you use the default mempool wiring (no custom pools), your existing code continues to work:

Advanced Setups: Migrate Your Customizations

If you built custom pools yourself, replace them with configuration objects: Before (v0.4.x):
After (v0.5.0):

Custom Legacy Pool Configuration

Customize EVM transaction pool parameters:

Custom Cosmos Mempool Configuration

The mempool uses a PriorityNonceMempool for Cosmos transactions by default. You can customize the priority calculation:

Custom Broadcast Function

Override the default broadcast behavior for promoted EVM transactions:

Custom Block Gas Limit

Different chains may require different gas limits based on their capacity:

Event Bus Integration

For best results, connect the mempool to CometBFT’s EventBus so it can react to finalized blocks:
This enables chain-head notifications so the mempool can promptly promote/evict transactions when blocks are committed.

Architecture Components

The EVM mempool consists of several key components:

ExperimentalEVMMempool

The main coordinator implementing Cosmos SDK’s ExtMempool interface (mempool/mempool.go). Key Methods:
  • Insert(ctx, tx): Routes transactions to appropriate pools
  • Select(ctx, filter): Returns unified iterator over all transactions
  • Remove(tx): Handles transaction removal with EVM-specific logic
  • InsertInvalidNonce(txBytes): Queues nonce-gapped EVM transactions locally

CheckTx Handler

Custom transaction validation that handles nonce gaps specially (mempool/check_tx.go). Special Handling: On ErrNonceGap for EVM transactions:

TxPool

Direct port of Ethereum’s transaction pool managing both pending and queued transactions (mempool/txpool/). Key Features:
  • Uses vm.StateDB interface for Cosmos state compatibility
  • Implements BroadcastTxFn callback for transaction promotion
  • Cosmos-specific reset logic for instant finality

PriorityNonceMempool

Standard Cosmos SDK mempool for non-EVM transactions with fee-based prioritization. Default Priority Calculation:

Transaction Type Routing

The mempool handles different transaction types appropriately:

Ethereum Transactions (MsgEthereumTx)

  • Tier 1 (Local): EVM TxPool handles nonce gaps and promotion
  • Tier 2 (Network): CometBFT broadcasts executable transactions

Cosmos Transactions (Bank, Staking, Gov, etc.)

  • Direct to Tier 2: Always go directly to CometBFT mempool
  • Standard Flow: Follow normal Cosmos SDK validation and broadcasting
  • Priority-Based: Use PriorityNonceMempool for fee-based ordering

Unified Transaction Selection

During block building, both transaction types compete fairly based on their effective tips:
Fee Comparison:
  • EVM: gas_tip_cap or min(gas_tip_cap, gas_fee_cap - base_fee)
  • Cosmos: (fee_amount / gas_limit) - base_fee
  • Selection: Higher effective tip gets selected first

Testing Your Integration

Verify Nonce Gap Handling

Test that transactions with nonce gaps are properly queued:

Test Transaction Replacement

Verify that higher-fee transactions replace lower-fee ones:

Verify Batch Deployments

Test typical deployment scripts (like Uniswap) that send many transactions at once:

Monitoring and Debugging

Use the txpool RPC methods to monitor mempool state:
  • txpool_status: Get pending and queued transaction counts
  • txpool_content: View all transactions in the pool
  • txpool_inspect: Get human-readable transaction summaries
  • txpool_contentFrom: View transactions from specific addresses