Files
proxmox/scripts/setup-thirdweb-rpc-nodes.sh
defiQUG cb47cce074 Complete markdown files cleanup and organization
- Organized 252 files across project
- Root directory: 187 → 2 files (98.9% reduction)
- Moved configuration guides to docs/04-configuration/
- Moved troubleshooting guides to docs/09-troubleshooting/
- Moved quick start guides to docs/01-getting-started/
- Moved reports to reports/ directory
- Archived temporary files
- Generated comprehensive reports and documentation
- Created maintenance scripts and guides

All files organized according to established standards.
2026-01-06 01:46:25 -08:00

536 lines
19 KiB
Bash
Executable File

#!/usr/bin/env bash
# Setup ThirdWeb RPC Node LXC Containers
# Creates and configures Besu RPC nodes optimized for ThirdWeb integration
#
# VMIDs: 2400-2402 (ThirdWeb RPC nodes) - aligned with IP addresses
# IP Range: 192.168.11.240-242 (VMIDs 2400-2402)
# IP Management: VMID 2400 = 192.168.11.240, VMID 2401 = 192.168.11.241, etc.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
CONFIG_DIR="$PROJECT_ROOT/smom-dbis-138/config"
# Configuration
PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.10}"
STORAGE="${STORAGE:-local-lvm}" # Use local-lvm (LVM-thin) like other containers
TEMPLATE="${TEMPLATE:-local:vztmpl/debian-12-standard_12.12-1_amd64.tar.zst}"
NETWORK="${NETWORK:-vmbr0}"
GATEWAY="${GATEWAY:-192.168.11.1}"
# Colors
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}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# VMID to IP Address Mapping Function
# Maps VMID to IP based on VMID pattern for 192.168.11.X network:
# - 4-digit VMID (2400-2499) -> last octet matches last 2 digits
# - Example: VMID 2400 = 192.168.11.240, VMID 2401 = 192.168.11.241
vmid_to_ip() {
local vmid=$1
local base_network="${2:-192.168.11}"
# For 4-digit VMIDs in 192.168.11.X network
if [[ $vmid =~ ^[0-9]{4}$ ]] && [[ "$base_network" == "192.168.11" ]]; then
local last_octet=$((vmid % 1000))
# Ensure last octet is in valid range (1-254, since .255 is broadcast)
if [[ $last_octet -ge 1 ]] && [[ $last_octet -le 254 ]]; then
echo "${base_network}.${last_octet}"
return 0
fi
fi
# Fallback: return empty (should not happen with valid VMIDs)
echo ""
return 1
}
# ThirdWeb RPC Node Configuration
# VMIDs 2400-2402 map to IPs 192.168.11.240-242 (aligned numbering)
# Note: .254 is last usable IP, .255 is broadcast in /24 network
# Existing RPC nodes use .250-252 (VMIDs 2500-2502)
declare -A THIRDWEB_RPC_NODES=(
[2400]="thirdweb-rpc-1:192.168.11.240:ThirdWeb RPC Node 1 (Primary)"
[2401]="thirdweb-rpc-2:192.168.11.241:ThirdWeb RPC Node 2 (Secondary)"
[2402]="thirdweb-rpc-3:192.168.11.242:ThirdWeb RPC Node 3 (Tertiary)"
)
# Resource specifications per node
MEMORY_GB=16
CPU_CORES=4
DISK_GB=200
# Check SSH access
check_ssh_access() {
log_info "Checking SSH access to $PROXMOX_HOST..."
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} "echo 'SSH OK'" &>/dev/null; then
log_success "SSH access confirmed"
return 0
else
log_error "Cannot access $PROXMOX_HOST via SSH"
log_error "Please ensure:"
log_error " 1. SSH key is set up"
log_error " 2. Host is reachable"
log_error " 3. Root access is available"
return 1
fi
}
# Check if container exists
container_exists() {
local vmid=$1
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
"pct list | grep -q '^$vmid ' && echo 'exists' || echo 'missing'" 2>/dev/null || echo "error"
}
# Create a container
create_container() {
local vmid=$1
local hostname=$2
local ip=$3
local description="$4"
log_info "Creating container $vmid: $hostname ($ip)..."
# Check if already exists
local exists=$(container_exists "$vmid")
if [[ "$exists" == "exists" ]]; then
log_warn "Container $vmid already exists, skipping creation..."
return 0
fi
log_info " Memory: ${MEMORY_GB}GB, CPU: ${CPU_CORES} cores, Disk: ${DISK_GB}GB"
log_info " Creating with DHCP first, then configuring static IP..."
# Create container with DHCP (more reliable)
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} <<CREATE_CONTAINER_EOF
set -e
pct create $vmid $TEMPLATE \
--hostname $hostname \
--memory $((MEMORY_GB * 1024)) \
--cores ${CPU_CORES} \
--rootfs ${STORAGE}:${DISK_GB} \
--net0 name=eth0,bridge=${NETWORK},ip=dhcp,type=veth \
--description "$description" \
--start 1 \
--onboot 1 \
--unprivileged 0 \
--features nesting=1,keyctl=1
CREATE_CONTAINER_EOF
if [ $? -eq 0 ]; then
log_success "Container $vmid created successfully with DHCP"
# Wait for container to start
log_info " Waiting for container to start..."
sleep 8
# Check status
local status=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
"pct status $vmid 2>/dev/null | awk '{print \$2}'" || echo "unknown")
if [[ "$status" == "running" ]]; then
log_success " Container $vmid is running"
# Now configure static IP
log_info " Configuring static IP: $ip/24"
local configure_result=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} bash -s <<CONFIGURE_IP_EOF
set -e
VMID=$vmid
NETWORK=$NETWORK
IP=$ip
GATEWAY=$GATEWAY
# Stop container to configure network
pct stop \$VMID 2>/dev/null || true
sleep 2
# Get current MAC address from config (if exists)
MAC_ADDRESS=\$(pct config \$VMID 2>/dev/null | grep "^net0:" | sed -n 's/.*hwaddr=\\([^,]*\\).*/\\1/p' || echo "")
if [[ -z "\$MAC_ADDRESS" ]]; then
# Generate a new MAC address if not found
MAC_ADDRESS=\$(printf "02:00:27:%02x:%02x:%02x" \$((RANDOM%256)) \$((RANDOM%256)) \$((RANDOM%256)))
fi
# Configure static IP
if pct set \$VMID --net0 name=eth0,bridge=\$NETWORK,hwaddr=\$MAC_ADDRESS,ip=\$IP/24,gw=\$GATEWAY,type=veth; then
# Start container
pct start \$VMID
echo "SUCCESS"
else
echo "FAILED"
exit 1
fi
CONFIGURE_IP_EOF
)
if echo "$configure_result" | grep -q "SUCCESS"; then
log_success " Static IP configured: $ip/24"
sleep 5
else
log_warn " Failed to configure static IP, container is running with DHCP"
log_info " Attempting to start container anyway..."
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} "pct start $vmid 2>/dev/null || true"
fi
else
log_warn " Container $vmid status: $status"
fi
return 0
else
log_error "Failed to create container $vmid"
return 1
fi
}
# Setup container with Besu RPC
setup_besu_rpc() {
local vmid=$1
local hostname=$2
local ip=$3
log_info "Setting up Besu RPC on container $vmid..."
# Copy installation script
local install_script="$SCRIPT_DIR/../smom-dbis-138-proxmox/install/besu-rpc-install.sh"
if [[ ! -f "$install_script" ]]; then
log_error "Besu installation script not found: $install_script"
return 1
fi
# Copy config file
local config_file="$CONFIG_DIR/config-rpc-thirdweb.toml"
if [[ ! -f "$config_file" ]]; then
log_warn "ThirdWeb config not found, will create default..."
create_thirdweb_config "$config_file"
fi
# First, copy files to Proxmox host, then push to container
log_info " Copying files to Proxmox host..."
local remote_install="/tmp/besu-rpc-install-$$.sh"
local remote_config="/tmp/config-rpc-thirdweb-$$.toml"
# Define paths for genesis and permissions (before heredoc)
local genesis_dir="$PROJECT_ROOT/smom-dbis-138/genesis"
local permissions_dir="$PROJECT_ROOT/smom-dbis-138/permissions"
scp -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$install_script" root@${PROXMOX_HOST}:${remote_install} || {
log_error "Failed to copy installation script to Proxmox host"
return 1
}
scp -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$config_file" root@${PROXMOX_HOST}:${remote_config} || {
log_error "Failed to copy config file to Proxmox host"
return 1
}
# Execute setup inside container
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} <<SETUP_EOF
set -e
# Wait for container to be fully ready
echo "Waiting for container $vmid to be ready..."
for i in {1..30}; do
if pct exec $vmid -- test -f /etc/os-release 2>/dev/null; then
break
fi
sleep 1
done
# Copy installation script from Proxmox host to container
pct push $vmid ${remote_install} /tmp/besu-rpc-install.sh
# Copy config from Proxmox host to container
pct push $vmid ${remote_config} /tmp/config-rpc-thirdweb.toml
# Install Besu
pct exec $vmid -- bash /tmp/besu-rpc-install.sh
# Move config to proper location
pct exec $vmid -- mkdir -p /etc/besu
pct exec $vmid -- cp /tmp/config-rpc-thirdweb.toml /etc/besu/config-rpc-thirdweb.toml
# Update systemd service to use ThirdWeb config
pct exec $vmid -- sed -i 's|config-rpc.toml|config-rpc-thirdweb.toml|g' /etc/systemd/system/besu-rpc.service || true
# Reload systemd and enable service
pct exec $vmid -- systemctl daemon-reload
pct exec $vmid -- systemctl enable besu-rpc.service
echo "Besu RPC setup completed for $vmid"
SETUP_EOF
# Copy genesis and permissions files if they exist (after heredoc to avoid variable issues)
local genesis_dir="$PROJECT_ROOT/smom-dbis-138/genesis"
local permissions_dir="$PROJECT_ROOT/smom-dbis-138/permissions"
if [[ -d "$genesis_dir" ]]; then
log_info " Copying genesis files..."
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} "pct exec $vmid -- mkdir -p /genesis /permissions" || true
if [[ -f "$genesis_dir/genesis.json" ]]; then
local remote_genesis="/tmp/genesis-$$.json"
scp -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$genesis_dir/genesis.json" root@${PROXMOX_HOST}:${remote_genesis} && {
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} "pct push $vmid ${remote_genesis} /genesis/genesis.json && rm -f ${remote_genesis}" || true
}
fi
if [[ -f "$genesis_dir/static-nodes.json" ]]; then
local remote_static="/tmp/static-nodes-$$.json"
scp -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$genesis_dir/static-nodes.json" root@${PROXMOX_HOST}:${remote_static} && {
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} "pct push $vmid ${remote_static} /genesis/static-nodes.json && rm -f ${remote_static}" || true
}
fi
fi
if [[ -d "$permissions_dir" ]] && [[ -f "$permissions_dir/permissions-nodes.toml" ]]; then
log_info " Copying permissions files..."
local remote_perms="/tmp/permissions-$$.toml"
scp -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$permissions_dir/permissions-nodes.toml" root@${PROXMOX_HOST}:${remote_perms} && {
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} "pct exec $vmid -- mkdir -p /permissions && pct push $vmid ${remote_perms} /permissions/permissions-nodes.toml && rm -f ${remote_perms}" || true
}
fi
# Clean up temporary files on Proxmox host
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} "rm -f ${remote_install} ${remote_config}" || true
if [ $? -eq 0 ]; then
log_success "Besu RPC setup completed for container $vmid"
return 0
else
log_error "Failed to setup Besu RPC on container $vmid"
# Clean up on failure
ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@${PROXMOX_HOST} "rm -f ${remote_install} ${remote_config}" || true
return 1
fi
}
# Create ThirdWeb-optimized Besu config
create_thirdweb_config() {
local config_file="$1"
log_info "Creating ThirdWeb RPC configuration: $config_file"
mkdir -p "$(dirname "$config_file")"
cat > "$config_file" <<'EOF'
# Besu Configuration for ThirdWeb RPC Nodes
# Optimized for ThirdWeb SDK and dApp integration
data-path="/data/besu"
genesis-file="/genesis/genesis.json"
# Network Configuration
network-id=138
p2p-host="0.0.0.0"
p2p-port=30303
# Consensus (RPC nodes don't participate)
miner-enabled=false
# Sync Configuration
sync-mode="FULL"
fast-sync-min-peers=2
# RPC Configuration (ThirdWeb-compatible APIs)
rpc-http-enabled=true
rpc-http-host="0.0.0.0"
rpc-http-port=8545
rpc-http-api=["ETH","NET","WEB3","DEBUG","TRACE"]
rpc-http-cors-origins=["*"]
rpc-http-host-allowlist=["*"]
# WebSocket RPC (recommended for ThirdWeb)
rpc-ws-enabled=true
rpc-ws-host="0.0.0.0"
rpc-ws-port=8546
rpc-ws-api=["ETH","NET","WEB3"]
rpc-ws-origins=["*"]
# Metrics
metrics-enabled=true
metrics-port=9545
metrics-host="0.0.0.0"
metrics-push-enabled=false
# Logging
logging="INFO"
# Permissioning
permissions-nodes-config-file-enabled=true
permissions-nodes-config-file="/permissions/permissions-nodes.toml"
permissions-accounts-config-file-enabled=false
# Transaction Pool (optimized for ThirdWeb transaction volume)
tx-pool-max-size=16384
tx-pool-price-bump=10
tx-pool-retention-hours=12
# Network Peering
bootnodes=[]
# Static Nodes (validators and other nodes)
static-nodes-file="/genesis/static-nodes.json"
# Discovery (enabled for redundancy)
discovery-enabled=true
# Privacy (disabled for public network)
privacy-enabled=false
# Gas Configuration (no fee cap for ThirdWeb compatibility)
rpc-tx-feecap="0x0"
# P2P Configuration (more peers for better connectivity)
max-peers=50
# GraphQL (optional, for advanced queries)
graphql-http-enabled=false
# JSON-RPC timeout (increased for ThirdWeb operations)
rpc-http-timeout=60
EOF
log_success "ThirdWeb RPC configuration created"
}
# Main execution
main() {
echo ""
log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log_info "ThirdWeb RPC Node Setup Script"
log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
log_info "Target: $PROXMOX_HOST"
log_info "Storage: $STORAGE"
log_info "Template: $TEMPLATE"
echo ""
# Check SSH access
if ! check_ssh_access; then
exit 1
fi
echo ""
log_info "This will create ${#THIRDWEB_RPC_NODES[@]} ThirdWeb RPC nodes:"
for vmid in "${!THIRDWEB_RPC_NODES[@]}"; do
IFS=':' read -r hostname ip description <<< "${THIRDWEB_RPC_NODES[$vmid]}"
log_info " • VMID $vmid: $hostname ($ip) - $description"
done
echo ""
# Check for non-interactive mode
if [[ "${NON_INTERACTIVE:-}" == "1" ]] || [[ ! -t 0 ]]; then
log_info "Non-interactive mode: proceeding automatically"
else
read -p "Continue? (y/N): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
log_info "Setup cancelled"
exit 0
fi
fi
local success_count=0
local fail_count=0
local skip_count=0
echo ""
log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log_info "Creating ThirdWeb RPC Containers"
log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Create containers
for vmid in "${!THIRDWEB_RPC_NODES[@]}"; do
IFS=':' read -r hostname ip description <<< "${THIRDWEB_RPC_NODES[$vmid]}"
local exists=$(container_exists "$vmid")
if [[ "$exists" == "exists" ]]; then
log_warn "Container $vmid already exists, skipping creation..."
skip_count=$((skip_count + 1))
elif create_container "$vmid" "$hostname" "$ip" "$description"; then
success_count=$((success_count + 1))
else
fail_count=$((fail_count + 1))
fi
echo ""
done
echo ""
log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log_info "Configuring Besu RPC on Containers"
log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
# Setup Besu on each container
for vmid in "${!THIRDWEB_RPC_NODES[@]}"; do
IFS=':' read -r hostname ip description <<< "${THIRDWEB_RPC_NODES[$vmid]}"
log_info "Setting up container $vmid..."
if setup_besu_rpc "$vmid" "$hostname" "$ip"; then
log_success "Container $vmid configured successfully"
else
log_error "Failed to configure container $vmid"
fail_count=$((fail_count + 1))
fi
echo ""
done
# Summary
echo ""
log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
log_info "Setup Summary"
log_info "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
log_info "Created: $success_count"
log_info "Skipped: $skip_count"
log_info "Failed: $fail_count"
echo ""
if [[ $fail_count -eq 0 ]]; then
log_success "ThirdWeb RPC nodes setup completed!"
echo ""
log_info "Next steps:"
log_info "1. Verify containers are running:"
for vmid in "${!THIRDWEB_RPC_NODES[@]}"; do
IFS=':' read -r hostname ip description <<< "${THIRDWEB_RPC_NODES[$vmid]}"
log_info " ssh root@$PROXMOX_HOST 'pct status $vmid'"
done
echo ""
log_info "2. Start Besu services (if not auto-started):"
for vmid in "${!THIRDWEB_RPC_NODES[@]}"; do
IFS=':' read -r hostname ip description <<< "${THIRDWEB_RPC_NODES[$vmid]}"
log_info " ssh root@$PROXMOX_HOST 'pct exec $vmid -- systemctl start besu-rpc.service'"
done
echo ""
log_info "3. Test RPC endpoints:"
for vmid in "${!THIRDWEB_RPC_NODES[@]}"; do
IFS=':' read -r hostname ip description <<< "${THIRDWEB_RPC_NODES[$vmid]}"
log_info " curl -X POST http://${ip}:8545 -H 'Content-Type: application/json' --data '{\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\",\"params\":[],\"id\":1}'"
done
echo ""
log_info "4. Configure ThirdWeb to use these RPC endpoints:"
for vmid in "${!THIRDWEB_RPC_NODES[@]}"; do
IFS=':' read -r hostname ip description <<< "${THIRDWEB_RPC_NODES[$vmid]}"
log_info " HTTP: http://${ip}:8545"
log_info " WebSocket: ws://${ip}:8546"
done
else
log_warn "Some containers failed to setup. Check logs above."
fi
}
# Run main function
main "$@"