Files
proxmox/scripts/archive/consolidated/verify/validate-besu-config.sh
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

411 lines
12 KiB
Bash
Executable File

#!/usr/bin/env bash
# Validate Besu Configuration Files
# Validates TOML syntax, checks for deprecated options, verifies required options
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# Output format (default: human-readable)
OUTPUT_FORMAT="${1:-human}"
REPORT_FILE="${2:-}"
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"; }
# Track validation results
TOTAL_FILES=0
PASSED_FILES=0
FAILED_FILES=0
ERRORS=()
WARNINGS=()
# Deprecated options list
readonly DEPRECATED_OPTIONS=(
"log-destination"
"fast-sync-min-peers"
"database-path"
"trie-logs-enabled"
"accounts-enabled"
"max-remote-initiated-connections"
"rpc-http-host-allowlist"
"tx-pool-max-size"
"tx-pool-price-bump"
"tx-pool-retention-hours"
)
# Required options by node type
declare -A REQUIRED_VALIDATOR=(
["data-path"]=1
["genesis-file"]=1
["network-id"]=1
["logging"]=1
["sync-mode"]=1
)
declare -A REQUIRED_RPC=(
["data-path"]=1
["genesis-file"]=1
["network-id"]=1
["logging"]=1
["sync-mode"]=1
["rpc-http-enabled"]=1
)
declare -A REQUIRED_SENTRY=(
["data-path"]=1
["genesis-file"]=1
["network-id"]=1
["logging"]=1
["sync-mode"]=1
)
# Valid log levels
readonly VALID_LOG_LEVELS=("OFF" "FATAL" "WARN" "INFO" "DEBUG" "TRACE" "ALL")
# Valid sync modes
readonly VALID_SYNC_MODES=("FULL" "FAST" "SNAP")
# Function to detect node type from filename
detect_node_type() {
local file="$1"
local basename=$(basename "$file")
if [[ "$basename" == *"validator"* ]]; then
echo "validator"
elif [[ "$basename" == *"sentry"* ]]; then
echo "sentry"
elif [[ "$basename" == *"member"* ]]; then
echo "member"
elif [[ "$basename" == *"rpc"* ]]; then
echo "rpc"
else
echo "unknown"
fi
}
# Function to check if TOML syntax is valid (basic check)
validate_toml_syntax() {
local file="$1"
local errors=0
# Check for basic TOML structure
if ! grep -q '^\[' "$file" 2>/dev/null; then
if ! grep -q '^[a-zA-Z]' "$file" 2>/dev/null; then
echo "No TOML sections or keys found"
return 1
fi
fi
# Check for unmatched quotes (basic check)
local single_quotes=$(grep -o "'" "$file" | wc -l)
local double_quotes=$(grep -o '"' "$file" | wc -l)
if [ $((single_quotes % 2)) -ne 0 ] && [ $((double_quotes % 2)) -ne 0 ]; then
# Could indicate syntax issues, but not always
:
fi
return 0
}
# Function to check for deprecated options
check_deprecated_options() {
local file="$1"
local deprecated_found=()
for option in "${DEPRECATED_OPTIONS[@]}"; do
if grep -qE "^${option}\s*=" "$file" 2>/dev/null; then
deprecated_found+=("$option")
fi
done
if [ ${#deprecated_found[@]} -gt 0 ]; then
echo "${deprecated_found[@]}"
return 1
fi
return 0
}
# Function to check required options
check_required_options() {
local file="$1"
local node_type="$2"
local missing=()
local -n required_ref="REQUIRED_${node_type^^}"
for option in "${!required_ref[@]}"; do
if ! grep -qE "^${option}\s*=" "$file" 2>/dev/null; then
missing+=("$option")
fi
done
if [ ${#missing[@]} -gt 0 ]; then
echo "${missing[@]}"
return 1
fi
return 0
}
# Function to validate option values
validate_option_values() {
local file="$1"
local issues=()
# Check logging level
if grep -qE '^logging\s*=' "$file" 2>/dev/null; then
local log_level=$(grep -E '^logging\s*=' "$file" | head -1 | sed -E 's/.*logging\s*=\s*"([^"]+)".*/\1/' || echo "")
if [[ ! " ${VALID_LOG_LEVELS[@]} " =~ " ${log_level} " ]]; then
issues+=("Invalid logging level: $log_level (should be one of: ${VALID_LOG_LEVELS[*]})")
fi
fi
# Check sync mode
if grep -qE '^sync-mode\s*=' "$file" 2>/dev/null; then
local sync_mode=$(grep -E '^sync-mode\s*=' "$file" | head -1 | sed -E 's/.*sync-mode\s*=\s*"([^"]+)".*/\1/' || echo "")
if [[ ! " ${VALID_SYNC_MODES[@]} " =~ " ${sync_mode} " ]]; then
issues+=("Invalid sync-mode: $sync_mode (should be one of: ${VALID_SYNC_MODES[*]})")
fi
fi
# Check for invalid rpc-tx-feecap="0x0"
if grep -qE 'rpc-tx-feecap\s*=\s*"0x0"' "$file" 2>/dev/null; then
issues+=("Invalid rpc-tx-feecap value: '0x0' cannot be converted to Wei")
fi
if [ ${#issues[@]} -gt 0 ]; then
printf '%s\n' "${issues[@]}"
return 1
fi
return 0
}
# Function to validate paths (check if they're reasonable, not if they exist)
validate_paths() {
local file="$1"
local issues=()
# Check data-path
if grep -qE '^data-path\s*=' "$file" 2>/dev/null; then
local data_path=$(grep -E '^data-path\s*=' "$file" | head -1 | sed -E 's/.*data-path\s*=\s*"([^"]+)".*/\1/' || echo "")
if [ -z "$data_path" ]; then
issues+=("data-path is empty or invalid")
fi
fi
# Check genesis-file
if grep -qE '^genesis-file\s*=' "$file" 2>/dev/null; then
local genesis_file=$(grep -E '^genesis-file\s*=' "$file" | head -1 | sed -E 's/.*genesis-file\s*=\s*"([^"]+)".*/\1/' || echo "")
if [ -z "$genesis_file" ]; then
issues+=("genesis-file is empty or invalid")
fi
fi
if [ ${#issues[@]} -gt 0 ]; then
printf '%s\n' "${issues[@]}"
return 1
fi
return 0
}
# Function to validate a single config file
validate_config_file() {
local file="$1"
local node_type=$(detect_node_type "$file")
local file_errors=()
local file_warnings=()
local failed=false
TOTAL_FILES=$((TOTAL_FILES + 1))
if [ "$OUTPUT_FORMAT" == "human" ]; then
echo ""
log_info "Validating: $file (type: $node_type)"
fi
# Check file exists and is readable
if [ ! -f "$file" ]; then
file_errors+=("File not found: $file")
failed=true
elif [ ! -r "$file" ]; then
file_errors+=("File not readable: $file")
failed=true
else
# Validate TOML syntax
if ! validate_toml_syntax "$file"; then
file_warnings+=("TOML syntax may have issues (basic check)")
fi
# Check for deprecated options
local deprecated=$(check_deprecated_options "$file")
if [ $? -ne 0 ]; then
file_errors+=("Deprecated options found: $deprecated")
failed=true
fi
# Check required options (skip if node type unknown)
if [ "$node_type" != "unknown" ]; then
local missing=$(check_required_options "$file" "$node_type")
if [ $? -ne 0 ]; then
file_errors+=("Missing required options: $missing")
failed=true
fi
fi
# Validate option values
local value_issues=$(validate_option_values "$file")
if [ $? -ne 0 ]; then
while IFS= read -r issue; do
file_errors+=("$issue")
done <<< "$value_issues"
failed=true
fi
# Validate paths
local path_issues=$(validate_paths "$file")
if [ $? -ne 0 ]; then
while IFS= read -r issue; do
file_warnings+=("$issue")
done <<< "$path_issues"
fi
fi
# Report results
if [ "$failed" = true ]; then
FAILED_FILES=$((FAILED_FILES + 1))
ERRORS+=("$file: ${file_errors[*]}")
if [ "$OUTPUT_FORMAT" == "human" ]; then
log_error " Validation FAILED"
for error in "${file_errors[@]}"; do
log_error " - $error"
done
fi
else
PASSED_FILES=$((PASSED_FILES + 1))
if [ "$OUTPUT_FORMAT" == "human" ]; then
log_success " Validation PASSED"
fi
fi
if [ ${#file_warnings[@]} -gt 0 ] && [ "$OUTPUT_FORMAT" == "human" ]; then
for warning in "${file_warnings[@]}"; do
log_warn " - $warning"
done
fi
WARNINGS+=("$file: ${file_warnings[*]}")
# Return exit code
if [ "$failed" = true ]; then
return 1
fi
return 0
}
# Main execution
if [ "$OUTPUT_FORMAT" == "human" ]; then
echo -e "${BLUE}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║ BESU CONFIGURATION VALIDATION ║${NC}"
echo -e "${BLUE}╚══════════════════════════════════════════════════════════════╝${NC}"
echo ""
fi
# Find all Besu config files
CONFIG_FILES=(
"$PROJECT_ROOT/smom-dbis-138/config/config-validator.toml"
"$PROJECT_ROOT/smom-dbis-138/config/config-rpc-core.toml"
"$PROJECT_ROOT/smom-dbis-138/config/config-rpc-public.toml"
"$PROJECT_ROOT/smom-dbis-138/config/config-rpc-perm.toml"
"$PROJECT_ROOT/smom-dbis-138/config/config-rpc-thirdweb.toml"
"$PROJECT_ROOT/smom-dbis-138/config/config-rpc-4.toml"
"$PROJECT_ROOT/smom-dbis-138/config/config-rpc-putu-1.toml"
"$PROJECT_ROOT/smom-dbis-138/config/config-rpc-putu-8a.toml"
"$PROJECT_ROOT/smom-dbis-138/config/config-rpc-luis-1.toml"
"$PROJECT_ROOT/smom-dbis-138/config/config-rpc-luis-8a.toml"
"$PROJECT_ROOT/smom-dbis-138/config/config-member.toml"
"$PROJECT_ROOT/smom-dbis-138-proxmox/templates/besu-configs/config-validator.toml"
"$PROJECT_ROOT/smom-dbis-138-proxmox/templates/besu-configs/config-rpc-core.toml"
"$PROJECT_ROOT/smom-dbis-138-proxmox/templates/besu-configs/config-rpc.toml"
"$PROJECT_ROOT/smom-dbis-138-proxmox/templates/besu-configs/config-rpc-4.toml"
"$PROJECT_ROOT/smom-dbis-138-proxmox/templates/besu-configs/config-sentry.toml"
)
# Validate each file
for file in "${CONFIG_FILES[@]}"; do
validate_config_file "$file"
done
# Summary
if [ "$OUTPUT_FORMAT" == "human" ]; then
echo ""
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}Validation Summary${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════════════════${NC}"
echo ""
echo "Total files validated: $TOTAL_FILES"
echo "Passed: $PASSED_FILES"
echo "Failed: $FAILED_FILES"
echo ""
if [ $FAILED_FILES -eq 0 ]; then
log_success "All configuration files passed validation!"
exit 0
else
log_error "Some configuration files failed validation"
exit 1
fi
else
# JSON output for automation (enhanced)
{
echo "{"
echo " \"total\": $TOTAL_FILES,"
echo " \"passed\": $PASSED_FILES,"
echo " \"failed\": $FAILED_FILES,"
echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\","
echo " \"errors\": ["
for i in "${!ERRORS[@]}"; do
echo -n " \"${ERRORS[$i]//\"/\\\"}\""
if [ $i -lt $((${#ERRORS[@]} - 1)) ]; then
echo ","
else
echo ""
fi
done
echo " ],"
echo " \"warnings\": ["
local warn_count=0
for i in "${!WARNINGS[@]}"; do
if [ -n "${WARNINGS[$i]}" ]; then
if [ $warn_count -gt 0 ]; then
echo ","
fi
echo -n " \"${WARNINGS[$i]//\"/\\\"}\""
warn_count=$((warn_count + 1))
fi
done
echo ""
echo " ],"
echo " \"success\": $([ $FAILED_FILES -eq 0 ] && echo "true" || echo "false")"
echo "}"
} > "$REPORT_FILE" 2>/dev/null || echo "Failed to write report"
exit $([ $FAILED_FILES -eq 0 ] && echo 0 || echo 1)
fi