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>
238 lines
7.4 KiB
Bash
238 lines
7.4 KiB
Bash
#!/usr/bin/env bash
|
|
# Verify enode addresses and IP addresses in static-nodes.json and permissions-nodes.toml.
|
|
# Ensures: (1) both files match (same enode@ip set), (2) IPs match expected VMID->IP mapping,
|
|
# (3) no duplicate node IDs (same key, different IPs).
|
|
#
|
|
# Usage: bash scripts/verify/verify-besu-enodes-and-ips.sh [--json]
|
|
# --json: output machine-readable summary only.
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
cd "$PROJECT_ROOT"
|
|
|
|
STATIC_FILE="${PROJECT_ROOT}/config/besu-node-lists/static-nodes.json"
|
|
PERM_FILE="${PROJECT_ROOT}/config/besu-node-lists/permissions-nodes.toml"
|
|
|
|
# Expected IP -> VMID/role (from config/ip-addresses.conf and BESU_NODES_FILE_REFERENCE)
|
|
declare -A EXPECTED_IP
|
|
EXPECTED_IP[192.168.11.100]=1000
|
|
EXPECTED_IP[192.168.11.101]=1001
|
|
EXPECTED_IP[192.168.11.102]=1002
|
|
EXPECTED_IP[192.168.11.103]=1003
|
|
EXPECTED_IP[192.168.11.104]=1004
|
|
EXPECTED_IP[192.168.11.150]=1500
|
|
EXPECTED_IP[192.168.11.151]=1501
|
|
EXPECTED_IP[192.168.11.152]=1502
|
|
EXPECTED_IP[192.168.11.153]=1503
|
|
EXPECTED_IP[192.168.11.154]=1504
|
|
EXPECTED_IP[192.168.11.211]=2101
|
|
EXPECTED_IP[192.168.11.212]=2102
|
|
EXPECTED_IP[192.168.11.221]=2201
|
|
EXPECTED_IP[192.168.11.232]=2301
|
|
EXPECTED_IP[192.168.11.233]=2303
|
|
EXPECTED_IP[192.168.11.234]=2304
|
|
EXPECTED_IP[192.168.11.235]=2305
|
|
EXPECTED_IP[192.168.11.236]=2306
|
|
EXPECTED_IP[192.168.11.240]=2400
|
|
EXPECTED_IP[192.168.11.241]=2401
|
|
EXPECTED_IP[192.168.11.242]=2402
|
|
EXPECTED_IP[192.168.11.243]=2403
|
|
EXPECTED_IP[192.168.11.172]=2500
|
|
EXPECTED_IP[192.168.11.173]=2501
|
|
EXPECTED_IP[192.168.11.174]=2502
|
|
EXPECTED_IP[192.168.11.246]=2503
|
|
EXPECTED_IP[192.168.11.247]=2504
|
|
EXPECTED_IP[192.168.11.248]=2505
|
|
EXPECTED_IP[192.168.11.213]=1505
|
|
EXPECTED_IP[192.168.11.214]=1506
|
|
EXPECTED_IP[192.168.11.244]=1507
|
|
EXPECTED_IP[192.168.11.245]=1508
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m'
|
|
log_ok() { echo -e "${GREEN}[✓]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
|
|
log_err() { echo -e "${RED}[✗]${NC} $1"; }
|
|
log_section() { echo -e "\n${CYAN}━━━ $1 ━━━${NC}\n"; }
|
|
|
|
JSON_OUT=false
|
|
[[ "${1:-}" = "--json" ]] && JSON_OUT=true
|
|
|
|
# Parse enode URLs from a line or JSON array: enode://<node_id>@<ip>:<port>
|
|
parse_enodes() {
|
|
local content="$1"
|
|
# Extract enode://...@...:30303 (optional ?discport=0 at end)
|
|
echo "$content" | grep -oE 'enode://[a-fA-F0-9]+@[0-9.]+:[0-9]+(\?discport=[0-9]+)?' | sed 's/?discport=0//' || true
|
|
}
|
|
|
|
# Get node_id (128 hex) from enode URL
|
|
node_id_from_enode() {
|
|
local enode="$1"
|
|
echo "$enode" | sed -n 's|enode://\([a-fA-F0-9]*\)@.*|\1|p'
|
|
}
|
|
|
|
# Get IP from enode URL
|
|
ip_from_enode() {
|
|
local enode="$1"
|
|
echo "$enode" | sed -n 's|enode://[a-fA-F0-9]*@\([0-9.]*\):.*|\1|p'
|
|
}
|
|
|
|
FAILED=0
|
|
|
|
if [[ ! -f "$STATIC_FILE" ]] || [[ ! -f "$PERM_FILE" ]]; then
|
|
log_err "Missing node list files: $STATIC_FILE or $PERM_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
# Collect enodes from static (JSON array)
|
|
STATIC_CONTENT=$(jq -r '.[]' "$STATIC_FILE" 2>/dev/null | tr -d '"' || cat "$STATIC_FILE")
|
|
# From permissions (TOML lines with enode://)
|
|
PERM_CONTENT=$(grep -oE 'enode://[^"]+' "$PERM_FILE" 2>/dev/null || true)
|
|
|
|
STATIC_ENODES=$(parse_enodes "$STATIC_CONTENT")
|
|
PERM_ENODES=$(parse_enodes "$PERM_CONTENT")
|
|
|
|
# Build set of node_id -> ip from static
|
|
declare -A STATIC_MAP
|
|
declare -A PERM_MAP
|
|
declare -A NODE_ID_COUNT
|
|
|
|
while IFS= read -r enode; do
|
|
[[ -z "$enode" ]] && continue
|
|
nid=$(node_id_from_enode "$enode")
|
|
ip=$(ip_from_enode "$enode")
|
|
[[ -n "$nid" && -n "$ip" ]] || continue
|
|
STATIC_MAP["$nid"]="$ip"
|
|
NODE_ID_COUNT["$nid"]=$((${NODE_ID_COUNT["$nid"]:-0} + 1))
|
|
done <<< "$STATIC_ENODES"
|
|
|
|
# Reset count for perm so we count per-file
|
|
declare -A PERM_NODE_COUNT
|
|
while IFS= read -r enode; do
|
|
[[ -z "$enode" ]] && continue
|
|
nid=$(node_id_from_enode "$enode")
|
|
ip=$(ip_from_enode "$enode")
|
|
[[ -n "$nid" && -n "$ip" ]] || continue
|
|
PERM_MAP["$nid"]="$ip"
|
|
PERM_NODE_COUNT["$nid"]=$((${PERM_NODE_COUNT["$nid"]:-0} + 1))
|
|
done <<< "$PERM_ENODES"
|
|
|
|
if $JSON_OUT; then
|
|
echo '{"static_count":'${#STATIC_MAP[@]}',"perm_count":'${#PERM_MAP[@]}',"issues":[]}'
|
|
exit 0
|
|
fi
|
|
|
|
log_section "Enode and IP verification"
|
|
|
|
# 1) Duplicate node IDs (same key, different IP) — critical
|
|
log_section "1. Duplicate node IDs (same enode key, different IPs)"
|
|
DUP_FOUND=0
|
|
for nid in "${!STATIC_MAP[@]}"; do
|
|
count=${NODE_ID_COUNT["$nid"]:-0}
|
|
if [[ "$count" -gt 1 ]]; then
|
|
log_err "Duplicate node ID in static-nodes: $nid appears multiple times (IPs may differ)."
|
|
((DUP_FOUND++)) || true
|
|
fi
|
|
done
|
|
# In our list we have .240 and .241 with same ID - check by IP count per nid
|
|
declare -A ID_TO_IPS
|
|
while IFS= read -r enode; do
|
|
[[ -z "$enode" ]] && continue
|
|
nid=$(node_id_from_enode "$enode")
|
|
ip=$(ip_from_enode "$enode")
|
|
[[ -z "$nid" ]] && continue
|
|
ID_TO_IPS["$nid"]="${ID_TO_IPS["$nid"]:-} $ip"
|
|
done <<< "$STATIC_ENODES"
|
|
for nid in "${!ID_TO_IPS[@]}"; do
|
|
ips="${ID_TO_IPS[$nid]}"
|
|
num_ips=$(echo "$ips" | wc -w)
|
|
if [[ "$num_ips" -gt 1 ]]; then
|
|
log_err "Same enode key used for multiple IPs: $nid -> $ips (each node must have a unique key)."
|
|
((DUP_FOUND++)) || true
|
|
((FAILED++)) || true
|
|
fi
|
|
done
|
|
if [[ "$DUP_FOUND" -eq 0 ]]; then
|
|
log_ok "No duplicate node IDs in static-nodes."
|
|
else
|
|
log_warn "Fix: Get the real enode for each VMID (e.g. admin_nodeInfo on 2401) and ensure unique keys."
|
|
fi
|
|
|
|
# 2) Static vs permissions match
|
|
log_section "2. static-nodes.json vs permissions-nodes.toml"
|
|
MISMATCH=0
|
|
for nid in "${!STATIC_MAP[@]}"; do
|
|
sip="${STATIC_MAP[$nid]}"
|
|
pip="${PERM_MAP[$nid]:-}"
|
|
if [[ -z "$pip" ]]; then
|
|
log_err "In static but not in permissions: node_id=${nid:0:16}... @ $sip"
|
|
((MISMATCH++)) || true
|
|
elif [[ "$sip" != "$pip" ]]; then
|
|
log_err "IP mismatch for same node_id: static=$sip permissions=$pip"
|
|
((MISMATCH++)) || true
|
|
((FAILED++)) || true
|
|
fi
|
|
done
|
|
for nid in "${!PERM_MAP[@]}"; do
|
|
if [[ -z "${STATIC_MAP[$nid]:-}" ]]; then
|
|
log_err "In permissions but not in static: node_id=${nid:0:16}... @ ${PERM_MAP[$nid]}"
|
|
((MISMATCH++)) || true
|
|
fi
|
|
done
|
|
if [[ "$MISMATCH" -eq 0 ]]; then
|
|
log_ok "Static and permissions lists match (same enodes, same IPs)."
|
|
else
|
|
((FAILED++)) || true
|
|
fi
|
|
|
|
# 3) IPs match expected mapping
|
|
log_section "3. IP addresses vs expected VMID mapping"
|
|
UNKNOWN_IP=0
|
|
for nid in "${!STATIC_MAP[@]}"; do
|
|
ip="${STATIC_MAP[$nid]}"
|
|
vmid="${EXPECTED_IP[$ip]:-}"
|
|
if [[ -z "$vmid" ]]; then
|
|
log_warn "IP $ip not in expected list (add to ip-addresses.conf / BESU_NODES_FILE_REFERENCE if intentional)."
|
|
((UNKNOWN_IP++)) || true
|
|
else
|
|
log_ok "$ip -> VMID $vmid"
|
|
fi
|
|
done
|
|
if [[ "$UNKNOWN_IP" -gt 0 ]]; then
|
|
log_warn "$UNKNOWN_IP IP(s) not in expected mapping (may be intentional, e.g. .154 when added)."
|
|
fi
|
|
|
|
# 4) Expected IPs missing from list
|
|
log_section "4. Expected nodes missing from lists"
|
|
for ip in "${!EXPECTED_IP[@]}"; do
|
|
vmid="${EXPECTED_IP[$ip]}"
|
|
found=false
|
|
for nid in "${!STATIC_MAP[@]}"; do
|
|
if [[ "${STATIC_MAP[$nid]}" = "$ip" ]]; then
|
|
found=true
|
|
break
|
|
fi
|
|
done
|
|
if [[ "$found" = false ]]; then
|
|
if [[ "$vmid" = 1504 ]]; then
|
|
log_warn "192.168.11.154 (VMID 1504) not in lists — add when enode is available."
|
|
else
|
|
log_warn "Expected $ip (VMID $vmid) not in static-nodes / permissions."
|
|
fi
|
|
fi
|
|
done
|
|
|
|
log_section "Summary"
|
|
if [[ "$FAILED" -eq 0 ]]; then
|
|
log_ok "Verification passed (no critical mismatches)."
|
|
else
|
|
log_err "$FAILED critical issue(s) found. Fix duplicate enode keys and static/permissions mismatch."
|
|
exit 1
|
|
fi
|
|
exit 0
|