~/.evmd/config/app.toml. This guide covers parameters unique to the EVM implementation.
- EVM
- Mempool
- JSON-RPC
- Runtime Flags
- Application Config
- Genesis Config
- Validator Nodes
EVM execution environment configuration.
Controls VM execution tracing for debugging.Valid Options:
""- Disabled (default)"json"- Full execution trace in JSON format, used by debug_traceTransaction RPC"struct"- Go struct format for programmatic processing"access_list"- Generates EIP-2930 access lists for gas optimization"markdown"- Human-readable format for manual analysis
server/config/config.go:139
Implementation: x/vm/keeper/state_transition.go:150-157Limits gas for transactions in CheckTx mode to prevent DoS attacks.When set to 0, any gas amount is accepted which can lead to mempool spam.Source:
server/config/config.go:141
Testnet Default: Set by evmd/cmd/evmd/cmd/testnet.go:303Enables SHA3 preimage recording in the VM for debugging tools to reverse hash lookups.Increases memory usage when enabled.Source:
server/config/config.go:143EIP-155 replay protection chain ID.Must match the expected network chain ID. Used for transaction signing validation.Source:
server/config/config.go:145
Used in: x/vm/genesis.go:22Minimum priority fee (tip) required for transaction inclusion in mempool.Transactions with tips below this value may be rejected. Set to 0 to disable filtering.Flag:
EVMMinTip
Source: server/config/config.go:150
Type: Converted to uint256.Int internallyAddress for go-ethereum metrics server.Emits EVM-specific metrics in Prometheus format on a separate server from Cosmos SDK metrics.Source:
server/config/config.go:152
New in: v0.5.0EVM mempool configuration for transaction pool management.Low-Resource Node:Strict Spam Protection:
New in v0.5.0: Mempool configuration is now fully exposed in
app.toml and can be adjusted without code changes. Previously, these settings were hardcoded.Minimum gas price to enforce for acceptance into the pool (in wei).Transactions with gas prices below this value are rejected from the mempool.Source:
server/config/config.go:160
Validation: Must be at least 1Minimum price bump percentage to replace an already existing transaction (nonce).When replacing a transaction with the same nonce, the new transaction must have a gas price at least this percentage higher.Source:
server/config/config.go:162
Example: 10 = require 10% higher gas price
Validation: Must be at least 1Number of executable transaction slots guaranteed per account.Each account is guaranteed to have this many pending transactions in the executable queue.Source:
server/config/config.go:164
Validation: Must be at least 1Maximum number of executable transaction slots for all accounts.Total capacity for all pending executable transactions across all accounts (4096 + 1024 = 5120).Source:
server/config/config.go:166
Validation: Must be at least 1Maximum number of non-executable transaction slots permitted per account.For transactions with gaps in nonce sequence (future transactions).Source:
server/config/config.go:168
Validation: Must be at least 1Maximum number of non-executable transaction slots for all accounts.Total capacity for queued (non-executable) transactions across all accounts.Source:
server/config/config.go:170
Validation: Must be at least 1Maximum amount of time non-executable transactions are queued.Transactions that remain non-executable longer than this duration are removed from the mempool.Source:
server/config/config.go:172
Format: Go duration string (e.g., "1h30m", "30m0s", "24h0m0s")
Validation: Must be at least 1nsConfiguration Examples
High-Throughput Chain:Copy
Ask AI
[evm.mempool]
global-slots = 10240
global-queue = 2048
price-limit = 100000000 # 0.1 gwei minimum
lifetime = "6h0m0s"
Copy
Ask AI
[evm.mempool]
global-slots = 2048
global-queue = 512
lifetime = "1h0m0s"
account-slots = 8
Copy
Ask AI
[evm.mempool]
price-limit = 1000000000 # 1 gwei minimum
price-bump = 25 # 25% replacement cost
lifetime = "30m0s"
account-slots = 4
Ethereum JSON-RPC server configuration.
Core Settings
Enable the JSON-RPC server.Must be
true for Ethereum compatibility.Source: server/config/config.go:169
Testnet configuration: evmd/cmd/evmd/cmd/testnet.go:303HTTP server bind address using standard Ethereum RPC port.Source:
server/config/config.go:153WebSocket server address for eth_subscribe methods.Source:
server/config/config.go:155
Implementation: rpc/stream/rpc.goJSON-RPC namespaces to enable.Available namespaces:
web3, eth, personal, net, txpool, debug, minerSource: server/config/config.go:151
Namespace implementations: rpc/namespaces/Allowed CORS origins for WebSocket connections.Source:
server/config/config.go:195Resource Limits
Gas limit for eth_call/estimateGas operations (25M gas).Set to 0 for unlimited.Source:
server/config/config.go:157
Enforced: rpc/namespaces/ethereum/eth/api.go:1039Maximum transaction fee cap in ether for eth_sendTransaction.Source:
server/config/config.go:163
Enforced: rpc/namespaces/ethereum/eth/api.go:1586Maximum concurrent filters per connection.Source:
server/config/config.go:165
Implementation: rpc/namespaces/ethereum/eth/filters/Maximum blocks that can be fetched for eth_feeHistory.Source:
server/config/config.go:167Maximum logs returned from a single eth_getLogs query.Source:
server/config/config.go:171
Enforced: rpc/namespaces/ethereum/eth/filters/api.go:442Maximum block range allowed for eth_getLogs queries.Source:
server/config/config.go:173
Enforced: rpc/namespaces/ethereum/eth/filters/filter.go:268Connection Settings
Maximum number of requests in a batch (go-ethereum standard).Source:
server/config/config.go:182Maximum bytes returned from a batched call (25MB).Source:
server/config/config.go:184Read/write timeout for HTTP JSON-RPC server.Source:
server/config/config.go:175Idle timeout for HTTP connections.Source:
server/config/config.go:177Maximum simultaneous connections for the server listener.Set to 0 for unlimited.Source:
server/config/config.go:187Global timeout for eth_call operations.Source:
server/config/config.go:161Features
Enable custom transaction indexer for EVM transactions.Required for:
eth_getLogs, eth_getTransactionReceiptSource: server/config/config.go:189
Testnet default: evmd/cmd/evmd/cmd/testnet.go:303Enable pprof endpoints in debug namespace.Source:
server/config/config.go:197Prometheus metrics server address.Metrics path:
/debug/metrics/prometheusSource: server/config/config.go:191Security
Allow non-EIP155 signed transactions to be submitted.Source:
server/config/config.go:180Allow insecure account unlocking when personal namespace is enabled.Source:
server/config/config.go:159CLI flags and environment variables for runtime configuration. These parameters can be set via command line or environment variables to override configuration file settings.
Context: These are EVM-specific runtime parameters that complement the standard Cosmos SDK flags. They control chain initialization and runtime behavior specific to EVM functionality.
Cosmos SDK chain identifier for transaction signing and network identification.CLI Flag:
--chain-id
Environment: EVMD_CHAIN_ID
Usage: evmd start --chain-id mychain-1EIP-155 replay protection chain ID for Ethereum compatibility. Must be unique across all EVM networks.CLI Flag:
--evm.evm-chain-id
Environment: EVMD_EVM_CHAIN_ID
Usage: evmd start --evm.evm-chain-id 9000
Config Alternative: Set in app.toml under [evm] evm-chain-idBase denomination for native token transactions and staking.CLI Flag:
--denom
Environment: EVMD_DENOM
Usage: evmd init mynode --denom mytokenMinimum priority fee (in wei) required for mempool inclusion.CLI Flag:
--evm.min-tip
Environment: EVMD_EVM_MIN_TIP
Usage: evmd start --evm.min-tip 1000000000
Config Alternative: Set in app.toml under [evm] min-tipMaximum gas limit for transactions in CheckTx validation mode.CLI Flag:
--evm.max-tx-gas-wanted
Environment: EVMD_MAX_TX_GAS_WANTED
Usage: evmd start --evm.max-tx-gas-wanted 50000000
Config Alternative: Set in app.toml under [evm] max-tx-gas-wantedComplete
app.toml with EVM-specific sections highlighted.Complete Application Configuration
Copy
Ask AI
# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml
###############################################################################
### Base Configuration ###
###############################################################################
# The minimum gas prices a validator is willing to accept for processing a
# transaction. A transaction's fees must meet the minimum of any denomination
# specified in this config (e.g. 0.25token1,0.0001token2).
minimum-gas-prices = "0atest"
# The maximum gas a query coming over rest/grpc may consume.
# If this is set to zero, the query can consume an unbounded amount of gas.
query-gas-limit = "0"
# default: the last 362880 states are kept, pruning at 10 block intervals
# nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)
# everything: 2 latest states will be kept; pruning at 10 block intervals.
# custom: allow pruning options to be manually specified through 'pruning-keep-recent', and 'pruning-interval'
pruning = "default"
# These are applied if and only if the pruning strategy is custom.
pruning-keep-recent = "0"
pruning-interval = "0"
# HaltHeight contains a non-zero block height at which a node will gracefully
# halt and shutdown that can be used to assist upgrades and testing.
#
# Note: Commitment of state will be attempted on the corresponding block.
halt-height = 0
# HaltTime contains a non-zero minimum block time (in Unix seconds) at which
# a node will gracefully halt and shutdown that can be used to assist upgrades
# and testing.
#
# Note: Commitment of state will be attempted on the corresponding block.
halt-time = 0
# MinRetainBlocks defines the minimum block height offset from the current
# block being committed, such that all blocks past this offset are pruned
# from CometBFT. It is used as part of the process of determining the
# ResponseCommit.RetainHeight value during ABCI Commit. A value of 0 indicates
# that no blocks should be pruned.
#
# This configuration value is only responsible for pruning CometBFT blocks.
# It has no bearing on application state pruning which is determined by the
# "pruning-*" configurations.
#
# Note: CometBFT block pruning is dependant on this parameter in conjunction
# with the unbonding (safety threshold) period, state pruning and state sync
# snapshot parameters to determine the correct minimum value of
# ResponseCommit.RetainHeight.
min-retain-blocks = 0
# InterBlockCache enables inter-block caching.
inter-block-cache = true
# IndexEvents defines the set of events in the form {eventType}.{attributeKey},
# which informs CometBFT what to index. If empty, all events will be indexed.
#
# Example:
# ["message.sender", "message.recipient"]
index-events = []
# IavlCacheSize set the size of the iavl tree cache (in number of nodes).
iavl-cache-size = 781250
# IAVLDisableFastNode enables or disables the fast node feature of IAVL.
# Default is false.
iavl-disable-fastnode = false
# AppDBBackend defines the database backend type to use for the application and snapshots DBs.
# An empty string indicates that a fallback will be used.
# The fallback is the db_backend value set in CometBFT's config.toml.
app-db-backend = ""
###############################################################################
### Telemetry Configuration ###
###############################################################################
[telemetry]
# Prefixed with keys to separate services.
service-name = ""
# Enabled enables the application telemetry functionality. When enabled,
# an in-memory sink is also enabled by default. Operators may also enabled
# other sinks such as Prometheus.
enabled = true
# Enable prefixing gauge values with hostname.
enable-hostname = false
# Enable adding hostname to labels.
enable-hostname-label = false
# Enable adding service to labels.
enable-service-label = false
# PrometheusRetentionTime, when positive, enables a Prometheus metrics sink.
prometheus-retention-time = 1000000000000
# GlobalLabels defines a global set of name/value label tuples applied to all
# metrics emitted using the wrapper functions defined in telemetry package.
#
# Example:
# [["chain_id", "cosmoshub-1"]]
global-labels = [
]
# MetricsSink defines the type of metrics sink to use.
metrics-sink = ""
# StatsdAddr defines the address of a statsd server to send metrics to.
# Only utilized if MetricsSink is set to "statsd" or "dogstatsd".
statsd-addr = ""
# DatadogHostname defines the hostname to use when emitting metrics to
# Datadog. Only utilized if MetricsSink is set to "dogstatsd".
datadog-hostname = ""
###############################################################################
### API Configuration ###
###############################################################################
[api]
# Enable defines if the API server should be enabled.
enable = true
# Swagger defines if swagger documentation should automatically be registered.
swagger = false
# Address defines the API server to listen on.
address = "tcp://localhost:1317"
# MaxOpenConnections defines the number of maximum open connections.
max-open-connections = 1000
# RPCReadTimeout defines the CometBFT RPC read timeout (in seconds).
rpc-read-timeout = 10
# RPCWriteTimeout defines the CometBFT RPC write timeout (in seconds).
rpc-write-timeout = 0
# RPCMaxBodyBytes defines the CometBFT maximum request body (in bytes).
rpc-max-body-bytes = 1000000
# EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk).
enabled-unsafe-cors = false
###############################################################################
### gRPC Configuration ###
###############################################################################
[grpc]
# Enable defines if the gRPC server should be enabled.
enable = true
# Address defines the gRPC server address to bind to.
address = "localhost:9090"
# MaxRecvMsgSize defines the max message size in bytes the server can receive.
# The default value is 10MB.
max-recv-msg-size = "10485760"
# MaxSendMsgSize defines the max message size in bytes the server can send.
# The default value is math.MaxInt32.
max-send-msg-size = "2147483647"
###############################################################################
### gRPC Web Configuration ###
###############################################################################
[grpc-web]
# GRPCWebEnable defines if the gRPC-web should be enabled.
# NOTE: gRPC must also be enabled, otherwise, this configuration is a no-op.
# NOTE: gRPC-Web uses the same address as the API server.
enable = true
###############################################################################
### State Sync Configuration ###
###############################################################################
# State sync snapshots allow other nodes to rapidly join the network without replaying historical
# blocks, instead downloading and applying a snapshot of the application state at a given height.
[state-sync]
# snapshot-interval specifies the block interval at which local state sync snapshots are
# taken (0 to disable).
snapshot-interval = 0
# snapshot-keep-recent specifies the number of recent snapshots to keep and serve (0 to keep all).
snapshot-keep-recent = 2
###############################################################################
### State Streaming ###
###############################################################################
# Streaming allows nodes to stream state to external systems.
[streaming]
# streaming.abci specifies the configuration for the ABCI Listener streaming service.
[streaming.abci]
# List of kv store keys to stream out via gRPC.
# The store key names MUST match the module's StoreKey name.
#
# Example:
# ["acc", "bank", "gov", "staking", "mint"[,...]]
# ["*"] to expose all keys.
keys = []
# The plugin name used for streaming via gRPC.
# Streaming is only enabled if this is set.
# Supported plugins: abci
plugin = ""
# stop-node-on-err specifies whether to stop the node on message delivery error.
stop-node-on-err = true
###############################################################################
### Mempool ###
###############################################################################
[mempool]
# Setting max-txs to 0 will allow for a unbounded amount of transactions in the mempool.
# Setting max_txs to negative 1 (-1) will disable transactions from being inserted into the mempool (no-op mempool).
# Setting max_txs to a positive number (> 0) will limit the number of transactions in the mempool, by the specified amount.
#
# Note, this configuration only applies to SDK built-in app-side mempool
# implementations.
max-txs = -1
###############################################################################
### EVM Configuration ###
###############################################################################
[evm]
# Tracer defines the 'vm.Tracer' type that the EVM will use when the node is run in
# debug mode. To enable tracing use the '--evm.tracer' flag when starting your node.
# Valid types are: json|struct|access_list|markdown
tracer = ""
# MaxTxGasWanted defines the gas wanted for each eth tx returned in ante handler in check tx mode.
max-tx-gas-wanted = 0
# EnablePreimageRecording enables tracking of SHA3 preimages in the VM
cache-preimage = false
# EVMChainID is the EIP-155 compatible replay protection chain ID. This is separate from the Cosmos chain ID.
evm-chain-id = 262144
# MinTip defines the minimum priority fee for the mempool.
min-tip = 0
# Geth metrics server address
geth-metrics-address = "127.0.0.1:8100"
# Mempool configuration for EVM transactions
[evm.mempool]
# PriceLimit is the minimum gas price to enforce for acceptance into the pool (in wei)
price-limit = 1
# PriceBump is the minimum price bump percentage to replace an already existing transaction (nonce)
price-bump = 10
# AccountSlots is the number of executable transaction slots guaranteed per account
account-slots = 16
# GlobalSlots is the maximum number of executable transaction slots for all accounts
global-slots = 5120
# AccountQueue is the maximum number of non-executable transaction slots permitted per account
account-queue = 64
# GlobalQueue is the maximum number of non-executable transaction slots for all accounts
global-queue = 1024
# Lifetime is the maximum amount of time non-executable transaction are queued
lifetime = "3h0m0s"
###############################################################################
### JSON RPC Configuration ###
###############################################################################
[json-rpc]
# Enable defines if the JSONRPC server should be enabled.
enable = true
# Address defines the EVM RPC HTTP server address to bind to.
address = "127.0.0.1:8545"
# Address defines the EVM WebSocket server address to bind to.
ws-address = "127.0.0.1:8546"
# WSOrigins defines the allowed origins for WebSocket connections.
# Example: ["localhost", "127.0.0.1", "myapp.example.com"]
ws-origins = ["127.0.0.1", "localhost"]
# API defines a list of JSON-RPC namespaces that should be enabled
# Example: "eth,txpool,personal,net,debug,web3"
api = "eth,net,web3"
# GasCap sets a cap on gas that can be used in eth_call/estimateGas (0=infinite). Default: 25,000,000.
gas-cap = 25000000
# Allow insecure account unlocking when account-related RPCs are exposed by http
allow-insecure-unlock = true
# EVMTimeout is the global timeout for eth_call. Default: 5s.
evm-timeout = "5s"
# TxFeeCap is the global tx-fee cap for send transaction. Default: 1eth.
txfee-cap = 1
# FilterCap sets the global cap for total number of filters that can be created
filter-cap = 200
# FeeHistoryCap sets the global cap for total number of blocks that can be fetched
feehistory-cap = 100
# LogsCap defines the max number of results can be returned from single 'eth_getLogs' query.
logs-cap = 10000
# BlockRangeCap defines the max block range allowed for 'eth_getLogs' query.
block-range-cap = 10000
# HTTPTimeout is the read/write timeout of http json-rpc server.
http-timeout = "30s"
# HTTPIdleTimeout is the idle timeout of http json-rpc server.
http-idle-timeout = "2m0s"
# AllowUnprotectedTxs restricts unprotected (non EIP155 signed) transactions to be submitted via
# the node's RPC when the global parameter is disabled.
allow-unprotected-txs = false
# MaxOpenConnections sets the maximum number of simultaneous connections
# for the server listener.
max-open-connections = 0
# EnableIndexer enables the custom transaction indexer for the EVM (ethereum transactions).
enable-indexer = false
# MetricsAddress defines the EVM Metrics server address to bind to. Pass --metrics in CLI to enable
# Prometheus metrics path: /debug/metrics/prometheus
metrics-address = "127.0.0.1:6065"
# Maximum number of requests in a batch.
batch-request-limit = 1000
# Maximum number of bytes returned from a batched call.
batch-response-max-size = 25000000
# Enabled profiling in the debug namespace
enable-profiling = false
###############################################################################
### TLS Configuration ###
###############################################################################
[tls]
# Certificate path defines the cert.pem file path for the TLS configuration.
certificate-path = ""
# Key path defines the key.pem file path for the TLS configuration.
key-path = ""
Lines (130-260): are EVM-specific configuration sections added by Cosmos EVMLines (1-129): are Base Cosmos SDK parametersKey EVM sections:
[evm]: EVM runtime settings (lines 645-670)[evm.mempool]: Mempool configuration (lines 672-694, new in v0.5.0)[json-rpc]: Ethereum JSON-RPC server (lines 700-747)[tls]: TLS configuration (lines 753-760)
- SDK config:
cosmos-sdk/server/config/toml.go - EVM config:
evm/server/config/toml.go
Blockchain initialization parameters set during chain genesis. These EVM-specific parameters configure the initial state and behavior of the EVM module.EVM-Specific Parameters:
Context: These parameters are set once during chain initialization and typically cannot be changed without governance proposals or network upgrades. They control fundamental EVM behavior and compatibility.
Genesis Configuration Example
Copy
Ask AI
{
"chain_id": "mychain-1",
"app_state": {
"evm": {
"params": {
"evm_denom": "atest",
"history_serve_window": 8192,
"active_static_precompiles": [
"0x0000000000000000000000000000000000000100",
"0x0000000000000000000000000000000000000400",
"0x0000000000000000000000000000000000000800",
"0x0000000000000000000000000000000000000801",
"0x0000000000000000000000000000000000000802",
"0x0000000000000000000000000000000000000804",
"0x0000000000000000000000000000000000000805"
],
"access_control": {
"create": {"access_type": "ACCESS_TYPE_PERMISSIONLESS"},
"call": {"access_type": "ACCESS_TYPE_PERMISSIONLESS"}
}
}
},
"feemarket": {
"params": {
"no_base_fee": false,
"base_fee_change_denominator": 8,
"elasticity_multiplier": 2,
"base_fee": "1000000000",
"min_gas_price": "0",
"min_gas_multiplier": "0.5"
}
}
},
"consensus": {
"params": {
"block": {
"max_bytes": "22020096",
"max_gas": "100000000"
}
}
}
}
evm_denom: Base denomination for EVM operations and gas paymentshistory_serve_window: Number of historical block hashes to store (EIP-2935)active_static_precompiles: Enabled precompile contract addressesaccess_control: Permissions for contract creation and execution
base_fee: Initial EIP-1559 base fee valuebase_fee_change_denominator: Rate of base fee adjustmentelasticity_multiplier: Block utilization threshold for fee changes
max_gas: Maximum gas per block (critical for mempool configuration)
Production validator node configuration and security considerations.Why this matters:
Critical Security Notice: Validator nodes should NEVER expose RPC/API ports publicly. Only dedicated RPC nodes (non-validators) should serve public traffic.
Validator vs RPC Node Architecture
Production networks should use a two-tier architecture:Validator Nodes (Private)
Purpose: Block production and consensus participation onlyConfiguration Requirements:- Disable all public-facing services
- Restrict network access to other validators via persistent peers
- Do NOT enable JSON-RPC server
- Do NOT expose API/gRPC ports publicly
- Use firewall rules to block external access
app.toml settings:Copy
Ask AI
[api]
enable = false # Disable REST API
[grpc]
enable = false # Disable gRPC or bind to localhost only
address = "localhost:9090"
[json-rpc]
enable = false # CRITICAL: Keep JSON-RPC disabled on validators
[evm]
max-tx-gas-wanted = 50000000 # Set reasonable gas limits
- DDoS Protection: Public RPC access can overwhelm validator resources
- Resource Exhaustion: Heavy query load impacts block production
- Uptime: Validators must prioritize consensus participation over serving requests
- Security: Reduced attack surface for exploits
- Slashing Risk: Downtime from overload can lead to slashing penalties
RPC Nodes (Public)
Purpose: Serve public API/RPC requests without participating in consensusConfiguration Requirements:- Enable JSON-RPC, API, and WebSocket endpoints
- Use load balancers for distribution
- Set appropriate rate limits and caps
- Can run multiple RPC nodes for redundancy
- No validator keys stored
app.toml settings:Copy
Ask AI
[api]
enable = true
address = "tcp://0.0.0.0:1317" # Bind to all interfaces
max-open-connections = 1000
[grpc]
enable = true
address = "0.0.0.0:9090"
[json-rpc]
enable = true
address = "0.0.0.0:8545"
ws-address = "0.0.0.0:8546"
api = "eth,net,web3,txpool"
# Set resource limits
gas-cap = 50000000
filter-cap = 200
logs-cap = 10000
block-range-cap = 10000
max-open-connections = 500
batch-request-limit = 100
Validator Security Checklist
- JSON-RPC is disabled on validator nodes
- API/gRPC endpoints not exposed publicly on validators
- Firewall rules restrict validator access to known peers only
- Separate RPC nodes deployed for public access
- Load balancers configured for RPC node redundancy
- Monitoring alerts for validator downtime
- Regular security audits of network architecture
- Validator keys stored securely (preferably HSM)
- SSH access restricted and key-based only
Network Topology Example
Copy
Ask AI
Public Internet
│
├─── Load Balancer
│ │
│ ┌────┴────┬────────┐
│ │ │ │
│ RPC Node RPC Node RPC Node
│ │ │ │
└────┴─────────┴────────┘
│
═══════════════════════════
Private Validator Network
═══════════════════════════
│
┌──────────┼──────────┐
│ │ │
Validator 1 Validator 2 Validator 3
(RPC disabled) (RPC disabled) (RPC disabled)
State Sync Consideration: If validators need to quickly sync using state sync, they may temporarily enable RPC on a private network segment to serve snapshots to each other. This should be done on a separate internal interface, never exposed publicly.