Skip to content

@tevm/txpool

The @tevm/txpool package provides a transaction pool (mempool) implementation for Tevm, managing pending transactions and their lifecycle within the Ethereum Virtual Machine.

Installation

npm install @tevm/txpool

Overview

The transaction pool is responsible for:

  • Managing pending transactions
  • Validating transaction requirements
  • Ordering transactions by price and nonce
  • Handling transaction replacement
  • Cleaning up stale transactions
  • Supporting transaction lifecycle management

API Reference

Core Class

TxPool

TxPool - The main transaction pool class with the following key features:

Constructor
new TxPool(options: TxPoolOptions)
Properties
  • BLOCKS_BEFORE_TARGET_HEIGHT_ACTIVATION: Number of blocks before chain head to start tx pool preparation
  • POOLED_STORAGE_TIME_LIMIT: Number of minutes to keep txs in the pool
  • HANDLED_CLEANUP_TIME_LIMIT: Number of minutes to forget about handled txs
  • pool: The central pool dataset mapping addresses to transactions
  • running: Boolean indicating if the pool is running
  • txsInPool: Number of transactions currently in the pool
Methods
  • add - Adds a transaction to the pool
  • addUnverified - Adds an unverified transaction to the pool
  • getByHash - Retrieves transactions by their hashes
  • removeByHash - Removes a transaction by its hash
  • txsByPriceAndNonce - Returns transactions sorted by price and nonce
  • cleanup - Performs pool cleanup
  • open - Opens the transaction pool
  • close - Closes the transaction pool
  • start - Starts transaction processing
  • stop - Stops transaction processing
  • deepCopy - Creates a deep copy of the pool

Usage Examples

Creating and Managing a Transaction Pool

import { TxPool } from '@tevm/txpool'
import { createCommon } from '@tevm/common'
 
const common = createCommon({ chain: 'mainnet' })
const txPool = new TxPool({
  common,
  maxPoolSize: 5000,
  minGasPriceBump: 10 // 10% price bump for replacement
})
 
// Start the pool
txPool.open()
txPool.start()

Adding Transactions

// Add a new transaction
await txPool.add(transaction, {
  requireSignature: true,
  skipBalance: false
})
 
// Add an unverified transaction
await txPool.addUnverified(transaction)

Retrieving Transactions

// Get transactions by hash
const txs = txPool.getByHash(txHashes)
 
// Get transactions by sender
const senderTxs = await txPool.getBySenderAddress(senderAddress)
 
// Get transactions ordered by price and nonce
const orderedTxs = await txPool.txsByPriceAndNonce({
  baseFee: 1000000000n,
  allowedBlobs: 3
})

Managing Transaction Lifecycle

// Remove a transaction
txPool.removeByHash(txHash)
 
// Remove transactions included in new blocks
txPool.removeNewBlockTxs(newBlocks)
 
// Perform cleanup of stale transactions
txPool.cleanup()

Pool Lifecycle Management

// Start the pool
txPool.open()
txPool.start()
 
// Stop the pool
txPool.stop()
txPool.close()
 
// Create a copy of the pool
const poolCopy = txPool.deepCopy(options)

Configuration

The transaction pool can be configured with various options:

interface TxPoolOptions {
  common: Common
  maxPoolSize?: number
  minGasPriceBump?: number
  minFeeBump?: number
  maxPendingTotal?: number
  maxPendingPerAccount?: number
  maxQueuedTotal?: number
  maxQueuedPerAccount?: number
  minPendingNodeBalance?: bigint
  minRemainingGasLimit?: bigint
}

Configuration Options

  • maxPoolSize: Maximum number of transactions in the pool
  • minGasPriceBump: Minimum price bump percentage for transaction replacement
  • minFeeBump: Minimum fee bump for transaction replacement
  • maxPendingTotal: Maximum number of pending transactions
  • maxPendingPerAccount: Maximum pending transactions per account
  • maxQueuedTotal: Maximum number of queued transactions
  • maxQueuedPerAccount: Maximum queued transactions per account
  • minPendingNodeBalance: Minimum balance required for pending transactions
  • minRemainingGasLimit: Minimum gas limit for remaining transactions

Error Handling

The transaction pool throws specific errors for various failure scenarios:

try {
  await txPool.add(transaction)
} catch (error) {
  if (error.code === 'POOL_FULL') {
    console.error('Transaction pool is full')
  } else if (error.code === 'UNDERPRICED') {
    console.error('Transaction is underpriced')
  } else if (error.code === 'NONCE_TOO_LOW') {
    console.error('Transaction nonce is too low')
  }
}

Best Practices

  1. Regular Cleanup: Call cleanup() periodically to remove stale transactions
  2. Transaction Replacement: Use appropriate gas price bumps for replacement transactions
  3. Pool Size Management: Monitor and adjust pool size limits based on network conditions
  4. Error Handling: Implement proper error handling for transaction additions and removals
  5. Lifecycle Management: Properly manage pool lifecycle with open(), start(), stop(), and close()

Related Packages

License

MIT