Documentation Index Fetch the complete documentation index at: https://cosmos-docs-evm-upgrade-7.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Cosmos EVM v0.5.0 introduces significant performance optimizations across gas estimation, state management, and transaction processing. This guide covers the improvements and provides optimization strategies for different use cases.
Gas Estimation Optimization
Smart Short-Circuit Detection
v0.5.0 introduces intelligent gas estimation that dramatically improves performance for common transaction types.
Plain Transfer Optimization
Performance Improvement: ~90% faster gas estimation for simple ETH transfers
// These transactions now estimate gas instantly (21000)
contract .call{value : 1 ether }( "" ); // Empty call to EOA
payable (recipient). transfer (amount); // Direct transfer
Implementation Details:
// Short-circuit logic for plain transfers
// Source: x/vm/keeper/grpc_query.go:414-422
if len ( msg . Data ) == 0 && msg . To != nil {
acct := k . GetAccountWithoutBalance ( ctx , * msg . To )
if acct == nil || ! acct . IsContract () {
// Return 21000 immediately without full execution
return & types . EstimateGasResponse { Gas : ethparams . TxGas }, nil
}
}
Optimistic Gas Bounds
Performance Improvement: Faster estimation for complex transactions through better initial bounds
// Uses actual execution results to optimize binary search
// Source: x/vm/keeper/grpc_query.go:450-452
optimisticGasLimit := ( result . MaxUsedGas + ethparams . CallStipend ) * 64 / 63
// Binary search starts with smarter bounds instead of blind search
if optimisticGasLimit < hi {
// Test optimistic limit first
if ! failed {
hi = optimisticGasLimit // Much faster convergence
}
}
Benefit: Reduces binary search iterations for complex contract interactions
Gas Estimation Benchmarks
Transaction Type v0.4.x Time v0.5.0 Time Improvement Simple Transfer ~50ms ~5ms 90% faster Contract Call ~100ms ~60ms 40% faster Contract Deploy ~200ms ~140ms 30% faster Complex DeFi ~300ms ~200ms 33% faster
State Management Optimization
EVM Instance Reduction
What Changed: Eliminated unnecessary EVM instance creation during balance checks
// Before (v0.4.x): Created full EVM instance for balance checks
func ( d CanTransferDecorator ) AnteHandle ( ... ) {
evm := d . evmKeeper . NewEVM ( ctx , msg , cfg , tracer , stateDB )
balance := evm . StateDB . GetBalance ( msg . From )
// Heavy operation for simple balance check
}
// After (v0.5.0): Direct keeper method
func CanTransfer ( ctx sdk . Context , evmKeeper EVMKeeper , msg core . Message , ... ) error {
balance := evmKeeper . GetAccount ( ctx , msg . From ). Balance
// Lightweight direct access
}
Performance Impact:
Ante Handler: 50-70% faster balance validation
Memory Usage: Reduced memory allocation during transaction validation
CPU Usage: Less computational overhead per transaction
Storage Empty Check Implementation
EIP Compliance: Implements proper storage empty checks per Ethereum standards
// Optimized storage operations with empty checks
func ( k Keeper ) SetState ( ctx sdk . Context , addr common . Address , key , value common . Hash ) {
if value == ( common . Hash {}) {
// Optimized path for storage deletion
k . deleteState ( ctx , addr , key )
return
}
// Standard storage set
k . setState ( ctx , addr , key , value )
}
Configuration-Based Optimization
v0.5.0’s configurable mempool enables fine-tuning for different performance requirements:
High-Throughput Configuration
// Optimized for maximum transaction volume
mempoolConfig := & evmmempool . EVMMempoolConfig {
LegacyPoolConfig : & legacypool . Config {
AccountSlots : 64 , // 4x more transactions per account
GlobalSlots : 16384 , // 4x more pending transactions
AccountQueue : 256 , // 4x larger queues
GlobalQueue : 4096 ,
PriceLimit : 1 , // Accept lowest gas prices
Lifetime : 6 * time . Hour , // Longer retention
},
BlockGasLimit : 200_000_000 , // Higher gas limit
}
Results:
Transaction Capacity: 4x more pending transactions
Account Throughput: 4x more transactions per account
Queue Depth: Better handling of transaction bursts
Low-Latency Configuration
// Optimized for fastest transaction processing
mempoolConfig := & evmmempool . EVMMempoolConfig {
LegacyPoolConfig : & legacypool . Config {
AccountSlots : 4 , // Faster iteration
GlobalSlots : 1024 , // Smaller pools
AccountQueue : 16 , // Quick processing
GlobalQueue : 256 ,
PriceLimit : 10 , // Higher minimum price
Lifetime : 30 * time . Minute , // Faster eviction
},
}
Results:
Selection Speed: Faster transaction selection for blocks
Memory Usage: Lower memory footprint
Eviction Time: Faster cleanup of stale transactions
Custom Priority Functions
Performance-Aware Priority: Optimize transaction ordering for specific use cases
Custom Priority Functions
// MEV-resistant priority function
func mevResistantPriority ( goCtx context . Context , tx sdk . Tx ) math . Int {
// Prioritize based on transaction age instead of just fees
feeTx , ok := tx .( sdk . FeeTx )
if ! ok {
return math . ZeroInt ()
}
basePriority := calculateFeePriority ( feeTx )
agePriority := calculateAgePriority ( tx ) // Factor in submission time
// Balanced priority prevents MEV front-running
return basePriority . Add ( agePriority )
}
// High-frequency trading priority
func hftPriority ( goCtx context . Context , tx sdk . Tx ) math . Int {
// Custom priority for time-sensitive protocols
for _ , msg := range tx . GetMsgs () {
if isArbitrageTx ( msg ) {
return math . NewInt ( 1000000 ) // Highest priority
}
if isLiquidationTx ( msg ) {
return math . NewInt ( 500000 ) // High priority
}
}
return standardPriority ( tx )
}
See all 28 lines
Block Processing Optimization
Notification Timing
What Changed: Improved block notification timing prevents funding errors
// Before: Block notifications could arrive too late
// After: Optimized timing ensures mempool updates before transaction processing
Benefits:
Reduced Errors: Fewer “insufficient funds” errors during block transitions
Better UX: More reliable transaction processing
Improved Reliability: Consistent mempool state management
Event Processing
EVM Log Optimization: EVM logs no longer emitted to cosmos-sdk events (commit fedc27f6)
// Before: Double emission increased processing overhead
// 1. EVM logs stored in transient state
// 2. EVM logs also emitted as Cosmos events
// After: Single emission path
// 1. EVM logs stored in transient state only
// 2. No duplicate Cosmos event emission
Performance Impact:
Event Processing: 40-50% faster event handling
Storage Efficiency: Reduced duplicate data storage
Network Bandwidth: Less event data propagated
Batch Processing Enhancements
DoS Protection: New batch processing limits prevent resource exhaustion
[ json-rpc ]
batch-request-limit = 1000 # Prevents batch DoS attacks
batch-response-max-size = 25000000 # Controls memory usage
max-open-connections = 100 # Connection limiting
Performance Tuning Examples:
Performance Configuration Examples
# High-performance API server
[ json-rpc ]
batch-request-limit = 5000
batch-response-max-size = 100000000
evm-timeout = "3s"
http-timeout = "15s"
# Resource-constrained node
[ json-rpc ]
batch-request-limit = 200
batch-response-max-size = 5000000
evm-timeout = "10s"
max-open-connections = 50
See all 13 lines
Access List Optimization
New RPC Method: eth_createAccessList enables transaction cost optimization
// Generate access list for gas optimization
const accessList = await provider . send ( "eth_createAccessList" , [{
to: contractAddress ,
data: contractInterface . encodeFunctionData ( "complexFunction" , [ arg1 , arg2 ]),
gasPrice: "0x" + gasPrice . toString ( 16 )
}, "latest" ]);
// Use access list in transaction for reduced gas costs
const tx = await contract . complexFunction ( arg1 , arg2 , {
accessList: accessList . accessList ,
gasLimit: accessList . gasUsed
});
Gas Savings: 5-15% reduction in gas costs for complex transactions
Optimization Strategies
Chain-Specific Tuning
DeFi-Focused Chain
// Optimized for DeFi protocols
mempoolConfig := & evmmempool . EVMMempoolConfig {
LegacyPoolConfig : & legacypool . Config {
AccountSlots : 32 , // Higher per-account limit
PriceBump : 25 , // Higher replacement threshold (MEV protection)
Lifetime : 30 * time . Minute , // Fast eviction
},
BlockGasLimit : 150_000_000 , // Optimized for complex contracts
}
// VM parameters
{
"history_serve_window" : 4096 , // Balanced for flash loan protocols
}
See all 14 lines
Gaming Chain
Gaming Chain Configuration
// Optimized for high transaction volume, low complexity
mempoolConfig := & evmmempool . EVMMempoolConfig {
LegacyPoolConfig : & legacypool . Config {
AccountSlots : 128 , // Many small transactions per player
GlobalSlots : 32768 , // Very high global capacity
PriceLimit : 1 , // Accept very low gas prices
Lifetime : 10 * time . Minute , // Fast turnover
},
}
// VM parameters
{
"history_serve_window" : 1024 , // Lower storage overhead
}
See all 14 lines
Enterprise/Private Chain
Enterprise Chain Configuration
// Optimized for predictable, high-value transactions
mempoolConfig := & evmmempool . EVMMempoolConfig {
LegacyPoolConfig : & legacypool . Config {
AccountSlots : 16 , // Standard capacity
GlobalSlots : 4096 , // Standard global capacity
PriceLimit : 100 , // Higher minimum price
PriceBump : 50 , // High replacement threshold
Lifetime : 24 * time . Hour , // Long retention
},
}
// VM parameters
{
"history_serve_window" : 16384 , // Extended history for audit trails
}
See all 15 lines
Monitoring and Metrics
Transaction Pool Metrics:
# Monitor mempool performance
curl -s http://localhost:6065/debug/metrics/prometheus | grep txpool
Gas Estimation Performance:
# Time gas estimation calls
time cast estimate --rpc-url http://localhost:8545 \
$CONTRACT_ADDRESS "complexFunction()" --from $ADDRESS
RPC Performance:
# Test batch processing performance
time curl -X POST \
-H "Content-Type: application/json" \
--data '[{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}, ...]' \
http://localhost:8545
Optimization Validation
Before Optimization:
# Capture baseline metrics
curl -s http://localhost:6065/debug/metrics/prometheus > baseline-metrics.txt
ab -n 1000 -c 10 'http://localhost:8545/[json-rpc-call]'
After Optimization:
# Compare optimized performance
curl -s http://localhost:6065/debug/metrics/prometheus > optimized-metrics.txt
ab -n 1000 -c 10 'http://localhost:8545/[json-rpc-call]'
diff baseline-metrics.txt optimized-metrics.txt
Best Practices
Development Environment
Development Environment Configuration
# Optimized for development speed
[ json-rpc ]
evm-timeout = "30s" # Longer timeout for debugging
gas-cap = 100000000 # Higher cap for testing
enable-profiling = true # Enable debugging (NEVER in production)
[ evm ]
tracer = "json" # Detailed execution traces
cache-preimage = true # Enable preimage tracking
See all 9 lines
Production Environment
Production Environment Configuration
# Optimized for production performance and security
[ json-rpc ]
evm-timeout = "3s" # Fast timeout
gas-cap = 25000000 # Standard cap
batch-request-limit = 1000 # DoS protection
batch-response-max-size = 25000000
enable-profiling = false # Security (NEVER enable)
[ evm ]
tracer = "" # No tracing overhead
cache-preimage = false # No preimage tracking
max-tx-gas-wanted = 10000000 # Reasonable ante limit
See all 12 lines
Load Testing
# Test transaction throughput
for i in { 1..1000} ; do
cast send --rpc-url http://localhost:8545 \
--private-key $PRIVATE_KEY \
$CONTRACT_ADDRESS \
"fastFunction()" &
done
wait
# Monitor mempool during load
watch 'curl -s -X POST \
-H "Content-Type: application/json" \
--data "{\"jsonrpc\":\"2.0\",\"method\":\"txpool_status\",\"params\":[],\"id\":1}" \
http://localhost:8545 | jq'
See all 14 lines
Slow Gas Estimation
Symptoms:
eth_estimateGas taking > 100ms consistently
Timeouts during gas estimation
Solutions:
# Increase timeout for complex contracts
[ json-rpc ]
evm-timeout = "10s"
# Or optimize at chain level
[ evm ]
max-tx-gas-wanted = 5000000 # Lower ante gas limit
Mempool Congestion
Symptoms:
Transactions stuck in pending state
“txpool is full” errors
Solutions:
// Increase mempool capacity
LegacyPoolConfig : & legacypool . Config {
GlobalSlots : 8192 , // 2x standard capacity
AccountSlots : 32 , // 2x per-account limit
GlobalQueue : 2048 , // 2x queue capacity
}
High Memory Usage
Symptoms:
Node memory usage consistently high
Out-of-memory errors during high load
Solutions:
// Reduce mempool memory footprint
LegacyPoolConfig : & legacypool . Config {
AccountSlots : 8 , // Lower per-account limit
GlobalSlots : 2048 , // Lower global capacity
Lifetime : 1 * time . Hour , // Faster eviction
}
Key Metrics to Track
# Transaction pool health
txpool_pending_gauge
txpool_queued_gauge
txpool_pending_discard_meter
# Gas estimation performance
eth_estimateGas_duration_histogram
eth_call_duration_histogram
# RPC performance
jsonrpc_batch_requests_total
jsonrpc_batch_response_size_histogram
http_request_duration_seconds
See all 13 lines
Alerting Thresholds
# Recommended alerting thresholds
mempool_pending_transactions : > 1000
mempool_queued_transactions : > 500
gas_estimation_p99_latency : > 200ms
rpc_error_rate : > 5%
block_processing_time : > 2s
Advanced Optimization Techniques
Custom Transaction Lifecycle
// Implement custom broadcast function for performance
BroadcastTxFn : func ( txs [] * ethtypes . Transaction ) error {
// Batch broadcast for efficiency
return batchBroadcastTransactions ( txs , batchSize = 50 )
}
State Preloading
// Preload frequently accessed state
func ( k Keeper ) PreloadState ( ctx sdk . Context , addresses [] common . Address ) {
for _ , addr := range addresses {
// Warm cache with frequently accessed accounts
k . GetAccount ( ctx , addr )
}
}
Gas Price Oracle Optimization
// Custom gas price calculation for better estimation
func optimizedGasPrice ( baseFee * big . Int , urgency string ) * big . Int {
switch urgency {
case "immediate" :
return new ( big . Int ). Mul ( baseFee , big . NewInt ( 2 ))
case "fast" :
return new ( big . Int ). Mul ( baseFee , big . NewInt ( 150 )). Div ( big . NewInt ( 100 ))
case "standard" :
return new ( big . Int ). Mul ( baseFee , big . NewInt ( 110 )). Div ( big . NewInt ( 100 ))
default :
return baseFee
}
}
Benchmark Suite
# Run performance benchmarks
cd /Users/cordt/repos/evm
go test -bench=. -benchmem ./x/vm/keeper/
go test -bench=. -benchmem ./mempool/
# RPC performance testing
go test -bench=BenchmarkRPC ./rpc/namespaces/ethereum/eth/
Load Testing Scripts
// Ethereum tooling load test
const { ethers } = require ( "ethers" );
async function loadTest () {
const provider = new ethers . JsonRpcProvider ( "http://localhost:8545" );
const wallet = new ethers . Wallet ( privateKey , provider );
// Send 1000 transactions concurrently
const promises = [];
for ( let i = 0 ; i < 1000 ; i ++ ) {
promises . push (
wallet . sendTransaction ({
to: "0x..." ,
value: ethers . parseEther ( "0.001" ),
nonce: await wallet . getNonce () + i ,
})
);
}
const start = Date . now ();
await Promise . allSettled ( promises );
const duration = Date . now () - start ;
console . log ( `Processed 1000 transactions in ${ duration } ms` );
}
See all 25 lines
References