Overview
The Mempool manages pending transactions waiting to be included in a block. It provides efficient storage, retrieval, and ordering of transactions with support for capacity limits and gas price prioritization.
Mempool
Transaction mempool for managing pending transactions.
Constructor
Create a new mempool with default configuration.Default configuration:
max_transactions: 10,000
max_per_account: 100
Create a new mempool with custom configuration.pub fn with_config(config: MempoolConfig) -> Self
Custom mempool configuration
Query Methods
len
Get the number of transactions in the mempool.pub fn len(&self) -> usize
Returns the total number of transactions
is_empty
Check if the mempool is empty.pub fn is_empty(&self) -> bool
Returns true if no transactions are present
contains
Check if a transaction is in the mempool.pub fn contains(&self, tx_hash: &Hash) -> bool
The hash of the transaction to check
Returns true if the transaction exists in the mempool
get
Get a transaction from the mempool.pub fn get(&self, tx_hash: &Hash) -> Option<&Transaction>
The hash of the transaction to retrieve
Returns the transaction if found, None otherwise
Modification Methods
add
Add a transaction to the mempool.pub fn add(&mut self, tx: Transaction) -> Result<()>
Returns Ok(()) on success, or:
MempoolError::DuplicateTransaction if already exists
MempoolError::MempoolFull if capacity exceeded
remove
Remove a transaction from the mempool.pub fn remove(&mut self, tx_hash: &Hash) -> Result<Transaction>
The hash of the transaction to remove
Returns the removed transaction or MempoolError::TransactionNotFound
remove_batch
Remove multiple transactions from the mempool.pub fn remove_batch(&mut self, tx_hashes: &[Hash])
Array of transaction hashes to remove
clear
Clear all transactions from the mempool.
Retrieval Methods
get_by_sender
Get all transactions from a specific sender.pub fn get_by_sender(&self, sender: &Address) -> Vec<Transaction>
Returns all transactions from the sender
get_next_for_sender
Get the next transaction for a sender (lowest nonce).pub fn get_next_for_sender(&self, sender: &Address) -> Option<Transaction>
Returns the transaction with the lowest nonce for this sender
get_by_gas_price
Get transactions ordered by gas price (highest first).pub fn get_by_gas_price(&self, limit: usize) -> Vec<Transaction>
Maximum number of transactions to return
Returns up to limit transactions, sorted by gas price descending
get_pending
Get pending transactions for block building.Returns transactions ordered by gas price. In a production implementation, this would validate nonces against current state and respect account dependencies.pub fn get_pending(&self, limit: usize) -> Vec<Transaction>
Maximum number of transactions to return
Returns up to limit executable transactions
get_all
Get all transactions in the mempool.pub fn get_all(&self) -> Vec<Transaction>
Returns all transactions (unordered)
stats
Get mempool statistics.pub fn stats(&self) -> MempoolStats
Returns current mempool statistics
MempoolConfig
Configuration for mempool behavior.
pub struct MempoolConfig {
pub max_transactions: usize,
pub max_per_account: usize,
}
Maximum total number of transactions in the mempool (default: 10,000)
Maximum transactions per account (default: 100)
MempoolStats
Statistics about the current mempool state.
pub struct MempoolStats {
pub total_transactions: usize,
pub unique_senders: usize,
pub capacity: usize,
}
Total number of transactions in the mempool
Number of unique sender addresses
Maximum capacity of the mempool
MempoolError
Errors that can occur during mempool operations.
pub enum MempoolError {
DuplicateTransaction,
MempoolFull(usize),
TransactionNotFound,
}
Transaction already exists in the mempool
Mempool has reached capacity limit
Transaction not found in mempool
Usage Example
use minichain_chain::{Mempool, MempoolConfig};
use minichain_core::{Transaction, Keypair, Address};
// Create mempool with custom config
let config = MempoolConfig {
max_transactions: 5000,
max_per_account: 50,
};
let mut mempool = Mempool::with_config(config);
// Add transactions
let keypair = Keypair::generate();
let from = keypair.address();
let to = Address::from_bytes([2u8; 20]);
let tx1 = Transaction::transfer(from, to, 1000, 0, 10).signed(&keypair);
let tx2 = Transaction::transfer(from, to, 2000, 1, 20).signed(&keypair);
mempool.add(tx1).unwrap();
mempool.add(tx2).unwrap();
println!("Mempool size: {}", mempool.len());
// Get transactions by gas price
let top_txs = mempool.get_by_gas_price(10);
println!("Top transaction has gas price: {}", top_txs[0].gas_price);
// Get transactions for a specific sender
let sender_txs = mempool.get_by_sender(&from);
println!("Sender has {} pending transactions", sender_txs.len());
// Get pending transactions for block building
let pending = mempool.get_pending(100);
println!("Got {} transactions for block", pending.len());
// Check if transaction exists
let tx_hash = tx1.hash();
if mempool.contains(&tx_hash) {
println!("Transaction is in mempool");
}
// Remove transaction
mempool.remove(&tx_hash).unwrap();
// Get statistics
let stats = mempool.stats();
println!("Total: {}, Senders: {}, Capacity: {}",
stats.total_transactions,
stats.unique_senders,
stats.capacity
);
// Clear all transactions
mempool.clear();
assert!(mempool.is_empty());
Implementation Details
The mempool uses multiple data structures for efficient operations:
- HashMap by hash: O(1) transaction lookup by hash
- HashMap by sender: O(1) sender transaction retrieval
- HashSet: O(1) existence checks
- VecDeque per sender: Preserves transaction order by nonce
See Also