Files
proxmox/scripts/besu-collect-all-enodes.sh.bak
defiQUG fbda1b4beb
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
docs: Ledger Live integration, contract deploy learnings, NEXT_STEPS updates
- 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>
2026-02-12 15:46:57 -08:00

199 lines
5.5 KiB
Bash
Executable File

#!/bin/bash
# Collect enodes from all nodes and generate allowlist
# Usage: Update NODES array with your node IPs, then: bash collect-all-enodes.sh
set -euo pipefail
WORK_DIR="${WORK_DIR:-./besu-enodes-$(date +%Y%m%d-%H%M%S)}"
mkdir -p "$WORK_DIR"
# Node inventory: IP:RPC_PORT:USE_RPC (use_rpc=1 if RPC available, 0 for nodekey)
declare -A NODES=(
["192.168.11.13"]="8545:1" # validator-1
["192.168.11.14"]="8545:1" # validator-2
["192.168.11.15"]="8545:1" # validator-3
["192.168.11.16"]="8545:1" # validator-4
["192.168.11.18"]="8545:1" # validator-5
["192.168.11.19"]="8545:1" # sentry-2
["192.168.11.20"]="8545:1" # sentry-3
["192.168.11.21"]="8545:1" # sentry-4
["192.168.11.22"]="8545:1" # sentry-5
["192.168.11.23"]="8545:1" # rpc-1
["192.168.11.24"]="8545:1" # rpc-2
["192.168.11.25"]="8545:1" # rpc-3
)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SSH_USER="${SSH_USER:-root}"
SSH_OPTS="${SSH_OPTS:--o StrictHostKeyChecking=accept-new}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
validate_enode() {
local enode="$1"
local node_id
node_id=$(echo "$enode" | sed 's|^enode://||' | cut -d'@' -f1 | tr '[:upper:]' '[:lower:]')
if [[ ${#node_id} -ne 128 ]]; then
return 1
fi
if ! echo "$node_id" | grep -qE '^[0-9a-f]{128}$'; then
return 1
fi
return 0
}
extract_via_rpc() {
local ip="$1"
local rpc_port="$2"
local rpc_url="http://${ip}:${rpc_port}"
local response
response=$(curl -s -m 5 -X POST \
-H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"admin_nodeInfo","params":[],"id":1}' \
"${rpc_url}" 2>/dev/null || echo "")
if [[ -z "$response" ]]; then
return 1
fi
if echo "$response" | python3 -c "import sys, json; data=json.load(sys.stdin); sys.exit(0 if 'error' not in data else 1)" 2>/dev/null; then
return 1
fi
local enode
enode=$(echo "$response" | python3 -c "import sys, json; print(json.load(sys.stdin).get('result', {}).get('enode', ''))" 2>/dev/null)
if [[ -z "$enode" ]] || [[ "$enode" == "None" ]] || [[ "$enode" == "null" ]]; then
return 1
fi
if validate_enode "$enode"; then
echo "$enode"
return 0
fi
return 1
}
extract_via_ssh_nodekey() {
local ip="$1"
local ssh_target="${SSH_USER}@${ip}"
local enode
enode=$(ssh $SSH_OPTS "$ssh_target" bash << REMOTE_SCRIPT
DATA_PATH="/data/besu"
BESU_BIN="/opt/besu/bin/besu"
HOST_IP="${ip}"
for path in "\${DATA_PATH}/key" "\${DATA_PATH}/nodekey" "/keys/besu/nodekey"; do
if [[ -f "\$path" ]]; then
ENODE=\$("\${BESU_BIN}" public-key export --node-private-key-file="\$path" --format=enode 2>/dev/null | sed "s/@[0-9.]*:/@\${HOST_IP}:/")
if [[ -n "\$ENODE" ]]; then
echo "\$ENODE"
exit 0
fi
fi
done
exit 1
REMOTE_SCRIPT
)
if [[ -n "$enode" ]] && validate_enode "$enode"; then
echo "$enode"
return 0
fi
return 1
}
log_info "Starting enode collection..."
echo ""
COLLECTED_ENODES="$WORK_DIR/collected-enodes.txt"
DUPLICATES="$WORK_DIR/duplicates.txt"
INVALIDS="$WORK_DIR/invalid-enodes.txt"
> "$COLLECTED_ENODES"
> "$DUPLICATES"
> "$INVALIDS"
declare -A ENODE_BY_IP
declare -A NODE_ID_SET
for ip in "${!NODES[@]}"; do
IFS=':' read -r rpc_port use_rpc <<< "${NODES[$ip]}"
log_info "Processing node: $ip"
ENODE=""
if [[ "$use_rpc" == "1" ]]; then
ENODE=$(extract_via_rpc "$ip" "$rpc_port" || echo "")
fi
if [[ -z "$ENODE" ]]; then
ENODE=$(extract_via_ssh_nodekey "$ip" || echo "")
fi
if [[ -z "$ENODE" ]]; then
log_error "Failed to extract enode from $ip"
echo "$ip|FAILED" >> "$INVALIDS"
continue
fi
if ! validate_enode "$ENODE"; then
log_error "Invalid enode format from $ip"
echo "$ip|$ENODE" >> "$INVALIDS"
continue
fi
NODE_ID=$(echo "$ENODE" | sed 's|^enode://||' | cut -d'@' -f1)
ENDPOINT=$(echo "$ENODE" | sed 's|.*@||')
if [[ -n "${NODE_ID_SET[$NODE_ID]:-}" ]]; then
log_warn "Duplicate node ID: ${NODE_ID:0:32}..."
echo "$ip|$ENODE|DUPLICATE_NODE_ID|${NODE_ID_SET[$NODE_ID]}" >> "$DUPLICATES"
continue
fi
if [[ -n "${ENODE_BY_IP[$ENDPOINT]:-}" ]]; then
log_warn "Duplicate endpoint: $ENDPOINT"
echo "$ip|$ENODE|DUPLICATE_ENDPOINT|${ENODE_BY_IP[$ENDPOINT]}" >> "$DUPLICATES"
continue
fi
NODE_ID_SET[$NODE_ID]="$ip"
ENODE_BY_IP[$ENDPOINT]="$ip"
echo "$ip|$ENODE" >> "$COLLECTED_ENODES"
log_success "Collected: $ip"
done
VALID_COUNT=$(wc -l < "$COLLECTED_ENODES" 2>/dev/null || echo "0")
DUP_COUNT=$(wc -l < "$DUPLICATES" 2>/dev/null || echo "0")
INVALID_COUNT=$(wc -l < "$INVALIDS" 2>/dev/null || echo "0")
echo ""
log_info "Collection Summary:"
log_success "Valid enodes: $VALID_COUNT"
[[ "$DUP_COUNT" -gt 0 ]] && log_warn "Duplicates: $DUP_COUNT (see $DUPLICATES)"
[[ "$INVALID_COUNT" -gt 0 ]] && log_error "Invalid: $INVALID_COUNT (see $INVALIDS)"
echo ""
log_info "Output directory: $WORK_DIR"
log_info "Run: bash ${SCRIPT_DIR}/besu-generate-allowlist.sh $COLLECTED_ENODES"