Configuration
Specter nodes are configured through three primary files located in ~/.umbralined/config/. This guide covers the key settings in each file and recommendations for different node roles (full node, validator, RPC provider).
Configuration Files
| File | Purpose |
|---|---|
config.toml | CometBFT settings: consensus, P2P networking, Tendermint RPC |
app.toml | Application settings: EVM config, Cosmos REST API, gRPC, gas prices |
genesis.json | Chain genesis state — do not modify after chain launch |
config.toml
This is the CometBFT configuration file. It controls consensus behavior, peer-to-peer networking, and the Tendermint RPC server.
General
# Human-readable name for this node (shown to peers)
moniker = "my-specter-node"
# Database backend: "goleveldb" | "rocksdb" | "pebbledb"
# goleveldb is default; pebbledb offers better compaction for large state
db_backend = "goleveldb"
# Log level: "info" | "debug" | "warn" | "error"
# Use "info" for production, "debug" for troubleshooting
log_level = "info"
# Log format: "plain" | "json"
# Use "json" if feeding logs into a structured logging system
log_format = "plain"
RPC Server
Controls the Tendermint RPC endpoint (default: port 26657). This is the Cosmos-side RPC, distinct from the EVM JSON-RPC.
[rpc]
# Listen address for Tendermint RPC
laddr = "tcp://127.0.0.1:26657"
# CORS allowed origins (set to ["*"] for public RPC nodes)
cors_allowed_origins = []
# Maximum number of simultaneous connections
max_open_connections = 900
# Maximum number of unique client subscriptions per connection
max_subscriptions_per_client = 5
# Timeout for broadcast_tx_commit (should be longer than block time)
timeout_broadcast_tx_commit = "10s"
# Maximum request body size (bytes)
max_body_bytes = 1000000
# Maximum header size (bytes)
max_header_bytes = 1048576
For public-facing RPC nodes, bind to 0.0.0.0:26657 and set appropriate cors_allowed_origins. For validators, keep the default 127.0.0.1 binding to minimize attack surface.
P2P Networking
[p2p]
# Listen address for P2P connections
laddr = "tcp://0.0.0.0:26656"
# External address to advertise to peers
# Required if behind NAT or a reverse proxy
external_address = ""
# Seed nodes for initial peer discovery (comma-separated)
seeds = ""
# Persistent peers to maintain constant connections to (comma-separated)
persistent_peers = ""
# Maximum number of inbound peers
max_num_inbound_peers = 40
# Maximum number of outbound peers
max_num_outbound_peers = 10
# Toggle peer exchange reactor (PEX)
# Set to false for private/sentry node architectures
pex = true
# Seed mode — node operates as a seed, crawls the network, and disconnects
seed_mode = false
# Comma-separated list of peer IDs to keep private (will not be gossiped)
private_peer_ids = ""
# Handshake and dial timeouts
handshake_timeout = "20s"
dial_timeout = "3s"
Consensus
[consensus]
# Propose timeout — how long the proposer waits before proposing an empty block
timeout_propose = "3s"
# Prevote timeout
timeout_prevote = "1s"
# Precommit timeout
timeout_precommit = "1s"
# Commit timeout — delay after committing a block before starting the next height
# This directly affects block time. Specter targets ~5s blocks.
timeout_commit = "3s"
# Make empty blocks (set to false to only produce blocks when there are transactions)
create_empty_blocks = true
# Interval between empty blocks (if create_empty_blocks is true)
create_empty_blocks_interval = "0s"
Mempool
[mempool]
# Maximum number of transactions in the mempool
size = 5000
# Maximum size of the mempool in bytes
max_txs_bytes = 1073741824 # 1 GB
# Maximum size of a single transaction (bytes)
max_tx_bytes = 1048576 # 1 MB
# TTL for transactions in the mempool (number of blocks; 0 = no limit)
ttl-num-blocks = 0
# TTL for transactions in the mempool (duration; 0s = no limit)
ttl-duration = "0s"
State Sync
[statesync]
# Enable state sync for fast initial node bootstrapping
enable = false
# Trusted RPC endpoints (comma-separated, at least 2)
rpc_servers = ""
# Trusted block height and hash (from a trusted RPC node)
trust_height = 0
trust_hash = ""
# Trust period — how far back in time the trust anchor can be
trust_period = "168h0m0s" # 7 days
# Time to wait for a state sync chunk before retrying
chunk_request_timeout = "10s"
app.toml
This file controls the Cosmos application layer, including the EVM module, API servers, and gas pricing.
Base Configuration
# Minimum gas prices — transactions with gas prices below this are rejected
# Critical for spam prevention
minimum-gas-prices = "0.001aghost"
# Pruning strategy: "default" | "nothing" | "everything" | "custom"
# "default" — keep recent 100 states + every 500th state
# "nothing" — keep all states (archive node)
# "everything" — keep only the current state (minimal storage)
pruning = "default"
# Custom pruning (only when pruning = "custom")
pruning-keep-recent = "100"
pruning-interval = "10"
# Halt height — node shuts down at this block height (0 = disabled)
# Useful for coordinated upgrades
halt-height = 0
# Halt time — node shuts down at this Unix timestamp (0 = disabled)
halt-time = 0
EVM Configuration
[evm]
# EVM transaction tracer: "" | "json" | "struct" | "access-list"
tracer = ""
# Maximum gas allowed in a block (0 = unlimited)
max-tx-gas-wanted = 0
JSON-RPC (EVM)
Controls the Ethereum-compatible JSON-RPC server.
[json-rpc]
# Enable the JSON-RPC server
enable = true
# Listen address for JSON-RPC HTTP
address = "0.0.0.0:8545"
# Listen address for JSON-RPC WebSocket
ws-address = "0.0.0.0:8546"
# API namespaces to enable
# Available: eth, txpool, personal, net, debug, web3, miner
api = "eth,net,web3,txpool"
# Maximum number of logs returned by eth_getLogs
max-log-limit = 10000
# Maximum gas allowed for eth_call
gas-cap = 25000000
# EVM timeout for eth_call (duration)
evm-timeout = "5s"
# Transaction fee cap (in GHOST) for RPC methods
txfee-cap = 1
# HTTP request timeout
http-timeout = "30s"
# HTTP idle timeout
http-idle-timeout = "120s"
# Maximum open HTTP connections (0 = unlimited)
max-open-connections = 0
# Enable indexing of EVM transactions
enable-indexer = false
Be aware that eth_getLogs has known limitations on Cosmos EVM chains. See Cosmos EVM Workarounds for details.
Cosmos REST API
[api]
# Enable the Cosmos REST API
enable = true
# Listen address
address = "tcp://0.0.0.0:1317"
# Enable Swagger documentation at /swagger/
swagger = false
# Maximum number of simultaneous connections (0 = unlimited)
max-open-connections = 1000
# Read and write timeouts
rpc-read-timeout = 10 # seconds
rpc-write-timeout = 0 # seconds (0 = no timeout)
gRPC
[grpc]
# Enable the gRPC server
enable = true
# Listen address
address = "0.0.0.0:9090"
# Maximum receive message size (bytes)
max-recv-msg-size = 10485760 # 10 MB
# Maximum send message size (bytes)
max-send-msg-size = 2147483647 # ~2 GB
Telemetry
[telemetry]
# Enable Prometheus metrics
enabled = false
# Prefix for all emitted metrics
global-labels = []
# Prometheus retention time (seconds)
prometheus-retention-time = 0
# Enable CPU and memory profiling
enable-hostname = false
enable-hostname-label = false
enable-service-label = false
genesis.json
The genesis file defines the initial state of the blockchain. It is set once at chain launch and must be identical across all nodes.
Key Sections
| Section | Purpose |
|---|---|
chain_id | Network identifier (umbraline_5446-1) |
genesis_time | Timestamp of the first block |
consensus_params | Block size limits, evidence rules, validator parameters |
app_state.bank | Initial token balances |
app_state.staking | Staking parameters (bond denom, unbonding time) |
app_state.slashing | Slashing parameters (downtime, double-sign penalties) |
app_state.gov | Governance parameters (voting period, quorum, threshold) |
app_state.evm | EVM chain config (chain ID, homestead block, etc.) |
app_state.ghostmint | GhostMint module parameters |
Consensus Parameters in Genesis
{
"consensus_params": {
"block": {
"max_bytes": "22020096",
"max_gas": "-1"
},
"evidence": {
"max_age_num_blocks": "100000",
"max_age_duration": "172800000000000",
"max_bytes": "1048576"
},
"validator": {
"pub_key_types": ["ed25519"]
}
}
}
Never modify genesis.json after the chain has launched. All nodes must use the identical genesis file. A mismatched genesis will cause your node to fail at block 1 with an app hash mismatch.
Recommended Configurations by Node Role
Validator
Validators prioritize security and consensus performance.
# config.toml
[rpc]
laddr = "tcp://127.0.0.1:26657" # Local-only RPC
[p2p]
max_num_inbound_peers = 40
max_num_outbound_peers = 10
pex = true
# app.toml
minimum-gas-prices = "0.001aghost"
pruning = "default"
[json-rpc]
enable = false # Disable EVM RPC on validators
[api]
enable = false # Disable REST API on validators
Public RPC Node
RPC nodes serve queries from users and applications.
# config.toml
[rpc]
laddr = "tcp://0.0.0.0:26657"
cors_allowed_origins = ["*"]
max_open_connections = 900
# app.toml
pruning = "nothing" # Keep all state for queries
[json-rpc]
enable = true
address = "0.0.0.0:8545"
ws-address = "0.0.0.0:8546"
api = "eth,net,web3,txpool"
[api]
enable = true
address = "tcp://0.0.0.0:1317"
swagger = true
Archive Node
Archive nodes retain complete historical state.
# app.toml
pruning = "nothing"
[json-rpc]
enable = true
enable-indexer = true
Applying Configuration Changes
After modifying configuration files, restart the node:
# If running as a systemd service
sudo systemctl restart umbralined
# If running directly
# Stop the running process (Ctrl+C) and restart
umbralined start
Most configuration changes take effect on restart. Changes to genesis.json after chain initialization require a full chain reset (umbralined tendermint unsafe-reset-all), which should only be done on testnets or if you are willing to resync from scratch.