Skip to main content

Validator Node Setup Guide

Overview

This comprehensive guide covers the complete process of setting up and operating a Savitri Network validator node. Validator nodes are critical for network security and consensus, requiring careful planning, proper hardware, and ongoing maintenance.

Technology Choice Rationale

Why Validator Setup Guide

Problem Statement: Setting up a validator node involves complex requirements including bond management, key security, consensus participation, and slashing protection, requiring detailed guidance for operators.

Chosen Solution: Comprehensive validator setup guide covering economics, hardware, security, operations, and troubleshooting.

Rationale:

  • Security: Proper key management and slashing protection
  • Economics: Clear understanding of bond requirements and rewards
  • Reliability: High availability and uptime requirements
  • Compliance: Adherence to network rules and regulations
  • Performance: Optimal hardware and network configuration

Expected Results:

  • Secure and reliable validator operations
  • Proper understanding of economic incentives and risks
  • High availability and performance
  • Compliance with network requirements
  • Effective risk management and mitigation

Validator Economics

Bond Requirements

Minimum Bond: 1,000,000 SAV tokens (~$1M+ USD value)

// Bond amount constants
pub const DEFAULT_BOND_AMOUNT: u128 = 1_000_000_000_000_000; // 1M tokens
pub const MIN_BOND_AMOUNT: u128 = 500_000_000_000_000; // 500K tokens
pub const MAX_BOND_AMOUNT: u128 = 10_000_000_000_000_000; // 10M tokens

Bond Economics:

  • Lock Period: 30 days minimum
  • Unbonding Period: 21 days withdrawal delay
  • Slashing Penalties: Up to 50% of bond amount
  • Reward Rate: Variable based on network participation

Reward Structure

Reward Calculation:

impl RewardCalculator {
pub fn calculate_validator_reward(&self, validator: &ValidatorInfo, block_height: u64) -> u128 {
let base_reward = (self.base_reward_rate * 1e18) as u128;

// Participation bonus (blocks participated / total blocks)
let participation_bonus = (validator.participation_rate * self.participation_multiplier) as u128;

// Uptime bonus (time online / total time)
let uptime_bonus = (validator.uptime_rate * self.uptime_multiplier) as u128;

// Performance bonus (blocks produced / expected blocks)
let performance_bonus = (validator.performance_rate * self.performance_multiplier) as u128;

let total_multiplier = 1.0 + participation_bonus + uptime_bonus + performance_bonus;

(base_reward * total_multiplier as u128) / 1000
}
}

Reward Distribution:

  • Block Rewards: Distributed to leader and active validators
  • Transaction Fees: Shared among participating validators
  • Network Fees: Distributed based on participation and performance
  • Slash Penalties: Distributed to honest validators when misbehavior detected

Risk Analysis

Slashing Conditions:

pub enum SlashingCondition {
// Equivocation (double signing)
DoubleSign {
block_height: u64,
first_signature: Signature,
second_signature: Signature,
},

// Unavailability (missing blocks)
Unavailable {
missed_slots: u64,
total_slots: u64,
period: Duration,
},

// Invalid block proposals
InvalidBlock {
block_hash: BlockHash,
reason: InvalidBlockReason,
},

// Vote manipulation
VoteManipulation {
conflicting_votes: Vec<Vote>,
},
}

Slashing Penalties:

  • Double Sign: 50% of bond amount
  • Unavailability: 10-30% based on downtime
  • Invalid Blocks: 20-40% based on severity
  • Vote Manipulation: 30-50% based on impact

Hardware Requirements

Minimum Specifications

CPU: 16 cores, 3.0GHz+ (Intel/AMD x64)

  • Rationale: Consensus processing, block production, parallel validation
  • Expected Performance: 2000+ TPS validation capacity

Memory: 32GB RAM

  • Rationale: State caching, consensus state, transaction pool
  • Expected Usage: 16GB for state, 8GB for consensus, 8GB for system

Storage: 1TB NVMe SSD

  • Rationale: Blockchain storage, consensus state, fast I/O for block production
  • Expected Growth: ~5GB per month with current network activity

Network: 1Gbps+ symmetric connection

  • Rationale: Consensus messaging, block propagation, low latency requirements
  • Expected Bandwidth: 100GB+ per month for consensus and P2P

CPU: 32 cores, 3.5GHz+ (Intel/AMD x64)

  • Benefits: Better consensus performance, higher TPS, parallel processing
  • Recommended: Intel Xeon or AMD EPYC series

Memory: 64GB RAM

  • Benefits: Larger state cache, better consensus performance, higher mempool
  • Recommended: ECC RAM for error correction

Storage: 2TB NVMe SSD + 10TB HDD

  • Benefits: Faster hot data access, extended historical retention
  • Configuration: Hot storage for recent data, cold storage for archives

Network: 10Gbps+ symmetric connection

  • Benefits: Faster consensus messaging, better block propagation
  • Recommended: Multiple network interfaces for redundancy

Hardware Benchmarking

CPU Performance Test:

# CPU benchmark
sysbench cpu --cpu-max-prime=20000 --threads=32 run

# Cryptographic performance
openssl speed -multi 4 aes-256-cbc
openssl speed -multi 4 sha256

Memory Performance Test:

# Memory bandwidth
sysbench memory --memory-block-size=1K --memory-total-size=32G run

# Memory latency
mlc --loaded_latency -D0 -R

Storage Performance Test:

# Disk I/O benchmark
fio --name=randwrite --ioengine=libaio --iodepth=16 --rw=randwrite --bs=4k --direct=1 --size=32G --numjobs=1 --runtime=60 --group_reporting

# Disk latency
ioping -c 10 /var/lib/savitri

Network Setup

Network Architecture

Network Topology:

Internet
|
|-- Router/Firewall
|
|-- Validator Node (Primary)
| |-- 10Gbps primary connection
| |-- 1Gbps backup connection
|
|-- Monitoring Node
| |-- 1Gbps connection
|
|-- Backup Storage
|-- 1Gbps connection

Network Configuration

Primary Network Interface:

# Configure 10Gbps interface
sudo ip link set dev eth0 up
sudo ip addr add 192.168.1.10/24 dev eth0
sudo ip route add default via 192.168.1.1 dev eth0

# Optimize network settings
echo 'net.core.rmem_max = 134217728' | sudo tee -a /etc/sysctl.conf
echo 'net.core.wmem_max = 134217728' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv4.tcp_rmem = 4096 87380 134217728' | sudo tee -a /etc/sysctl.conf
echo 'net.ipv4.tcp_wmem = 4096 65536 134217728' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Backup Network Interface:

# Configure backup interface
sudo ip link set dev eth1 up
sudo ip addr add 192.168.2.10/24 dev eth1

# Add backup route
sudo ip route add 192.168.2.0/24 via 192.168.2.1 dev eth1

Network Security

Firewall Configuration:

# Configure UFW firewall
sudo ufw --force reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow SSH (restricted)
sudo ufw allow from 192.168.1.0/24 to any port 22 proto tcp

# Allow P2P port
sudo ufw allow 30333/tcp

# Allow RPC (restricted)
sudo ufw allow from 192.168.1.0/24 to any port 8545 proto tcp

# Enable firewall
sudo ufw enable

DDoS Protection:

# Install fail2ban
sudo apt install fail2ban

# Configure fail2ban for Savitri
sudo tee /etc/fail2ban/jail.local << 'EOF'
[savitri-ddos]
enabled = true
port = 30333
filter = savitri-ddos
logpath = /var/log/savitri/node.log
maxretry = 100
bantime = 3600
findtime = 60
EOF

sudo systemctl restart fail2ban

Key Management

Key Generation

Generate Validator Key:

# Create secure key directory
sudo mkdir -p /etc/savitri/keys
sudo chmod 700 /etc/savitri/keys

# Generate new validator key
savitri-node key generate \
--scheme Ed25519 \
--output-file /etc/savitri/keys/validator-key.json \
--password-file /etc/savitri/keys/validator-password.txt

# Set secure permissions
sudo chmod 600 /etc/savitri/keys/validator-key.json
sudo chmod 600 /etc/savitri/keys/validator-password.txt

Key Backup:

# Create backup directory
sudo mkdir -p /backup/savitri/keys

# Backup keys
sudo cp /etc/savitri/keys/validator-key.json /backup/savitri/keys/
sudo cp /etc/savitri/keys/validator-password.txt /backup/savitri/keys/

# Encrypt backup
sudo gpg --symmetric --cipher-algo AES256 --output /backup/savitri/keys/validator-key.json.gpg /etc/savitri/keys/validator-key.json
sudo gpg --symmetric --cipher-algo AES256 --output /backup/savitri/keys/validator-password.txt.gpg /etc/savitri/keys/validator-password.txt

# Remove unencrypted backup
sudo rm /backup/savitri/keys/validator-key.json
sudo rm /backup/savitri/keys/validator-password.txt

Hardware Security Module (HSM)

HSM Configuration:

# Install HSM software
sudo apt install opensc-pkcs11

# Configure HSM
sudo tee /etc/savitri/hsm.conf << 'EOF'
[hsm]
library = /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so
slot = 0
pin = 123456
EOF

# Test HSM connection
pkcs11-tool --module /usr/lib/x86_64-linux-gnu/opensc-pkcs11.so --list-tokens

HSM Key Storage:

# Generate key in HSM
savitri-node key generate \
--scheme Ed25519 \
--key-store hsm \
--hsm-slot 0 \
--hsm-pin 123456 \
--output-file /etc/savitri/keys/hsm-key-reference.json

Software Installation

System Preparation

Update System:

# Update package lists
sudo apt update

# Upgrade packages
sudo apt upgrade -y

# Install required packages
sudo apt install -y build-essential pkg-config libssl-dev git curl wget

Create User Account:

# Create savitri user
sudo useradd -m -s /bin/bash savitri

# Add to required groups
sudo usermod -aG sudo,docker savitri

# Switch to savitri user
sudo su - savitri

Rust Installation

Install Rust:

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"

# Verify installation
rustc --version
cargo --version

Install Nightly Toolchain:

# Install nightly for latest features
rustup toolchain install nightly
rustup default nightly

# Install required components
rustup component add rustfmt clippy

Build Savitri Node

Clone Repository:

# Clone repository
git clone https://github.com/savitri-network/savitri-node.git
cd savitri-node

# Checkout specific version
git checkout v1.0.0

Build from Source:

# Build release version
cargo build --release --features validator

# Run tests
cargo test --release --features validator

# Install binary
sudo cp target/release/savitri-node /usr/local/bin/
sudo chmod +x /usr/local/bin/savitri-node

Configuration

Validator Configuration

Create Configuration File:

# /etc/savitri/validator.toml

[node]
# Node identity
name = "savitri-validator-01"
data_dir = "/var/lib/savitri"
log_level = "info"

# Network configuration
network = "mainnet"
bootnodes = [
"/ip4/104.131.131.82/tcp/30333/p2p/12D3KooWJvyP3UJ6ApXPArq9CWKijKp7N2QzMKK4bL2X9G1XQz1",
"/ip4/104.131.131.83/tcp/30333/p2p/12D3KooWJvyP3UJ6ApXPArq9CWKijKp7N2QzMKK4bL2X9G1XQz2",
]

# Validator configuration
[validator]
enable = true
key_file = "/etc/savitri/keys/validator-key.json"
password_file = "/etc/savitri/keys/validator-password.txt"
bond_amount = "1000000000000000" # 1M tokens

# Consensus configuration
[consensus]
slot_duration = 6000 # 6 seconds
epoch_duration = 432000 # 72 slots (12 minutes)
leader_rotation = "round-robin"

# Slashing protection
[slashing]
enable = true
history_length = 10000
evidence_storage = "database"

# RPC configuration
[rpc]
enable = true
external = false # Keep RPC internal for security
port = 8545
hosts = ["127.0.0.1"]

# WebSocket configuration
[websocket]
enable = true
external = false
port = 8546
hosts = ["127.0.0.1"]

# Database configuration
[database]
cache_size = "8GB"
max_open_files = 1000
write_buffer_size = "256MB"
compression = "zstd"

# Monitoring configuration
[monitoring]
prometheus_enable = true
prometheus_port = 9615
metrics_update_interval = 5000

Systemd Service

Create Service File:

# /etc/systemd/system/savitri-validator.service
[Unit]
Description=Savitri Network Validator Node
After=network.target
Wants=network-online.target

[Service]
Type=simple
User=savitri
Group=savitri
ExecStart=/usr/local/bin/savitri-node \
--config /etc/savitri/validator.toml \
--validator \
--base-path /var/lib/savitri
Restart=always
RestartSec=10
StartLimitInterval=60
StartLimitBurst=3

# Security settings
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/savitri /var/log/savitri

# Resource limits
LimitNOFILE=65536
LimitNPROC=4096

# Environment variables
Environment=RUST_LOG=info
Environment=RUST_BACKTRACE=1

[Install]
WantedBy=multi-user.target

Enable and Start Service:

# Reload systemd
sudo systemctl daemon-reload

# Enable service
sudo systemctl enable savitri-validator

# Start service
sudo systemctl start savitri-validator

# Check status
sudo systemctl status savitri-validator

Bond Management

Initial Bond Setup

Create Bond Transaction:

# Create bond transaction
savitri-node \
--config /etc/savitri/validator.toml \
validator bond \
--amount 1000000000000000 \
--key-file /etc/savitri/keys/validator-key.json \
--password-file /etc/savitri/keys/validator-password.txt \
--output bond-transaction.json

Sign and Submit Bond:

# Sign transaction
savitri-node \
transaction sign \
--input bond-transaction.json \
--key-file /etc/savitri/keys/validator-key.json \
--password-file /etc/savitri/keys/validator-password.txt \
--output signed-bond-transaction.json

# Submit transaction
savitri-node \
transaction submit \
--input signed-bond-transaction.json

Bond Management Operations

Increase Bond:

# Increase bond amount
savitri-node \
--config /etc/savitri/validator.toml \
validator bond-increase \
--additional-amount 500000000000000 \
--key-file /etc/savitri/keys/validator-key.json \
--password-file /etc/savitri/keys/validator-password.txt

Unbond (Withdraw):

# Initiate unbonding
savitri-node \
--config /etc/savitri/validator.toml \
validator unbond \
--amount 500000000000000 \
--key-file /etc/savitri/keys/validator-key.json \
--password-file /etc/savitri/keys/validator-password.txt

# Withdraw after unbonding period
savitri-node \
--config /etc/savitri/validator.toml \
validator withdraw \
--amount 500000000000000 \
--destination 0x1234567890123456789012345678901234567890 \
--key-file /etc/savitri/keys/validator-key.json \
--password-file /etc/savitri/keys/validator-password.txt

Monitoring and Alerting

Prometheus Monitoring

Prometheus Configuration:

# /etc/prometheus/prometheus.yml
global:
scrape_interval: 15s

scrape_configs:
- job_name: 'savitri-validator'
static_configs:
- targets: ['localhost:9615']
scrape_interval: 5s
metrics_path: /metrics

Key Metrics:

# Block production rate
savitri_block_production_total

# Consensus participation
savitri_consensus_participation_rate

# Validator uptime
savitri_validator_uptime_seconds

# Bond amount
savitri_validator_bond_amount

# Slashing events
savitri_validator_slashing_events_total

Grafana Dashboard

Dashboard Configuration:

{
"dashboard": {
"title": "Savitri Validator Monitoring",
"panels": [
{
"title": "Block Production Rate",
"type": "graph",
"targets": [
{
"expr": "rate(savitri_block_production_total[5m])",
"legendFormat": "Blocks/sec"
}
],
"yAxes": [
{
"label": "Blocks per Second"
}
]
},
{
"title": "Consensus Participation",
"type": "stat",
"targets": [
{
"expr": "savitri_consensus_participation_rate",
"legendFormat": "Participation Rate"
}
]
},
{
"title": "Validator Uptime",
"type": "stat",
"targets": [
{
"expr": "savitri_validator_uptime_seconds",
"legendFormat": "Uptime"
}
]
},
{
"title": "Bond Amount",
"type": "stat",
"targets": [
{
"expr": "savitri_validator_bond_amount",
"legendFormat": "Bond Amount"
}
]
}
]
}
}

Alerting Rules

Prometheus Alert Rules:

# /etc/prometheus/validator-alerts.yml
groups:
- name: validator-alerts
rules:
- alert: ValidatorDown
expr: up{job="savitri-validator"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Validator node is down"
description: "Validator node {{ $labels.instance }} has been down for more than 1 minute"

- alert: LowParticipation
expr: savitri_consensus_participation_rate < 0.95
for: 5m
labels:
severity: warning
annotations:
summary: "Low consensus participation"
description: "Validator participation rate is {{ $value }}%"

- alert: SlashingEvent
expr: increase(savitri_validator_slashing_events_total[5m]) > 0
for: 0m
labels:
severity: critical
annotations:
summary: "Slashing event detected"
description: "Validator has been slashed"

Security Best Practices

Key Security

Multi-Signature Protection:

# Generate multiple keys
savitri-node key generate --scheme Ed25519 --output-file key1.json
savitri-node key generate --scheme Ed25519 --output-file key2.json
savitri-node key generate --scheme Ed25519 --output-file key3.json

# Create multi-sig configuration
savitri-node multi-sig create \
--keys key1.json,key2.json,key3.json \
--threshold 2 \
--output-file multi-sig-config.json

Hardware Security Module:

# Use HSM for key storage
savitri-node \
--key-store hsm \
--hsm-slot 0 \
--hsm-pin-file /etc/savitri/hsm-pin.txt

Network Security

VPN Configuration:

# Install WireGuard
sudo apt install wireguard

# Generate keys
wg genkey | sudo tee /etc/wireguard/private.key
sudo chmod 600 /etc/wireguard/private.key
sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key

# Configure WireGuard
sudo tee /etc/wireguard/wg0.conf << 'EOF'
[Interface]
PrivateKey = $(cat /etc/wireguard/private.key)
Address = 10.0.0.1/24
DNS = 8.8.8.8

[Peer]
PublicKey = PEER_PUBLIC_KEY
Endpoint = peer.example.com:51820
AllowedIPs = 10.0.0.2/32
EOF

# Enable WireGuard
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0

System Security

AppArmor Profile:

# Create AppArmor profile
sudo tee /etc/apparmor.d/usr.local.bin.savitri-node << 'EOF'
#include <tunables/global>

/usr/local/bin/savitri-node {
#include <abstractions/base>
#include <abstractions/nameservice>

/var/lib/savitri/** rw,
/etc/savitri/** r,
/var/log/savitri/** w,

network inet stream,
network inet dgram,

deny /proc/sys/** w,
deny /sys/** w,
}
EOF

# Load profile
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.savitri-node
sudo apparmor_parser -r /etc/apparmor.d/usr.local.bin.savitri-node

Troubleshooting

Common Issues

Validator Not Producing Blocks:

# Check validator status
curl -X POST http://localhost:8545 -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"validator_status","params":[],"id":1}'

# Check bond status
curl -X POST http://localhost:8545 -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"validator_bondStatus","params":["0x..."],"id":1}'

# Check consensus participation
curl -X POST http://localhost:8545 -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"validator_participation","params":[],"id":1}'

High Memory Usage:

# Check memory usage
ps aux | grep savitri-node
free -h

# Check RocksDB cache
curl -X POST http://localhost:8545 -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"database_stats","params":[],"id":1}'

# Reduce cache size if needed
# Edit /etc/savitri/validator.toml
# [database]
# cache_size = "4GB"

Network Connectivity Issues:

# Check peer connections
curl -X POST http://localhost:8545 -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"system_peers","params":[],"id":1}'

# Check network latency
ping -c 5 104.131.131.82

# Check bandwidth usage
iftop -i eth0

Performance Optimization

Database Optimization:

# RocksDB tuning
savitri-node \
--db-cache-size 16GB \
--db-write-buffer-size 512MB \
--db-max-background-compactions 4 \
--db-max-background-flushes 2

Consensus Optimization:

# Consensus tuning
savitri-node \
--consensus-cache-size 1GB \
--consensus-threads 8 \
--consensus-batch-size 100

Maintenance

Regular Maintenance Tasks

Daily Tasks:

#!/bin/bash
# daily-maintenance.sh

# Check validator status
systemctl status savitri-validator

# Check bond status
curl -X POST http://localhost:8545 -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"validator_bondStatus","params":["0x..."],"id":1}'

# Check logs for errors
grep -i error /var/log/savitri/validator.log | tail -10

# Check system resources
free -h
df -h /var/lib/savitri

Weekly Tasks:

#!/bin/bash
# weekly-maintenance.sh

# Update software
git pull origin main
cargo build --release
sudo systemctl restart savitri-validator

# Backup configuration
sudo cp -r /etc/savitri /backup/savitri-config-$(date +%Y%m%d)

# Check performance metrics
curl -X POST http://localhost:8545 -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"validator_performance","params":[],"id":1}'

Monthly Tasks:

#!/bin/bash
# monthly-maintenance.sh

# Full backup
sudo tar -czf /backup/savitri-full-$(date +%Y%m%d).tar.gz /var/lib/savitri /etc/savitri

# Security audit
sudo apparmor_status
sudo ufw status verbose

# Performance review
iostat -x 1 5
sar -u 1 5

Backup and Recovery

Automated Backup:

#!/bin/bash
# backup-validator.sh

BACKUP_DIR="/backup/savitri"
DATE=$(date +%Y%m%d_%H%M%S)

# Create backup directory
mkdir -p "$BACKUP_DIR"

# Backup node data
sudo tar -czf "$BACKUP_DIR/validator-data-$DATE.tar.gz" /var/lib/savitri

# Backup configuration
sudo cp -r /etc/savitri "$BACKUP_DIR/config-$DATE"

# Backup keys (encrypted)
sudo gpg --symmetric --cipher-algo AES256 \
--output "$BACKUP_DIR/keys-$DATE.gpg" \
/etc/savitri/keys/validator-key.json

# Cleanup old backups (keep 7 days)
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete
find "$BACKUP_DIR" -name "*.gpg" -mtime +7 -delete

echo "Backup completed: $BACKUP_DIR/validator-data-$DATE.tar.gz"

Recovery Procedure:

#!/bin/bash
# recover-validator.sh

BACKUP_FILE=$1

if [ -z "$BACKUP_FILE" ]; then
echo "Usage: $0 <backup-file>"
exit 1
fi

# Stop validator
sudo systemctl stop savitri-validator

# Backup current data
sudo mv /var/lib/savitri /var/lib/savitri.bak

# Restore from backup
sudo tar -xzf "$BACKUP_FILE" -C /

# Restore configuration
sudo cp -r /backup/savitri/config-* /etc/savitri/

# Set permissions
sudo chown -R savitri:savitri /var/lib/savitri
sudo chmod 600 /etc/savitri/keys/*

# Start validator
sudo systemctl start savitri-validator

# Verify recovery
systemctl status savitri-validator

This comprehensive validator setup guide provides everything needed to successfully operate a Savitri Network validator node with proper security, monitoring, and maintenance procedures.