#!/bin/bash # Info: Prepare script for Polkadot Validator # Author: Provisioning System # Release: 1.0 # Date: 2025-07-24 USAGE="prepare-polkadot-validator.sh" [ "$1" == "-h" ] && echo "$USAGE" && exit 1 [ -r "env-polkadot-validator" ] && . ./env-polkadot-validator echo "Preparing Polkadot Validator environment..." # Check if running as root for system preparation if [ "$EUID" -ne 0 ]; then echo "This preparation script must be run as root" exit 1 fi # Validate system requirements echo "Validating system requirements..." # Check CPU cores CPU_CORES=$(nproc) if [ "$CPU_CORES" -lt 8 ]; then echo "❌ CRITICAL: Polkadot validators require at least 8 CPU cores. Found: $CPU_CORES" exit 1 else echo "✅ CPU cores: $CPU_CORES (minimum 8 required)" fi # Check memory TOTAL_MEM=$(free -g | awk '/^Mem:/{print $2}') if [ "$TOTAL_MEM" -lt 32 ]; then echo "❌ CRITICAL: Polkadot validators require at least 32GB RAM. Found: ${TOTAL_MEM}GB" exit 1 else echo "✅ Memory: ${TOTAL_MEM}GB (minimum 32GB required)" fi # Check storage STORAGE_PATH=${POLKADOT_BASE_PATH:-/var/lib/polkadot/data} PARENT_DIR=$(dirname "$STORAGE_PATH") [ ! -d "$PARENT_DIR" ] && PARENT_DIR="/" AVAILABLE_SPACE_KB=$(df "$PARENT_DIR" | awk 'NR==2 {print $4}') AVAILABLE_SPACE_GB=$((AVAILABLE_SPACE_KB / 1024 / 1024)) if [ "$AVAILABLE_SPACE_GB" -lt 2000 ]; then echo "❌ CRITICAL: Polkadot validators require at least 2TB NVMe SSD storage" echo "Available: ${AVAILABLE_SPACE_GB}GB" exit 1 else echo "✅ Storage: ${AVAILABLE_SPACE_GB}GB available (minimum 2TB required)" fi # Check if storage is SSD (best effort) STORAGE_DEVICE=$(df "$PARENT_DIR" | awk 'NR==2 {print $1}' | sed 's/[0-9]*$//') if [ -f "/sys/block/$(basename "$STORAGE_DEVICE")/queue/rotational" ]; then IS_ROTATIONAL=$(cat "/sys/block/$(basename "$STORAGE_DEVICE")/queue/rotational" 2>/dev/null || echo "1") if [ "$IS_ROTATIONAL" = "0" ]; then echo "✅ Storage type: SSD/NVMe detected" else echo "⚠️ WARNING: Rotational storage detected. NVMe SSD strongly recommended for validators" fi fi # Check network connectivity echo "Checking network connectivity..." # Test internet connectivity if ping -c 1 -W 5 8.8.8.8 >/dev/null 2>&1; then echo "✅ Internet connectivity: Available" else echo "❌ CRITICAL: No internet connectivity detected" exit 1 fi # Check DNS resolution if nslookup github.com >/dev/null 2>&1; then echo "✅ DNS resolution: Working" else echo "❌ CRITICAL: DNS resolution not working" exit 1 fi # Test GitHub access (for binary downloads) if curl -s --connect-timeout 10 https://api.github.com/repos/paritytech/polkadot/releases/latest >/dev/null; then echo "✅ GitHub API access: Available" else echo "❌ CRITICAL: Cannot access GitHub API for Polkadot releases" exit 1 fi # Validate required ports echo "Checking port availability..." REQUIRED_PORTS="30333 9933 9944 9615" for port in $REQUIRED_PORTS; do if ss -tulnp | grep -q ":${port} "; then echo "⚠️ WARNING: Port $port is already in use" ss -tulnp | grep ":${port} " else echo "✅ Port $port: Available" fi done # Check system limits echo "Checking system limits..." # File descriptor limits CURRENT_ULIMIT=$(ulimit -n) if [ "$CURRENT_ULIMIT" -lt 65536 ]; then echo "⚠️ WARNING: File descriptor limit is $CURRENT_ULIMIT, should be at least 65536" echo "Consider adding to /etc/security/limits.conf:" echo "* soft nofile 65536" echo "* hard nofile 65536" else echo "✅ File descriptor limit: $CURRENT_ULIMIT" fi # Check systemd if ! systemctl --version >/dev/null 2>&1; then echo "❌ CRITICAL: systemd not available" exit 1 else echo "✅ Systemd: Available" fi # Validate environment variables echo "Validating environment configuration..." REQUIRED_VARS="POLKADOT_VERSION POLKADOT_CHAIN POLKADOT_VALIDATOR_NAME" for var in $REQUIRED_VARS; do if [ -z "${!var}" ]; then echo "❌ CRITICAL: Required environment variable $var is not set" exit 1 else echo "✅ $var: ${!var}" fi done # Validate chain name VALID_CHAINS="polkadot kusama westend" CHAIN_VALID=false for chain in $VALID_CHAINS; do if [ "${POLKADOT_CHAIN}" = "$chain" ]; then CHAIN_VALID=true break fi done if [ "$CHAIN_VALID" = "false" ]; then echo "❌ CRITICAL: Invalid chain '${POLKADOT_CHAIN}'. Valid chains: $VALID_CHAINS" exit 1 fi # Check for existing installation echo "Checking for existing Polkadot installation..." POLKADOT_BIN=${POLKADOT_BIN_PATH:-/usr/local/bin/polkadot} if [ -f "$POLKADOT_BIN" ]; then VERSION_OUTPUT=$("$POLKADOT_BIN" --version 2>/dev/null || echo "unknown") echo "⚠️ WARNING: Existing Polkadot installation found: $VERSION_OUTPUT" echo "Installation will overwrite existing binary" fi # Check systemd service if systemctl list-unit-files | grep -q "polkadot-validator.service"; then echo "⚠️ WARNING: polkadot-validator.service already exists" SERVICE_STATUS=$(systemctl is-active polkadot-validator.service 2>/dev/null || echo "inactive") echo "Current status: $SERVICE_STATUS" fi # Validate user configuration POLKADOT_USER=${POLKADOT_RUN_USER:-polkadot} if id "$POLKADOT_USER" >/dev/null 2>&1; then echo "⚠️ WARNING: User $POLKADOT_USER already exists" USER_HOME=$(getent passwd "$POLKADOT_USER" | cut -d: -f6) echo "User home: $USER_HOME" else echo "✅ User $POLKADOT_USER: Will be created" fi # Check directory permissions echo "Checking directory structure..." DIRECTORIES="/etc/polkadot /var/lib/polkadot /var/log/polkadot /var/backups/polkadot" for dir in $DIRECTORIES; do if [ -d "$dir" ]; then OWNER=$(stat -c '%U:%G' "$dir" 2>/dev/null || echo "unknown") PERMS=$(stat -c '%a' "$dir" 2>/dev/null || echo "unknown") echo "⚠️ WARNING: Directory $dir already exists (owner: $OWNER, perms: $PERMS)" else echo "✅ Directory $dir: Will be created" fi done # Security checks echo "Performing security checks..." # Check if fail2ban is available if command -v fail2ban-client >/dev/null 2>&1; then echo "✅ fail2ban: Available" else echo "⚠️ WARNING: fail2ban not installed (will be installed during setup)" fi # Check firewall if command -v ufw >/dev/null 2>&1; then UFW_STATUS=$(ufw status | head -1) echo "✅ UFW firewall: $UFW_STATUS" elif command -v firewall-cmd >/dev/null 2>&1; then FIREWALLD_STATUS=$(systemctl is-active firewalld 2>/dev/null || echo "inactive") echo "✅ firewalld: $FIREWALLD_STATUS" else echo "⚠️ WARNING: No firewall detected (will be configured during setup)" fi # Check for automatic updates if command -v unattended-upgrades >/dev/null 2>&1; then echo "✅ Automatic updates: unattended-upgrades available" elif command -v dnf >/dev/null 2>&1; then echo "✅ Automatic updates: dnf-automatic available" else echo "⚠️ WARNING: Automatic update system not detected" fi # Time synchronization check if systemctl is-active --quiet systemd-timesyncd || systemctl is-active --quiet ntp || systemctl is-active --quiet chrony; then echo "✅ Time synchronization: Active" else echo "⚠️ WARNING: Time synchronization service not active" echo "Accurate time is critical for validators" fi # Check entropy ENTROPY=$(cat /proc/sys/kernel/random/entropy_avail 2>/dev/null || echo "unknown") if [ "$ENTROPY" != "unknown" ] && [ "$ENTROPY" -lt 1000 ]; then echo "⚠️ WARNING: Low entropy ($ENTROPY). Consider installing haveged or rng-tools" else echo "✅ System entropy: $ENTROPY" fi # Final validation summary echo "" echo "=========================================" echo "Polkadot Validator Preparation Summary" echo "=========================================" echo "Chain: ${POLKADOT_CHAIN}" echo "Validator name: ${POLKADOT_VALIDATOR_NAME}" echo "Version: ${POLKADOT_VERSION}" echo "User: ${POLKADOT_USER}" echo "" # Check for critical issues CRITICAL_ISSUES=0 # Re-check critical requirements if [ "$CPU_CORES" -lt 8 ]; then echo "❌ CRITICAL: Insufficient CPU cores" CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1)) fi if [ "$TOTAL_MEM" -lt 32 ]; then echo "❌ CRITICAL: Insufficient memory" CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1)) fi if [ "$AVAILABLE_SPACE_GB" -lt 2000 ]; then echo "❌ CRITICAL: Insufficient storage" CRITICAL_ISSUES=$((CRITICAL_ISSUES + 1)) fi if [ "$CRITICAL_ISSUES" -gt 0 ]; then echo "" echo "❌ PREPARATION FAILED: $CRITICAL_ISSUES critical issue(s) found" echo "Please resolve the above issues before proceeding with installation" exit 1 fi echo "✅ All critical requirements met" echo "" echo "NEXT STEPS:" echo "1. Review any warnings above" echo "2. Run the installation script: ./install-polkadot-validator.sh" echo "3. Configure session keys after node sync" echo "4. Set up staking and validation" echo "" echo "SECURITY REMINDERS:" echo "- Ensure this server has proper backup procedures" echo "- Monitor the validator continuously" echo "- Keep the system updated" echo "- Never run duplicate validators with the same keys" echo "" exit 0