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>
411 lines
12 KiB
Bash
Executable File
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
|