Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands - CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround - CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check - NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere - MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates - LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference Co-authored-by: Cursor <cursoragent@cursor.com>
221 lines
8.0 KiB
Bash
Executable File
221 lines
8.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Load IP configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
|
|
|
|
|
|
|
# Verify and Update Node Lists (static-nodes.json and permissioned-nodes.json)
|
|
# Ensures each RPC node has unique enode with matching IP address
|
|
# All enodes must be in both static-nodes.json and permissioned-nodes.json on all nodes
|
|
|
|
set -e
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
|
|
# 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}"; }
|
|
|
|
# Configuration paths
|
|
STATIC_NODES_FILE="${1:-$PROJECT_ROOT/smom-dbis-138/config/static-nodes.json}"
|
|
PERMISSIONED_NODES_FILE="${2:-$PROJECT_ROOT/smom-dbis-138-proxmox/config/permissioned-nodes.json}"
|
|
|
|
# Expected RPC nodes with IPs (from ALL_VMIDS_ENDPOINTS.md)
|
|
declare -A RPC_NODES=(
|
|
# ThirdWeb RPC
|
|
["2400"]="${RPC_THIRDWEB_PRIMARY}"
|
|
["2401"]="${RPC_THIRDWEB_1:-${RPC_THIRDWEB_1:-${RPC_THIRDWEB_1:-${RPC_THIRDWEB_1:-192.168.11.241}}}}"
|
|
["2402"]="${RPC_THIRDWEB_2:-${RPC_THIRDWEB_2:-${RPC_THIRDWEB_2:-${RPC_THIRDWEB_2:-192.168.11.242}}}}"
|
|
# Public/Permissioned RPC
|
|
["2500"]="${RPC_ALLTRA_1:-192.168.11.250}"
|
|
["2501"]="${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-${RPC_ALI_1:-192.168.11.251}}}}"
|
|
["2502"]="${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-${RPC_ALI_2:-192.168.11.252}}}}"
|
|
["2503"]="192.168.11.253"
|
|
["2504"]="192.168.11.254"
|
|
# Named RPC
|
|
["2505"]="${IP_VAULT_PHOENIX_2:-192.168.11.201}"
|
|
["2506"]="192.168.11.202"
|
|
["2507"]="192.168.11.203"
|
|
["2508"]="192.168.11.204"
|
|
# VMID 2101 (if exists)
|
|
["2101"]="${RPC_CORE_1}"
|
|
)
|
|
|
|
# Validator nodes
|
|
declare -A VALIDATOR_NODES=(
|
|
["1000"]="${IP_VALIDATOR_0:-${IP_VALIDATOR_0:-${IP_VALIDATOR_0:-${IP_VALIDATOR_0:-192.168.11.100}}}}"
|
|
["1001"]="${IP_VALIDATOR_1:-${IP_VALIDATOR_1:-${IP_VALIDATOR_1:-${IP_VALIDATOR_1:-192.168.11.101}}}}"
|
|
["1002"]="${IP_VALIDATOR_2:-${IP_VALIDATOR_2:-${IP_VALIDATOR_2:-${IP_VALIDATOR_2:-192.168.11.102}}}}"
|
|
["1003"]="${IP_VALIDATOR_3:-${IP_VALIDATOR_3:-${IP_VALIDATOR_3:-${IP_VALIDATOR_3:-192.168.11.103}}}}"
|
|
["1004"]="${IP_VALIDATOR_4:-${IP_VALIDATOR_4:-${IP_VALIDATOR_4:-${IP_VALIDATOR_4:-192.168.11.104}}}}"
|
|
)
|
|
|
|
# Sentry nodes
|
|
declare -A SENTRY_NODES=(
|
|
["1500"]="${IP_BESU_RPC_0:-${IP_BESU_RPC_0:-${IP_BESU_RPC_0:-${IP_BESU_RPC_0:-192.168.11.150}}}}"
|
|
["1501"]="${IP_BESU_RPC_1:-${IP_BESU_RPC_1:-${IP_BESU_RPC_1:-${IP_BESU_RPC_1:-192.168.11.151}}}}"
|
|
["1502"]="${IP_BESU_RPC_2:-${IP_BESU_RPC_2:-${IP_BESU_RPC_2:-${IP_BESU_RPC_2:-192.168.11.152}}}}"
|
|
["1503"]="${IP_BESU_RPC_3:-${IP_BESU_RPC_3:-${IP_BESU_RPC_3:-${IP_BESU_RPC_3:-192.168.11.153}}}}"
|
|
["1504"]="${IP_BESU_SENTRY:-192.168.11.154}"
|
|
)
|
|
|
|
log_section "Node List Verification and Update"
|
|
|
|
log_info "Static nodes file: $STATIC_NODES_FILE"
|
|
log_info "Permissioned nodes file: $PERMISSIONED_NODES_FILE"
|
|
log_info ""
|
|
|
|
# Step 1: Verify files exist
|
|
if [ ! -f "$STATIC_NODES_FILE" ]; then
|
|
log_error "Static nodes file not found: $STATIC_NODES_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -f "$PERMISSIONED_NODES_FILE" ]; then
|
|
log_warn "Permissioned nodes file not found: $PERMISSIONED_NODES_FILE"
|
|
log_info "Creating new permissioned nodes file..."
|
|
mkdir -p "$(dirname "$PERMISSIONED_NODES_FILE")"
|
|
echo "[]" > "$PERMISSIONED_NODES_FILE"
|
|
fi
|
|
|
|
# Step 2: Parse current enodes from static-nodes.json
|
|
log_section "Step 1: Parsing Current Enodes"
|
|
|
|
STATIC_ENODES=()
|
|
while IFS= read -r line; do
|
|
# Extract enode from JSON (handles quotes and commas)
|
|
enode=$(echo "$line" | sed 's/^[[:space:]]*"\(.*\)",\?$/\1/' | grep -o 'enode://[^"]*' || true)
|
|
if [ -n "$enode" ]; then
|
|
STATIC_ENODES+=("$enode")
|
|
# Extract IP from enode
|
|
ip=$(echo "$enode" | sed -n 's/.*@\([0-9.]*\):.*/\1/p')
|
|
# Extract node ID (first 128 chars after enode://)
|
|
node_id=$(echo "$enode" | sed -n 's/enode:\/\/\([^@]*\).*/\1/p')
|
|
log_info " Found: $ip -> $node_id"
|
|
fi
|
|
done < <(cat "$STATIC_NODES_FILE" | jq -r '.[]' 2>/dev/null || cat "$STATIC_NODES_FILE" | grep -o 'enode://[^"]*' 2>/dev/null || echo "")
|
|
|
|
# Step 3: Check for duplicates and verify IP matching
|
|
log_section "Step 2: Checking for Duplicates and IP Mismatches"
|
|
|
|
declare -A ENODE_IPS=()
|
|
declare -A IP_ENODES=()
|
|
declare -A NODE_IDS=()
|
|
DUPLICATES_FOUND=false
|
|
IP_MISMATCHES=false
|
|
|
|
for enode in "${STATIC_ENODES[@]}"; do
|
|
if [ -z "$enode" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Extract components
|
|
node_id=$(echo "$enode" | sed -n 's/enode:\/\/\([^@]*\).*/\1/p')
|
|
ip=$(echo "$enode" | sed -n 's/.*@\([0-9.]*\):.*/\1/p')
|
|
port=$(echo "$enode" | sed -n 's/.*:\([0-9]*\)$/\1/p')
|
|
|
|
# Check for duplicate node IDs
|
|
if [ -n "${NODE_IDS[$node_id]}" ]; then
|
|
log_error "Duplicate node ID found: $node_id"
|
|
log_error " First: ${NODE_IDS[$node_id]}"
|
|
log_error " Duplicate: $enode"
|
|
DUPLICATES_FOUND=true
|
|
else
|
|
NODE_IDS[$node_id]="$enode"
|
|
fi
|
|
|
|
# Check for duplicate IPs with different enodes
|
|
if [ -n "${IP_ENODES[$ip]}" ] && [ "${IP_ENODES[$ip]}" != "$enode" ]; then
|
|
log_error "IP $ip has multiple enodes:"
|
|
log_error " ${IP_ENODES[$ip]}"
|
|
log_error " $enode"
|
|
IP_MISMATCHES=true
|
|
else
|
|
IP_ENODES[$ip]="$enode"
|
|
ENODE_IPS[$enode]="$ip"
|
|
fi
|
|
done
|
|
|
|
if [ "$DUPLICATES_FOUND" = false ] && [ "$IP_MISMATCHES" = false ]; then
|
|
log_success "No duplicates or IP mismatches found in static-nodes.json"
|
|
else
|
|
log_error "Issues found - please review and fix"
|
|
exit 1
|
|
fi
|
|
|
|
# Step 4: Verify permissioned-nodes.json matches
|
|
log_section "Step 3: Verifying Permissioned Nodes Match"
|
|
|
|
PERMISSIONED_ENODES=()
|
|
if command -v jq &> /dev/null; then
|
|
while IFS= read -r enode; do
|
|
if [ -n "$enode" ]; then
|
|
PERMISSIONED_ENODES+=("$enode")
|
|
fi
|
|
done < <(jq -r '.[]' "$PERMISSIONED_NODES_FILE" 2>/dev/null || echo "")
|
|
else
|
|
# Fallback to grep if jq not available
|
|
while IFS= read -r line; do
|
|
enode=$(echo "$line" | grep -o 'enode://[^"]*' || true)
|
|
if [ -n "$enode" ]; then
|
|
PERMISSIONED_ENODES+=("$enode")
|
|
fi
|
|
done < <(cat "$PERMISSIONED_NODES_FILE" 2>/dev/null || echo "")
|
|
fi
|
|
|
|
# Compare static and permissioned lists
|
|
STATIC_SORTED=$(printf '%s\n' "${STATIC_ENODES[@]}" | sort)
|
|
PERMISSIONED_SORTED=$(printf '%s\n' "${PERMISSIONED_ENODES[@]}" | sort)
|
|
|
|
if [ "$STATIC_SORTED" = "$PERMISSIONED_SORTED" ]; then
|
|
log_success "static-nodes.json and permissioned-nodes.json match"
|
|
else
|
|
log_warn "static-nodes.json and permissioned-nodes.json differ"
|
|
log_info "Updating permissioned-nodes.json to match static-nodes.json..."
|
|
|
|
# Update permissioned-nodes.json to match static-nodes.json
|
|
if command -v jq &> /dev/null; then
|
|
cp "$STATIC_NODES_FILE" "$PERMISSIONED_NODES_FILE"
|
|
log_success "Updated permissioned-nodes.json"
|
|
else
|
|
log_error "jq not available - cannot update permissioned-nodes.json"
|
|
log_info "Please manually update permissioned-nodes.json to match static-nodes.json"
|
|
fi
|
|
fi
|
|
|
|
# Step 5: Summary
|
|
log_section "Summary"
|
|
|
|
TOTAL_NODES=${#STATIC_ENODES[@]}
|
|
log_info "Total enodes in static-nodes.json: $TOTAL_NODES"
|
|
log_info "Total enodes in permissioned-nodes.json: ${#PERMISSIONED_ENODES[@]}"
|
|
log_info ""
|
|
|
|
log_info "Expected RPC nodes: ${#RPC_NODES[@]}"
|
|
log_info "Expected Validator nodes: ${#VALIDATOR_NODES[@]}"
|
|
log_info "Expected Sentry nodes: ${#SENTRY_NODES[@]}"
|
|
log_info ""
|
|
|
|
log_success "Verification complete!"
|
|
log_info ""
|
|
log_info "Next steps:"
|
|
log_info "1. Ensure static-nodes.json is deployed to ALL nodes"
|
|
log_info "2. Ensure permissioned-nodes.json is deployed to ALL nodes"
|
|
log_info "3. Restart Besu services on all nodes to apply changes"
|
|
log_info "4. Verify peer connections after restart"
|