ChainOS Node Configuration

Configuration Overview

This guide provides detailed information on configuring your ChainOS node for optimal performance and security. Proper configuration is essential for stable node operation and network participation.

Configuration Files

ChainOS uses several configuration files located in the ~/.chainosd/config/ directory:

Primary Configuration Files

  • config.toml: Main configuration file for the node (consensus, p2p, etc.)
  • app.toml: Application-specific configuration (API, state sync, etc.)
  • client.toml: Client configuration for the CLI
  • genesis.json: Initial state of the blockchain
  • priv_validator_key.json: Private key for validator operations (validators only)
  • node_key.json: Private key for p2p communication

Security Warning

The priv_validator_key.json file contains sensitive private key information. For validators, it's crucial to secure this file properly. Consider using a Hardware Security Module (HSM) for production validators.

config.toml Configuration

The config.toml file contains settings for the consensus engine and networking components. Here are the key sections and parameters:

Base Configuration

# TCP or UNIX socket address of the ABCI application,
# or the name of an ABCI application compiled in with the Tendermint binary
proxy_app = "tcp://127.0.0.1:26658"

# A custom human readable name for this node
moniker = "my-node-name"

# Database backend: goleveldb | cleveldb | boltdb | rocksdb
# * goleveldb (github.com/syndtr/goleveldb - most popular implementation)
# * cleveldb (uses levigo wrapper)
# * boltdb (uses etcd's fork of bolt - github.com/etcd-io/bbolt)
# * rocksdb (uses github.com/tecbot/gorocksdb)
db_backend = "goleveldb"

# Database directory
db_dir = "data"

# Output level for logging, including package level options
log_level = "info"

Recommended changes:

RPC Configuration

[rpc]
# TCP or UNIX socket address for the RPC server to listen on
laddr = "tcp://127.0.0.1:26657"

# A list of origins a cross-domain request can be executed from
# Default value '[]' disables cors support
# Use '["*"]' to allow any origin
cors_allowed_origins = []

# Maximum number of simultaneous connections
max_open_connections = 1000

# Maximum number of unique client subscriptions
max_subscription_clients = 100

Recommended changes:

Security Note

When exposing RPC endpoints publicly, ensure you have proper firewall rules and rate limiting in place to prevent abuse.

P2P Configuration

[p2p]
# Address to listen for incoming connections
laddr = "tcp://0.0.0.0:26656"

# Maximum number of inbound peers
max_num_inbound_peers = 40

# Maximum number of outbound peers to connect to, excluding persistent peers
max_num_outbound_peers = 10

# List of node IDs, to which a connection will be (re)established ignoring any existing limits
unconditional_peer_ids = ""

# Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
private_peer_ids = ""

# Toggle to disable guard against peers connecting from the same ip
allow_duplicate_ip = false

# Peer connection configuration
handshake_timeout = "20s"
dial_timeout = "3s"

# Comma separated list of seed nodes to connect to
seeds = "2b89c755963a03a2a2c846d5efb97c06e6d2cdfe@seed.chainos.network:26656,3b89c755963a03a2a2c846d5efb97c06e6d2cdfe@seed2.chainos.network:26656"

# Comma separated list of nodes to keep persistent connections to
persistent_peers = "2b89c755963a03a2a2c846d5efb97c06e6d2cdfe@chainos.network:26656"

Recommended changes:

Consensus Configuration

[consensus]
# How long we wait for a proposal block before prevoting nil
timeout_propose = "3s"
# How long we wait after receiving +2/3 prevotes for "anything" (i.e. not a single block or nil)
timeout_prevote = "1s"
# How long we wait after receiving +2/3 precommits for "anything" (i.e. not a single block or nil)
timeout_precommit = "1s"
# How long we wait after committing a block, before starting on the new height
timeout_commit = "1s"

# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
skip_timeout_commit = false

# EmptyBlocks mode and possible interval between empty blocks
create_empty_blocks = true
create_empty_blocks_interval = "0s"

Recommended changes:

State Sync Configuration

[statesync]
# State sync rapidly bootstraps a new node by discovering, fetching, and restoring a state machine
# snapshot from peers instead of fetching and replaying historical blocks
enable = false

# RPC servers (comma-separated) for light client verification of the synced state machine and
# retrieval of state data for node bootstrapping
rpc_servers = "chainos.network:26657,chainos-backup.network:26657"

# Trusted block height
trust_height = 0

# Trusted block hash
trust_hash = ""

# Trusted block header provider
trust_period = "168h0m0s"

To enable state sync (for faster node synchronization):

  1. Set enable = true
  2. Set rpc_servers to reliable RPC endpoints
  3. Get a recent block height and its hash from a trusted source
  4. Set trust_height to that block height
  5. Set trust_hash to that block's hash

State Sync Tip

You can get a recent block height and hash by running:

curl -s "chainos.network:26657/block?height=3500000" | jq -r '.result.block_id.hash'

Replace 3500000 with a recent block height.

app.toml Configuration

The app.toml file contains application-specific settings. Here are the key sections:

API Configuration

[api]
# Enable defines if the API server should be enabled.
enable = true

# Address defines the API server to listen on.
address = "tcp://0.0.0.0:1317"

# EnableUnsafeCORS defines if CORS should be enabled (unsafe - use it at your own risk).
enabled-unsafe-cors = false

Recommended changes:

gRPC Configuration

[grpc]
# Enable defines if the gRPC server should be enabled.
enable = true

# Address defines the gRPC server address to bind to.
address = "0.0.0.0:9090"

Recommended changes:

Telemetry Configuration

[telemetry]
# 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 = 0

Recommended changes:

Pruning Configuration

[pruning]
# Pruning strategy:
# - "nothing": All historic states will be saved, nothing will be deleted (i.e. archiving node).
# - "everything": All saved states will be deleted, storing only the current state.
# - "custom": Allow pruning options to be manually specified through 'pruning-keep-recent',
#   'pruning-keep-every', and 'pruning-interval'.
pruning = "default"

# These are applied if and only if the pruning strategy is custom.
pruning-keep-recent = "100"
pruning-keep-every = "0"
pruning-interval = "10"

Recommended settings for different node types:

client.toml Configuration

The client.toml file contains settings for the CLI client:

# Chain ID to sign with
chain-id = "chainos-1"

# Keyring backend, options: os|file|kwallet|pass|test|memory
keyring-backend = "os"

# CLI output format (text|json)
output = "text"

# Node to connect to
node = "tcp://localhost:26657"

# Transaction broadcast mode (sync|async|block)
broadcast-mode = "sync"

Recommended changes:

Performance Optimization

Here are some recommended configurations for different types of nodes:

Validator Node Configuration

Recommended Settings

  • db_backend: "rocksdb" for better performance
  • max_num_inbound_peers: 60
  • max_num_outbound_peers: 20
  • pruning: "custom" with pruning-keep-recent = "100"
  • indexer: "null" (disable indexing to save resources)
  • persistent_peers: Add multiple reliable peers

API Node Configuration

Recommended Settings

  • api.enable: true
  • api.address: "tcp://0.0.0.0:1317" (with proper firewall rules)
  • grpc.enable: true
  • grpc.address: "0.0.0.0:9090" (with proper firewall rules)
  • rpc.max_open_connections: 1000 or higher
  • pruning: "default" or "custom" with larger keep-recent value
  • indexer: "kv" (enable indexing for API queries)

Archive Node Configuration

Recommended Settings

  • pruning: "nothing" (keep all historical states)
  • indexer: "kv" (enable indexing for historical queries)
  • state_sync.enable: false (archive nodes should sync from genesis)
  • db_backend: "rocksdb" for better performance with large datasets

Advanced Configuration

For advanced users, here are some additional configuration options:

Custom Indexer Configuration

[tx_index]
# What indexer to use for transactions
#
# The application will set which txs to index. In some cases a node operator will be able
# to decide which txs to index based on configuration set in the application.
#
# Options:
#   1) "null"
#   2) "kv" (default) - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).
# 		- When "kv" is chosen "tx.height" and "tx.hash" will always be indexed.
indexer = "kv"

# The events to index.
# Example:
# index_events = ["message.sender", "message.recipient"]
index_events = []

For better transaction querying capabilities:

Mempool Configuration

[mempool]
# Maximum number of transactions in the mempool
size = 5000

# Maximum size of a single transaction
max_tx_bytes = 1048576

# Maximum size of all transactions in the mempool
max_txs_bytes = 1073741824

# Size of the cache (used to filter transactions we saw earlier)
cache_size = 10000

For high-throughput nodes:

Configuration Examples

Here are some example configurations for different node types:

Validator Node Example

# config.toml
[rpc]
laddr = "tcp://127.0.0.1:26657"  # Local access only for security

[p2p]
laddr = "tcp://0.0.0.0:26656"
max_num_inbound_peers = 60
max_num_outbound_peers = 20
persistent_peers = "2b89c755963a03a2a2c846d5efb97c06e6d2cdfe@chainos.network:26656,3b89c755963a03a2a2c846d5efb97c06e6d2cdfe@chainos-backup.network:26656"

[mempool]
size = 10000
cache_size = 20000

[tx_index]
indexer = "null"  # Save resources by disabling indexing

# app.toml
[pruning]
pruning = "custom"
pruning-keep-recent = "100"
pruning-keep-every = "0"
pruning-interval = "10"

[api]
enable = false  # Disable API for security

[grpc]
enable = false  # Disable gRPC for security

[telemetry]
enabled = true
prometheus-retention-time = 60  # Enable Prometheus metrics

API Node Example

# config.toml
[rpc]
laddr = "tcp://0.0.0.0:26657"  # Public access
max_open_connections = 1000
cors_allowed_origins = ["*"]  # Allow all origins (with proper security measures)

[p2p]
laddr = "tcp://0.0.0.0:26656"
max_num_inbound_peers = 40
max_num_outbound_peers = 10

[tx_index]
indexer = "kv"
index_events = ["message.sender", "message.recipient", "transfer.recipient"]

# app.toml
[pruning]
pruning = "default"

[api]
enable = true
address = "tcp://0.0.0.0:1317"
enabled-unsafe-cors = true  # Enable CORS (with proper security measures)

[grpc]
enable = true
address = "0.0.0.0:9090"

[telemetry]
enabled = true
prometheus-retention-time = 60

Need Help?

If you need assistance with your node configuration, join our Discord community where our team and other node operators can help.