#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" source "${PROJECT_ROOT}/scripts/lib/vmid-ip-maps.sh" 2>/dev/null || true # Analyze and Fix Node Lists # Matches RPC nodes with static-nodes.json and permissioned-nodes.json # Identifies gaps, inconsistencies, duplicates, and updates files # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_section() { echo -e "\n${CYAN}=== $1 ===${NC}"; } STATIC_NODES_FILE="$PROJECT_ROOT/smom-dbis-138/config/static-nodes.json" PERMISSIONED_NODES_FILE="$PROJECT_ROOT/smom-dbis-138-proxmox/config/permissioned-nodes.json" # VALIDATOR_NODES, SENTRY_NODES, RPC_NODES from scripts/lib/vmid-ip-maps.sh # Collect all expected IPs declare -A EXPECTED_IPS for ip in "${VALIDATOR_NODES[@]}" "${SENTRY_NODES[@]}" "${RPC_NODES[@]}"; do EXPECTED_IPS["$ip"]=1 done log_section "Analyzing Node Lists" # Parse current static-nodes.json declare -A CURRENT_ENODES declare -A IP_TO_ENODE declare -A ENODE_TO_IP if [ -f "$STATIC_NODES_FILE" ]; then while IFS= read -r line; do enode=$(echo "$line" | grep -o 'enode://[^"]*' || echo "") if [ -n "$enode" ]; then ip=$(echo "$enode" | sed -n 's/.*@\([0-9.]*\):.*/\1/p') CURRENT_ENODES["$ip"]="$enode" IP_TO_ENODE["$ip"]="$enode" ENODE_TO_IP["$enode"]="$ip" fi done < <(cat "$STATIC_NODES_FILE" | jq -r '.[]' 2>/dev/null || grep -o 'enode://[^"]*' "$STATIC_NODES_FILE" 2>/dev/null || echo "") fi log_info "Current enodes in static-nodes.json: ${#CURRENT_ENODES[@]}" log_info "Expected nodes (validators + sentries + RPC): $((${#VALIDATOR_NODES[@]} + ${#SENTRY_NODES[@]} + ${#RPC_NODES[@]}))" log_info "" # Identify gaps and inconsistencies log_section "Identifying Issues" MISSING_IPS=() UNKNOWN_IPS=() DUPLICATES=() ISSUES_FOUND=0 # Check for missing expected IPs log_info "Checking for missing nodes..." for ip in "${!EXPECTED_IPS[@]}"; do if [ -z "${CURRENT_ENODES[$ip]}" ]; then MISSING_IPS+=("$ip") log_warn " Missing: $ip" ((ISSUES_FOUND++)) fi done # Check for unknown IPs (not in expected list) log_info "" log_info "Checking for unknown/unexpected IPs..." for ip in "${!CURRENT_ENODES[@]}"; do if [ -z "${EXPECTED_IPS[$ip]}" ]; then UNKNOWN_IPS+=("$ip") log_warn " Unknown IP: $ip (enode: ${CURRENT_ENODES[$ip]})" ((ISSUES_FOUND++)) fi done # Summary log_section "Analysis Summary" log_info "Missing nodes: ${#MISSING_IPS[@]}" if [ ${#MISSING_IPS[@]} -gt 0 ]; then for ip in "${MISSING_IPS[@]}"; do log_info " - $ip" done fi log_info "" log_info "Unknown IPs in file: ${#UNKNOWN_IPS[@]}" if [ ${#UNKNOWN_IPS[@]} -gt 0 ]; then for ip in "${UNKNOWN_IPS[@]}"; do log_info " - $ip (enode: ${CURRENT_ENODES[$ip]})" done fi log_info "" if [ $ISSUES_FOUND -eq 0 ]; then log_success "No issues found - files are consistent" else log_warn "Found $ISSUES_FOUND issues" log_info "" log_info "Note: Missing nodes will need their enodes collected from running nodes" log_info "Unknown IPs may be from old/decommissioned nodes or need verification" fi # Create report REPORT_FILE="$PROJECT_ROOT/docs/06-besu/NODE_LIST_ANALYSIS_REPORT.md" cat > "$REPORT_FILE" << EOF # Node List Analysis Report **Date**: $(date) **Status**: Analysis Complete --- ## Summary - **Current enodes in file**: ${#CURRENT_ENODES[@]} - **Expected nodes**: $((${#VALIDATOR_NODES[@]} + ${#SENTRY_NODES[@]} + ${#RPC_NODES[@]})) - **Missing nodes**: ${#MISSING_IPS[@]} - **Unknown IPs**: ${#UNKNOWN_IPS[@]} --- ## Missing Nodes (${#MISSING_IPS[@]}) These nodes are expected but not found in static-nodes.json: EOF if [ ${#MISSING_IPS[@]} -gt 0 ]; then for ip in "${MISSING_IPS[@]}"; do echo "- **$ip**" >> "$REPORT_FILE" done else echo "None - all expected nodes are present" >> "$REPORT_FILE" fi cat >> "$REPORT_FILE" << EOF --- ## Unknown IPs (${#UNKNOWN_IPS[@]}) These IPs are in static-nodes.json but not in expected node list: EOF if [ ${#UNKNOWN_IPS[@]} -gt 0 ]; then for ip in "${UNKNOWN_IPS[@]}"; do echo "- **$ip** - Enode: \`${CURRENT_ENODES[$ip]}\`" >> "$REPORT_FILE" done echo "" >> "$REPORT_FILE" echo "**Action Required**: Verify if these are old/decommissioned nodes or need to be added to expected list" >> "$REPORT_FILE" else echo "None - all IPs in file are expected" >> "$REPORT_FILE" fi log_info "" log_info "Report saved to: $REPORT_FILE"