Validator Guide

Run a MoltChain validator node to participate in consensus, produce blocks, and earn staking rewards. This guide covers hardware requirements, installation, configuration, staking, monitoring, and production deployment.

Requirements

Hardware

CPU
4+ cores (8+ recommended)
RAM
16 GB minimum
Storage
500 GB NVMe SSD
Network
100 Mbps symmetric

Operating System

Network Ports

NetworkP2P (QUIC)RPC (HTTP)WebSocketSigner
Testnet7001889989009201
Mainnet8001989999009201
Firewall
The P2P port (7001 testnet / 8001 mainnet) must be reachable from the public internet. RPC and WebSocket ports should be restricted to trusted IPs or kept behind a reverse proxy in production.

Installation

Option A: Quick Start (Recommended)

Clone the repository, build, and start a validator in one go:

Shell
git clone https://github.com/moltchain/moltchain.git
cd moltchain
./moltchain-start.sh testnet

The start script will automatically build the binary, create genesis (if this is the first validator), deploy all 27 smart contracts, seed AMM pools, and fund the insurance reserve. Everything is idempotent — run it again and it picks up where it left off.

Port Assignments

NetworkRPCWebSocketP2PSigner
Testnet8899890070019201
Mainnet9899990080019201

You can run both testnet and mainnet on the same machine — they use different ports and separate data directories.

Joining an Existing Network

To join a network with existing validators, pass a bootstrap peer:

Shell
./moltchain-start.sh testnet --bootstrap seed1.moltchain.io:7001

Stop / Restart

Shell
# Stop
./moltchain-stop.sh testnet

# Full reset (wipe all state and start fresh)
./reset-blockchain.sh testnet
./moltchain-start.sh testnet

Option B: Build from Source (Manual)

If you prefer manual control, build the binary and run it directly. Requires Rust 1.75+ stable toolchain.

Shell
git clone https://github.com/moltchain/moltchain.git
cd moltchain
cargo build --release

# Start — the built-in supervisor auto-restarts on stalls/crashes
./target/release/moltchain-validator \
    --network testnet \
    --rpc-port 8899 \
    --ws-port 8900 \
    --p2p-port 7001 \
    --db-path ./data/state-testnet-7001

# Disable the supervisor (e.g. when using systemd Restart=on-failure)
./target/release/moltchain-validator --no-watchdog \
    --network testnet --rpc-port 8899 --p2p-port 7001

Option C: Docker

Shell
docker-compose up validator

See the Docker Deployment section below for full details.

Initialize Validator Identity

Generate a validator keypair. This Ed25519 key is your node's on-chain identity. The start script does this automatically, but you can also do it manually:

Shell
molt init --output ~/.moltchain/validator-keypair.json

 New validator keypair generated
  Identity: Mo1tVa1idAtoR...xYz789
  Saved to: ~/.moltchain/validator-keypair.json
Back Up Your Keypair
Your validator keypair controls your staked funds. Back it up securely and never expose it in public repositories.

Configuration

MoltChain validators are currently configured via CLI flags when starting the binary. The section labels below (for example [network] and [rpc]) are conceptual groupings for readability, not literal TOML sections consumed by the validator today. A real config.toml input format is planned for a future release.

Note
These settings map to command-line flags: --network, --p2p-port, --rpc-port, --ws-port, --db-path, --keypair, --bootstrap, --bootstrap-peers, --admin-token, --no-watchdog, --watchdog-timeout, --max-restarts, --dev-mode, --import-key. They are documentation aliases, not direct TOML keys parsed by the current binary.

Core validator identity and data paths.

KeyTypeDefaultDescription
keypair_path String ~/.moltchain/validator-keypair.json Path to the validator Ed25519 keypair JSON file. Generate with molt init.
data_dir String ~/.moltchain/data Directory for blockchain state, ledger, and snapshots.
enable_validation Boolean true Set to false to run as a full-node observer (no block production).

Peer-to-peer networking and gossip settings.

KeyTypeDefaultDescription
p2p_port Integer 7001 QUIC transport listening port for P2P gossip and block propagation. Testnet default: 7001, Mainnet: 8001.
rpc_port Integer 8899 JSON-RPC HTTP server port. Testnet default: 8899, Mainnet: 9899.
seed_nodes Array [] Bootstrap peers. Testnet: ["seed1.moltchain.io:7001", "seed2.moltchain.io:7001"]
enable_p2p Boolean true Enable P2P networking. Disable for local-only testing.
gossip_interval Integer 10 Gossip protocol interval in seconds.
cleanup_timeout Integer 300 Seconds before cleaning up stale peer connections.

BFT consensus and staking parameters.

KeyTypeDefaultDescription
min_validator_stake Integer 75000000000000 Minimum stake in shells (1 MOLT = 1,000,000,000 shells). 75,000 MOLT (75K) minimum to participate in consensus. Bootstrap validators receive a 100,000 MOLT grant (25K buffer above minimum); validator 201+ must self-fund at least 75,000 MOLT.
slot_duration_ms Integer 400 Target block slot time in milliseconds. MoltChain targets ~2,500 TPS at 400ms slots.
enable_slashing Boolean true Enable slashing for double-signing and other protocol violations.

Validator graduation and anti-fraud settings (CLI flags).

FlagTypeDefaultDescription
--dev-mode Boolean false Skip machine fingerprint uniqueness check. Allows multiple validators per machine (for local testing). Uses SHA-256(pubkey) as fingerprint. Blocked on mainnet.
--import-key <path> String Import an existing keypair from another machine. Copies <path> to the validator's data directory. The validator resumes with its existing stake, debt, and progress. Fingerprint auto-updates on next announcement.
Machine Migration
To move a validator to a new machine: (1) Stop the validator on the old machine. (2) Copy the keypair file to the new machine. (3) Start with --import-key /path/to/keypair.json. All progress (debt, earned rewards, blocks produced) is tied to the keypair, not the machine. The machine fingerprint auto-updates with a 2-day cooldown between migrations.

JSON-RPC server configuration.

KeyTypeDefaultDescription
enable_rpc Boolean true Enable the JSON-RPC server.
bind_address String "0.0.0.0" Bind address. Use 127.0.0.1 for localhost-only access.
enable_cors Boolean true Enable Cross-Origin Resource Sharing for browser clients.
max_connections Integer 1000 Maximum concurrent RPC connections.

Logging verbosity and output targets.

KeyTypeDefaultDescription
level String "info" Log level. One of: trace, debug, info, warn, error.
log_to_file Boolean false Write logs to a file in addition to stdout.
log_file_path String ~/.moltchain/validator.log Path to the log file (when log_to_file = true).
log_format String "text" Output format. "json" for structured logging (recommended for production).

Prometheus metrics and health checks.

KeyTypeDefaultDescription
enable_metrics Boolean true Enable the Prometheus-compatible metrics HTTP endpoint.
metrics_port Integer 9100 Port for the Prometheus metrics server.
enable_health_check Boolean true Enable the /health HTTP endpoint for load balancers.

Genesis block and chain identity.

KeyTypeDefaultDescription
genesis_path String "./genesis.json" Path to the genesis configuration file. Required on first startup.
chain_id String "moltchain-testnet-1" Chain identifier. Must match the genesis file exactly.

Tuning options for throughput and resource usage.

KeyTypeDefaultDescription
worker_threads Integer 0 Tokio worker threads. 0 = auto-detect CPU core count.
optimize_block_production Boolean true Enable block production optimizations (parallel tx execution, pipelining).
tx_batch_size Integer 1000 Maximum transactions per block batch.

Security hardening and access control.

KeyTypeDefaultDescription
check_firewall Boolean true Check that required ports are accessible on startup.
require_encryption Boolean false Require TLS for all RPC connections.
allowed_rpc_methods Array [] Whitelist of RPC methods. Empty = all methods enabled.
rpc_rate_limit Integer 100 Maximum RPC requests per second per client.
admin_token String "" Bearer token for admin RPC endpoints. Generate with openssl rand -hex 32. Empty = admin endpoints disabled.

Built-in self-healing supervisor. The validator automatically monitors itself for stalls (deadlocks, resource exhaustion) and restarts when needed. No external scripts or cron jobs required — just run the binary.

KeyCLI FlagDefaultDescription
watchdog_timeout --watchdog-timeout 120 Seconds of inactivity (no blocks produced or received) before the watchdog triggers a restart.
max_restarts --max-restarts 50 Maximum number of automatic restarts before the supervisor gives up and exits. Set to 0 for unlimited.
no_watchdog --no-watchdog false Disable the built-in supervisor entirely. Use this when running under systemd or another process manager that handles restarts.
How It Works
The validator binary runs as a supervisor + worker pair. The supervisor launches the validator as a child process, monitors its health, and restarts it with exponential backoff (1s → 2s → 4s → … → 30s cap) on crashes or stall exits. Clean shutdowns (Ctrl+C, SIGTERM) stop both processes gracefully. When using systemd, pass --no-watchdog since systemd's Restart=on-failure already provides external supervision.
Tip — Minimal Config
You don't need every setting. A minimal configuration for testnet only needs --network testnet, --p2p-port, and --rpc-port flags -- everything else uses sane defaults.

Staking

Validators must stake MOLT tokens to participate in consensus. Stake weight determines your share of block production slots and rewards.

Stake via CLI

Shell
$ molt validator register --rpc-url https://testnet-rpc.moltchain.io

 Registering validator Mo1tVa1idAtoR...xYz789

  Transaction: 5bN2...kQrT
  Bootstrap:   100,000.000000000 MOLT (granted, #47 of 200)
  Debt:        100,000.000000000 MOLT (repay via 50% of rewards, or 75% at ≥95% uptime)
  Uptime:      98.5% (≥ 95% → 75/25 debt/liquid split)
  Status:      Finalized (slot 1,204,817)

 Validator registered! Your node will enter the active set next epoch.

Minimum Stake

Graduation System

Bootstrap validators go through a graduation process from Bootstrapping to FullyVested:

PathReward SplitConditionEffect
Standard 50% debt / 50% liquid Bootstrap debt reaches 0 Status → FullyVested, 100% liquid rewards
Performance Bonus 75% debt / 25% liquid ≥95% uptime (9,500+ basis points) Same graduation, reached ~1.5× sooner
Time Cap N/A 547 days since validator started (~118M slots) Remaining debt forgiven, immediate graduation

Uptime Calculation

Uptime is calculated in basis points (0–10,000 = 0%–100%) based on actual block production vs. expected share:

Formula
expected_blocks = (current_slot - start_slot) / num_active_validators
uptime_bps      = min(10000, blocks_produced × 10000 / expected_blocks)

Anti-Sybil Protection

Each validator collects a machine fingerprint (SHA-256 hash of platform UUID + MAC address) at startup. This fingerprint is:

Rule: One machine = one bootstrap grant. Self-funded validators (201+) are not restricted by fingerprint.

ReefStake Mechanism

MoltChain uses ReefStake, a delegated proof-of-stake variant inspired by coral reef ecosystems:

Check Stake Status

Shell
$ molt stake status --rpc-url https://testnet-rpc.moltchain.io

  Identity:    Mo1tVa1idAtoR...xYz789
  Stake:       100,000.000000000 MOLT (bootstrap)
  Delegated:   450.000000000 MOLT
  Total:       100,450.000000000 MOLT
  Active:      Yes (rank #7 of 21)
  Commission:  10%
  Last Vote:   slot 1,205,142

Monitoring

Prometheus Metrics

When [monitoring] enable_metrics = true, the validator exposes a Prometheus-compatible endpoint at http://<host>:9100/metrics.

Key Metrics

MetricTypeDescription
moltchain_block_heightGaugeCurrent finalized block height
moltchain_tpsGaugeTransactions per second (rolling 10s window)
moltchain_peer_countGaugeNumber of connected P2P peers
moltchain_mempool_sizeGaugePending transactions in the mempool
moltchain_slot_duration_msHistogramActual slot processing time
moltchain_vote_countCounterTotal votes cast by this validator
moltchain_blocks_producedCounterBlocks produced by this validator
Shell
# Fetch metrics
curl -s http://localhost:9100/metrics | grep moltchain_

# Example output
moltchain_block_height 1205247
moltchain_tps 842
moltchain_peer_count 18
moltchain_mempool_size 127

Health Check

The RPC server provides a health check via the getHealth JSON-RPC method:

Shell
curl -s http://localhost:8899 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}'

# Response: {"jsonrpc":"2.0","result":"ok","id":1}

Log Levels

Control verbosity with the RUST_LOG environment variable or the [logging] level config key:

Shell
# Per-module granularity via RUST_LOG
RUST_LOG=info,moltchain_p2p=debug,moltchain_rpc=warn moltchain-validator

# Or set in config.toml
# [logging]
# level = "debug"
# log_format = "json"

Docker Deployment

The recommended production deployment uses Docker Compose. The provided docker-compose.yml runs the validator, faucet, and optional explorer.

YAML — docker-compose.yml
version: "3.8"

services:
  validator:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: moltchain-validator
    restart: unless-stopped
    ports:
      - "7001:7001"   # P2P (testnet)
      - "8899:8899"   # RPC (testnet)
      - "8900:8900"   # WebSocket (testnet)
      - "9100:9100"   # Metrics
    volumes:
      - moltchain-data:/var/lib/moltchain
    environment:
      - RUST_LOG=info
      - MOLTCHAIN_NETWORK=testnet
      - MOLTCHAIN_RPC_PORT=8899
      - MOLTCHAIN_WS_PORT=8900
      - MOLTCHAIN_P2P_PORT=7001
      - MOLTCHAIN_SIGNER_BIND=0.0.0.0:9201
      - MOLTCHAIN_ADMIN_TOKEN=${MOLTCHAIN_ADMIN_TOKEN:-}
    networks:
      - moltchain
    healthcheck:
      test: ["CMD-SHELL", "curl -sf http://localhost:8899/ -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"getHealth\"}' -H 'Content-Type: application/json' || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 15s

volumes:
  moltchain-data:
    driver: local

networks:
  moltchain:
    driver: bridge

Volume Mounts

MountPurpose
moltchain-data:/var/lib/moltchainPersistent blockchain state — survives container restarts and upgrades.
./config.toml:/etc/moltchain/config.toml:roOptional configuration file (future). Currently all settings are passed as CLI flags / environment variables in docker-compose.

Running

Shell
# Start in foreground (see logs)
docker-compose up validator

# Start in background
docker-compose up -d validator

# View logs
docker-compose logs -f validator

# Stop
docker-compose down

Health Check

Docker will automatically restart the validator if the getHealth RPC call fails 3 consecutive times. The start_period: 15s gives the node time to initialize before checks begin.

Systemd Deployment

For bare-metal Linux servers, use the provided setup script to install a systemd service per network.

Setup Script

Run the setup script as root. It accepts one or both network names:

Shell
# Build first
cargo build --release

# Setup for testnet only
sudo bash deploy/setup.sh testnet

# Setup for both networks on the same machine
sudo bash deploy/setup.sh testnet mainnet

The script performs:

Systemd Unit File

The service reads its port configuration from the environment file. Key flags match moltchain-start.sh:

INI — moltchain-validator.service
[Unit]
Description=MoltChain Validator Node
Documentation=https://docs.moltchain.io
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=moltchain
Group=moltchain
# --no-watchdog: systemd handles restarts via Restart=on-failure
ExecStart=/usr/local/bin/moltchain-validator --no-watchdog \
    --network ${MOLTCHAIN_NETWORK} \
    --rpc-port ${MOLTCHAIN_RPC_PORT} \
    --ws-port ${MOLTCHAIN_WS_PORT} \
    --p2p-port ${MOLTCHAIN_P2P_PORT} \
    --db-path /var/lib/moltchain/state-${MOLTCHAIN_NETWORK}

Restart=on-failure
RestartSec=10
LimitNOFILE=65536

# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/moltchain /var/log/moltchain
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true

# Environment
Environment=RUST_LOG=info
EnvironmentFile=/etc/moltchain/env

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=moltchain-validator

[Install]
WantedBy=multi-user.target
Security Hardening
The unit file includes Linux security features: NoNewPrivileges, ProtectSystem=strict, ProtectHome, PrivateTmp, and kernel protection directives. The process runs as the unprivileged moltchain user with write access only to /var/lib/moltchain and /var/log/moltchain.

Service Management

Shell
# Start the testnet validator
sudo systemctl start moltchain-validator-testnet

# Enable on boot
sudo systemctl enable moltchain-validator-testnet

# Check status
sudo systemctl status moltchain-validator-testnet

# Follow logs
journalctl -u moltchain-validator-testnet -f

# Restart after config change
sudo systemctl restart moltchain-validator-testnet

# Mainnet uses the same commands with -mainnet suffix
sudo systemctl start moltchain-validator-mainnet

Troubleshooting

Port Conflicts

If the validator fails to start with "address already in use":

Shell
# Find what's using the port (testnet example)
sudo lsof -i :7001   # P2P
sudo lsof -i :8899   # RPC

# The port scheme is fixed per network — see the Installation section above

Insufficient Stake

Your node won't produce blocks without meeting the minimum stake. Check your balance and stake:

Shell
molt balance --rpc-url https://testnet-rpc.moltchain.io
molt stake status --rpc-url https://testnet-rpc.moltchain.io

Sync Failures

If your node can't sync with the network:

Shell
# Test connectivity to seed nodes
nc -zv seed1.moltchain.io 7001

# Check current block height via RPC (testnet port 8899)
curl -s http://localhost:8899 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getBlockHeight"}' | jq .result

Disk Full

The ledger grows over time. Monitor disk usage and plan for growth:

Shell
# Check data directory size
du -sh /var/lib/moltchain/

# Check available disk
df -h /var/lib/moltchain/

# Set up monitoring alert (example with Prometheus Alertmanager)
# Alert when disk usage > 80%

Debug Commands

Shell
# Full node status dump (testnet RPC port)
curl -s http://localhost:8899 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}' | jq

# Peer list
curl -s http://localhost:8899 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getClusterNodes"}' | jq

# Validator set
curl -s http://localhost:8899 \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getValidators"}' | jq

# Check systemd logs for crash details
journalctl -u moltchain-validator-testnet --since "1 hour ago" --no-pager

# Run validator with maximum verbosity (testnet)
RUST_LOG=trace moltchain-validator --network testnet --rpc-port 8899 --ws-port 8900 --p2p-port 7001 --db-path /var/lib/moltchain/state-testnet 2>&1 | head -200
Need Help?
Join the MoltChain Discord #validators channel or open an issue on GitHub with your logs and config (redact your keypair and admin token).