Running a Node
This guide covers running Ashen nodes in various configurations: development, production validators, followers, and RPC gateways.
Node Types Overview
Section titled “Node Types Overview”| Mode | Command | Use Case |
|---|---|---|
| Single-node | node run | Local development, testing |
| Validator | node run --validator | Production consensus participation |
| Follower | node follower | Archive/RPC nodes via P2P sync |
| RPC Gateway | node rpc | Offload RPC from validators |
Quick Start (Development)
Section titled “Quick Start (Development)”The fastest way to run a local development node:
# 1. Generate a keypairjust ed25519-keygen > ./target/dev.key.jsonexport ASHEN_PRIVATE_KEY=@./target/dev.key.jsonADDR=$(jq -r .address ./target/dev.key.json)
# 2. Initialize with funded accountjust devnet-node init --data-dir ./node-data --alloc "$ADDR=1000000000000"
# 3. Run the nodejust devnet-node run --data-dir ./node-data
# In another terminal, verify it's working:just rpc-statusjust rpc-account $ADDROr use the all-in-one just node recipe:
just node DATA_DIR=./node-dataSingle-Node Mode
Section titled “Single-Node Mode”Single-node mode runs a complete chain with one validator. This is ideal for:
- Local development and testing
- Contract development and debugging
- Integration testing
Basic Usage
Section titled “Basic Usage”# Initialize data directorynode init \ --data-dir ./node-data \ --alloc "0xYOUR_ADDRESS=1000000000000"
# Run the nodenode run \ --data-dir ./node-data \ --listen 127.0.0.1:3030 \ --block-time-ms 1000Configuration Options
Section titled “Configuration Options”| Option | Default | Description |
|---|---|---|
--data-dir | ./node-data | Directory for chain data |
--listen | 127.0.0.1:3030 | RPC server address |
--block-time-ms | 1000 | Target block time |
--produce-empty-blocks | true | Produce blocks even when mempool is empty |
--no-rate-limit | false | Disable RPC rate limiting (dev only) |
Genesis Allocation
Section titled “Genesis Allocation”Pre-fund accounts at genesis using --alloc:
# Single allocationnode init --data-dir ./node-data --alloc "0xADDR=1000000000000"
# Multiple allocationsnode init --data-dir ./node-data \ --alloc "0xADDR1=1000000000000" \ --alloc "0xADDR2=500000000000"
# Seeded accounts (deterministic for testing)node init --data-dir ./node-data \ --seed 42 \ --seed-count 10 \ --seed-balance 1000000000Fast Development Mode
Section titled “Fast Development Mode”For rapid iteration, reduce block time and disable rate limiting:
node run \ --data-dir ./node-data \ --block-time-ms 500 \ --no-rate-limit \ --produce-empty-blocksValidator Mode
Section titled “Validator Mode”Validator mode participates in consensus with other validators. This is required for production networks.
Prerequisites
Section titled “Prerequisites”- Ed25519 network key for P2P identity
- Peers configuration with all validator addresses
- BLS keys for threshold signatures (from DKG or testnet seed)
Deterministic Toolchain (Required)
Section titled “Deterministic Toolchain (Required)”Ashen validators validate the ELF output produced by the canonical compilers. If you build with a different Rust/LLVM/Zig toolchain, the ELF will not validate and your artifacts will be rejected. This is intentional: it protects developers from shipping binaries that the network cannot accept.
Do not go rogue on toolchains. Use the exact toolchain pinned by devenv (or the Docker image
built from devenv) for all contract builds and node runs in live environments. Validators run the
node inside that same Docker image in production.
1. Create Network Key
Section titled “1. Create Network Key”# Initialize keystoreashen keystore init
# Generate network keyashen keystore add --label my-validator
# Export address for peers.yamlashen keystore export --label my-validator2. Configure Peers
Section titled “2. Configure Peers”Create peers.yaml with all validator public keys and addresses:
addresses: "0x1234...abcd": "192.168.1.10:4040" "0x5678...efgh": "192.168.1.11:4040" "0x9abc...ijkl": "192.168.1.12:4040"3. Run Validator
Section titled “3. Run Validator”Testnet mode (deterministic BLS keys):
node run \ --data-dir /var/lib/ashen \ --validator \ --validator-network-key "keystore:my-validator" \ --peers ./peers.yaml \ --p2p-port 4040 \ --bls-seed 42 \ --validator-index 0 \ --bootstrapper "0x1234...abcd"Production mode (DKG-generated BLS keys):
node run \ --data-dir /var/lib/ashen \ --validator \ --validator-network-key "keystore:my-validator" \ --peers ./peers.yaml \ --p2p-port 4040 \ --bls-share "$BLS_SHARE" \ --bls-polynomial "$BLS_POLY" \ --bootstrapper "0x1234...abcd"Validator Options
Section titled “Validator Options”| Option | Description |
|---|---|
--validator | Enable validator mode |
--validator-network-key | Ed25519 key reference (keystore:<label>) |
--peers | Path to peers.yaml |
--p2p-port | P2P listen port (separate from RPC) |
--bootstrapper | Bootstrapper public key (repeatable) |
--bls-share | BLS threshold share (hex) |
--bls-polynomial | BLS commitment polynomial (hex) |
--bls-seed | Deterministic BLS seed (testnet) |
--validator-index | Your index in validator set (testnet) |
--enable-rpc | Enable full RPC (validators default to health/metrics only) |
--skip-preflight | Skip startup checks (not recommended) |
Preflight Checks
Section titled “Preflight Checks”Validators run preflight checks at startup:
- BLS Key — Validates share and polynomial format
- Disk Space — Requires at least 1GB free
- Clock Sync — Warns if system time appears off
- Data Directory — Verifies write access
To skip (development only):
node run --validator --skip-preflight ...Follower Mode
Section titled “Follower Mode”Follower nodes sync via P2P without participating in consensus. Use for:
- Archive nodes in different datacenters
- RPC nodes that don’t share storage with validators
- Read-only indexing nodes
node follower \ --data-dir ./follower-data \ --peers peers.yaml \ --bootstrapper "0x1234...abcd" \ --listen 127.0.0.1:3030 \ --p2p-port 4040Follower Options
Section titled “Follower Options”| Option | Default | Description |
|---|---|---|
--sync-batch-size | 32 | Headers per sync request |
--sync-poll-ms | 1000 | Poll interval when caught up |
--tx-forward-url | — | Forward transactions to this URL |
--network-key | — | Optional: specify P2P identity |
Transaction Forwarding
Section titled “Transaction Forwarding”Followers can forward transactions to a leader node:
node follower \ --tx-forward-url http://leader:3030 \ ...RPC Gateway Mode
Section titled “RPC Gateway Mode”RPC gateway mode runs a read-only RPC server that shares the data directory with a running node. Use to offload RPC traffic from validators.
# On the same machine as the validatornode rpc \ --data-dir /var/lib/ashen \ --listen 0.0.0.0:3030 \ --refresh-interval-s 1RPC Options
Section titled “RPC Options”| Option | Default | Description |
|---|---|---|
--refresh-interval-s | 1 | How often to reload from disk |
--rate-limit-per-s | 1000 | Requests per second |
--rate-limit-burst | 2000 | Burst allowance |
--auth-token | — | Optional authentication token |
Architecture
Section titled “Architecture” ┌─────────────────┐ Internet ────►│ RPC Gateway │──┐ │ (node rpc) │ │ └─────────────────┘ │ shared ├─ data-dir ┌─────────────────┐ │ Validators ◄──►│ Validator │──┘ │ (node run) │ └─────────────────┘State Management
Section titled “State Management”Archive Mode
Section titled “Archive Mode”Preserve all historical state (no pruning):
node run --archive-mode --data-dir ./archive-data ...Archive mode is required for:
- Historical queries at any block height
- State sync for new nodes
- Debugging and forensics
Pruning
Section titled “Pruning”Non-archive nodes prune old state to save disk space:
# Keep 10 epochs of state (default)node run --prune-keep-epochs 10 ...
# Keep more historynode run --prune-keep-epochs 100 ...Checkpoints
Section titled “Checkpoints”Checkpoints enable fast sync by providing state snapshots:
# Checkpoint every 1000 blocksnode run --checkpoint-interval 1000 ...
# Default: checkpoint at epoch boundariesnode run ...Monitoring
Section titled “Monitoring”Health Endpoint
Section titled “Health Endpoint”curl http://localhost:3030/health# Returns: {"status":"healthy"}Metrics Endpoint
Section titled “Metrics Endpoint”curl http://localhost:3030/metrics# Returns: Prometheus-format metricsKey Metrics
Section titled “Key Metrics”| Metric | Description |
|---|---|
ashen_tip_height | Current chain tip height |
ashen_finalized_height | Last finalized height |
ashen_mempool_size | Pending transaction count |
ashen_block_time_seconds | Recent block times |
ashen_rpc_requests_total | RPC request counter |
Agent Report
Section titled “Agent Report”Generate a diagnostic bundle:
just agent-report LISTEN=127.0.0.1:3030 OUT_DIR=./diagnosticsThis collects:
- Health status
- Metrics snapshot
- Recent log lines
- Chain status
Debugging
Section titled “Debugging”Execution Tracing
Section titled “Execution Tracing”Enable detailed execution traces:
# Trace to stdoutASHEN_TRACE_OUTPUT=1 node run --data-dir ./node-data
# Trace to filesASHEN_TRACE_OUTPUT_DIR=./traces node run --data-dir ./node-dataCompare Traces
Section titled “Compare Traces”just trace-diff trace_a.json trace_b.jsonDebug a Transaction
Section titled “Debug a Transaction”# Trace transaction executionashen debug trace --tx-hash 0x...
# Replay with breakpointsashen debug replay --tx-hash 0x... --breakpoint pc:0x1000Logging
Section titled “Logging”File Logging
Section titled “File Logging”node run \ --log-file /var/log/ashen/ \ --log-rotation daily \ --log-max-files 30 \ --log-prefix node \ ...Log Files
Section titled “Log Files”With rotation enabled, logs are named:
node.2026-01-22.lognode.2026-01-21.log- etc.
Environment Variables
Section titled “Environment Variables”| Variable | Description |
|---|---|
NODE_LOG_FILE | Log file path |
NODE_LOG_ROTATION | daily, hourly, or never |
NODE_LOG_MAX_FILES | Max rotated files to keep |
NODE_LOG_PREFIX | Log filename prefix |
RUST_LOG | Log level filter |
Security
Section titled “Security”Rate Limiting
Section titled “Rate Limiting”Default rate limits protect against DoS:
# Customize limitsnode run \ --rate-limit-per-s 5000 \ --rate-limit-burst 10000 \ ...
# Separate limits for utility endpointsnode run \ --utility-rate-limit-per-s 100 \ --utility-rate-limit-burst 200 \ ...Authentication
Section titled “Authentication”Protect RPC with bearer tokens:
# Server sidenode run --auth-token "secret-token-here" ...
# Client sideexport NODE_AUTH_TOKEN="secret-token-here"ashen statusNetwork Binding
Section titled “Network Binding”For production, bind RPC to localhost and use a reverse proxy:
# Node binds to localhostnode run --listen 127.0.0.1:3030 ...
# Nginx or Caddy handles TLS and public exposureOperations Runbook
Section titled “Operations Runbook”Starting a Node
Section titled “Starting a Node”# Check prerequisitesnode run --validator --skip-preflight=false --data-dir ./check-only 2>&1 | head -20
# Start with systemdsudo systemctl start ashen-node
# Or directlynode run --data-dir /var/lib/ashen --validator ...Stopping a Node
Section titled “Stopping a Node”Nodes handle SIGTERM gracefully:
# Graceful shutdownkill -TERM $(pgrep -f "node run")
# Or with systemdsudo systemctl stop ashen-nodeResetting State
Section titled “Resetting State”# Remove all state (DESTRUCTIVE)node reset --data-dir ./node-data
# Or manuallyrm -rf ./node-data/{chain,state,logs}Backup and Restore
Section titled “Backup and Restore”# Export snapshotashen backup export --data-dir ./node-data --output ./snapshot.tar
# Import snapshotashen backup import --data-dir ./new-node --input ./snapshot.tarTroubleshooting
Section titled “Troubleshooting”Node Won’t Start
Section titled “Node Won’t Start”“BLS key not found”
- Ensure
--bls-shareand--bls-polynomialare both provided - Or use
--bls-seed+--validator-indexfor testnet
“peer not found in config”
- Your public key must be in
peers.yaml - Check with
ashen keystore export --label my-validator
“disk space check failed”
- Ensure at least 1GB free in data directory
- Use
--skip-preflighttemporarily (not recommended)
Consensus Stalled
Section titled “Consensus Stalled”-
Check peer connectivity:
Terminal window curl http://localhost:3030/health -
Check logs for timeout messages:
Terminal window grep -i "timeout\|stall" /var/log/ashen/*.log -
Verify clock sync:
Terminal window timedatectl status
High Memory Usage
Section titled “High Memory Usage”- Reduce
--p2p-mailbox-sizeand--p2p-message-backlog - Enable pruning (disable
--archive-mode) - Reduce
--prune-keep-epochs
RPC Errors
Section titled “RPC Errors”“rate limited”
- Increase
--rate-limit-per-sand--rate-limit-burst - Or use
--no-rate-limitfor development
“body too large”
- Increase
--max-body-bytes
Related
Section titled “Related”- Installation — Build from source
- Configuration — Full configuration reference
- Using the CLI — CLI command reference
- Deploying Contracts — Contract deployment guide