Skip to content

Instantly share code, notes, and snippets.

@bussyjd
Created December 30, 2025 07:01
Show Gist options
  • Select an option

  • Save bussyjd/a7885d1e42f33be4957b14c1c2df829a to your computer and use it in GitHub Desktop.

Select an option

Save bussyjd/a7885d1e42f33be4957b14c1c2df829a to your computer and use it in GitHub Desktop.
Validates Execution Layer and Consensus Layer endpoints for Aztec validation duties
#!/usr/bin/env bash
#
# Aztec EL/CL Fitness Validator
# Validates Execution Layer and Consensus Layer endpoints for Aztec validation duties
#
set -uo pipefail
# Note: -e is intentionally omitted to allow graceful error handling
# Default values
CHAIN_ID=1
GENESIS_TIME=1606824023 # Mainnet beacon chain genesis
SLOT_DURATION=12
# Counters
EL_PASS=0
EL_FAIL=0
EL_WARN=0
CL_PASS=0
CL_FAIL=0
CL_WARN=0
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
usage() {
cat <<EOF
Usage: $(basename "$0") --el <EL_URL> --cl <CL_URL> [OPTIONS]
Validates EL/CL endpoints for Aztec validation duties.
Required:
--el <URL> Execution Layer JSON-RPC URL
--cl <URL> Consensus Layer Beacon API URL
Options:
--chain-id <ID> Expected chain ID (default: 1 for mainnet)
--genesis <TIME> Beacon chain genesis timestamp (default: 1606824023 for mainnet)
-h, --help Show this help message
Examples:
$(basename "$0") --el http://geth:8545 --cl http://lighthouse:5052
$(basename "$0") --el http://geth:8545 --cl http://lighthouse:5052 --chain-id 17000
EOF
exit 2
}
# Parse arguments
EL_URL=""
CL_URL=""
while [[ $# -gt 0 ]]; do
case $1 in
--el)
EL_URL="$2"
shift 2
;;
--cl)
CL_URL="$2"
shift 2
;;
--chain-id)
CHAIN_ID="$2"
shift 2
;;
--genesis)
GENESIS_TIME="$2"
shift 2
;;
-h|--help)
usage
;;
*)
echo "Unknown option: $1"
usage
;;
esac
done
if [[ -z "$EL_URL" || -z "$CL_URL" ]]; then
echo "Error: --el and --cl are required"
usage
fi
# Helper functions
check_pass() {
echo -e "${GREEN}[PASS]${NC} $1"
}
check_fail() {
echo -e "${RED}[FAIL]${NC} $1"
}
check_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# Make JSON-RPC call to EL
rpc_call() {
local method="$1"
local params="${2:-[]}"
curl -s -X POST "$EL_URL" \
-H "Content-Type: application/json" \
-d "{\"jsonrpc\":\"2.0\",\"method\":\"$method\",\"params\":$params,\"id\":1}" \
--connect-timeout 10 \
--max-time 30
}
# Make GET request to CL beacon API
beacon_get() {
local path="$1"
curl -s "${CL_URL}${path}" \
--connect-timeout 10 \
--max-time 30
}
# Print header
echo ""
echo "========================================"
echo " Aztec EL/CL Fitness Validator"
echo "========================================"
echo ""
echo "EL Endpoint: $EL_URL"
echo "CL Endpoint: $CL_URL"
echo "Chain ID: $CHAIN_ID"
echo ""
# =============================================================================
# EXECUTION LAYER CHECKS
# =============================================================================
echo "--- Execution Layer Checks ---"
# 1. Chain ID
result=$(rpc_call "eth_chainId" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
check_fail "Chain ID - connection failed"
((EL_FAIL++))
else
chain_id_hex=$(echo "$result" | jq -r '.result // empty')
if [[ -n "$chain_id_hex" ]]; then
chain_id_dec=$((chain_id_hex))
if [[ "$chain_id_dec" -eq "$CHAIN_ID" ]]; then
check_pass "Chain ID matches ($chain_id_dec)"
((EL_PASS++))
else
check_fail "Chain ID mismatch (got $chain_id_dec, expected $CHAIN_ID)"
((EL_FAIL++))
fi
else
check_fail "Chain ID - invalid response"
((EL_FAIL++))
fi
fi
# 2. Sync Status
result=$(rpc_call "eth_syncing" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
check_fail "Sync status - request failed"
((EL_FAIL++))
else
syncing=$(echo "$result" | jq -r '.result')
if [[ "$syncing" == "false" ]]; then
check_pass "Node is fully synced"
((EL_PASS++))
else
current=$(echo "$syncing" | jq -r '.currentBlock // "unknown"')
highest=$(echo "$syncing" | jq -r '.highestBlock // "unknown"')
check_fail "Node is syncing (current: $current, highest: $highest)"
((EL_FAIL++))
fi
fi
# 3. Block Freshness
result=$(rpc_call "eth_getBlockByNumber" '["latest", false]' 2>/dev/null || echo '{"error":"connection failed"}')
LATEST_BLOCK_HASH=""
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
check_fail "Block freshness - request failed"
((EL_FAIL++))
else
block_timestamp_hex=$(echo "$result" | jq -r '.result.timestamp // empty')
LATEST_BLOCK_HASH=$(echo "$result" | jq -r '.result.hash // empty')
if [[ -n "$block_timestamp_hex" ]]; then
block_timestamp=$((block_timestamp_hex))
current_time=$(date +%s)
drift=$((current_time - block_timestamp))
if [[ "$drift" -le 60 ]]; then
check_pass "Block freshness (${drift}s behind)"
((EL_PASS++))
else
check_fail "Block freshness - ${drift}s behind (max 60s)"
((EL_FAIL++))
fi
else
check_fail "Block freshness - invalid response"
((EL_FAIL++))
fi
fi
# 4. eth_getLogs support
block_number_result=$(rpc_call "eth_blockNumber" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$block_number_result" | jq -e '.error' > /dev/null 2>&1; then
check_fail "eth_getLogs - cannot get block number"
((EL_FAIL++))
else
block_number_hex=$(echo "$block_number_result" | jq -r '.result // empty')
if [[ -n "$block_number_hex" ]]; then
block_number=$((block_number_hex))
from_block=$((block_number - 10))
from_block_hex=$(printf "0x%x" $from_block)
result=$(rpc_call "eth_getLogs" "[{\"fromBlock\":\"$from_block_hex\",\"toBlock\":\"latest\",\"address\":null}]" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
error_msg=$(echo "$result" | jq -r '.error.message // "unknown error"')
check_fail "eth_getLogs - $error_msg"
((EL_FAIL++))
else
log_count=$(echo "$result" | jq -r '.result | length')
check_pass "eth_getLogs supported ($log_count logs in last 10 blocks)"
((EL_PASS++))
fi
else
check_fail "eth_getLogs - invalid block number"
((EL_FAIL++))
fi
fi
# 5. Filter API support (eth_newBlockFilter + eth_getFilterChanges)
# This is CRITICAL for Aztec - tests the full filter lifecycle
result=$(rpc_call "eth_newBlockFilter" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
error_msg=$(echo "$result" | jq -r '.error.message // "not supported"')
check_fail "Filter API - eth_newBlockFilter failed: $error_msg"
((EL_FAIL++))
else
filter_id=$(echo "$result" | jq -r '.result // empty')
if [[ -n "$filter_id" && "$filter_id" != "null" ]]; then
# Now test eth_getFilterChanges with the filter
sleep 1 # Wait for potential new blocks
changes_result=$(rpc_call "eth_getFilterChanges" "[\"$filter_id\"]" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$changes_result" | jq -e '.error' > /dev/null 2>&1; then
error_msg=$(echo "$changes_result" | jq -r '.error.message // "failed"')
check_fail "Filter API - eth_getFilterChanges failed: $error_msg"
((EL_FAIL++))
else
changes_count=$(echo "$changes_result" | jq -r '.result | length // 0')
check_pass "Filter API supported (filter: $filter_id, changes: $changes_count)"
((EL_PASS++))
fi
# Cleanup: uninstall the filter
rpc_call "eth_uninstallFilter" "[\"$filter_id\"]" > /dev/null 2>&1 || true
else
check_fail "Filter API - eth_newBlockFilter returned invalid filter ID"
((EL_FAIL++))
fi
fi
# 5b. Filter API - stale/foreign filter handling
# Test that the node gracefully handles unknown filter IDs (critical for multi-node setups)
FAKE_FILTER_ID="0xdeadbeefdeadbeefdeadbeefdeadbeef"
stale_result=$(rpc_call "eth_getFilterChanges" "[\"$FAKE_FILTER_ID\"]" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$stale_result" | jq -e '.error' > /dev/null 2>&1; then
error_msg=$(echo "$stale_result" | jq -r '.error.message // "unknown"')
# "filter not found" is the expected graceful error
if [[ "$error_msg" == *"filter not found"* || "$error_msg" == *"does not exist"* ]]; then
check_pass "Stale filter handling (graceful error for unknown filter)"
((EL_PASS++))
else
# Any other error (like overflow, crash) is a problem
check_fail "Stale filter handling - unexpected error: $error_msg"
((EL_FAIL++))
fi
else
# If it returns success for a fake filter, that's also wrong
check_fail "Stale filter handling - accepted invalid filter ID (should error)"
((EL_FAIL++))
fi
# 6. eth_call support
result=$(rpc_call "eth_call" '[{"to":"0x0000000000000000000000000000000000000000","data":"0x"},"latest"]' 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
# Some nodes may return error for empty call, try with a different approach
check_warn "eth_call - empty call returned error (may be normal)"
((EL_WARN++))
else
check_pass "eth_call supported"
((EL_PASS++))
fi
# 7. eth_estimateGas support
result=$(rpc_call "eth_estimateGas" '[{"from":"0x0000000000000000000000000000000000000001","to":"0x0000000000000000000000000000000000000002","value":"0x0"}]' 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
check_warn "eth_estimateGas - returned error (may be account-specific)"
((EL_WARN++))
else
gas=$(echo "$result" | jq -r '.result // empty')
if [[ -n "$gas" ]]; then
check_pass "eth_estimateGas supported (estimate: $gas)"
((EL_PASS++))
else
check_warn "eth_estimateGas - empty response"
((EL_WARN++))
fi
fi
# 8. eth_feeHistory support
result=$(rpc_call "eth_feeHistory" '["0x4", "latest", [25, 75]]' 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
check_fail "eth_feeHistory - not supported"
((EL_FAIL++))
else
base_fees=$(echo "$result" | jq -r '.result.baseFeePerGas | length // 0')
if [[ "$base_fees" -gt 0 ]]; then
latest_fee=$(echo "$result" | jq -r '.result.baseFeePerGas[-1]')
check_pass "eth_feeHistory supported (latest baseFee: $latest_fee)"
((EL_PASS++))
else
check_fail "eth_feeHistory - invalid response"
((EL_FAIL++))
fi
fi
# 9. eth_blobBaseFee support (post-Dencun)
result=$(rpc_call "eth_blobBaseFee" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
check_warn "eth_blobBaseFee - not supported (pre-Dencun or unsupported)"
((EL_WARN++))
else
blob_fee=$(echo "$result" | jq -r '.result // empty')
if [[ -n "$blob_fee" ]]; then
check_pass "eth_blobBaseFee supported ($blob_fee)"
((EL_PASS++))
else
check_warn "eth_blobBaseFee - empty response"
((EL_WARN++))
fi
fi
# 10. eth_getBlockByHash with parentBeaconBlockRoot (EIP-4788)
PARENT_BEACON_ROOT=""
if [[ -n "$LATEST_BLOCK_HASH" ]]; then
result=$(rpc_call "eth_getBlockByHash" "[\"$LATEST_BLOCK_HASH\", false]" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
check_fail "eth_getBlockByHash - request failed"
((EL_FAIL++))
else
PARENT_BEACON_ROOT=$(echo "$result" | jq -r '.result.parentBeaconBlockRoot // empty')
if [[ -n "$PARENT_BEACON_ROOT" && "$PARENT_BEACON_ROOT" != "null" ]]; then
check_pass "eth_getBlockByHash with parentBeaconBlockRoot"
((EL_PASS++))
else
check_warn "eth_getBlockByHash - no parentBeaconBlockRoot (pre-Dencun block?)"
((EL_WARN++))
fi
fi
else
check_warn "eth_getBlockByHash - skipped (no block hash available)"
((EL_WARN++))
fi
# 11. debug_traceTransaction (optional)
# Use a known transaction hash for testing - this is a simple ETH transfer on mainnet
TEST_TX_HASH="0x5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060"
result=$(rpc_call "debug_traceTransaction" "[\"$TEST_TX_HASH\", {\"tracer\": \"callTracer\"}]" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.error' > /dev/null 2>&1; then
error_msg=$(echo "$result" | jq -r '.error.message // "not available"')
check_warn "debug_traceTransaction - $error_msg"
((EL_WARN++))
else
trace_type=$(echo "$result" | jq -r '.result.type // empty')
if [[ -n "$trace_type" ]]; then
check_pass "debug_traceTransaction supported"
((EL_PASS++))
else
check_warn "debug_traceTransaction - unexpected response format"
((EL_WARN++))
fi
fi
echo ""
# =============================================================================
# CONSENSUS LAYER CHECKS
# =============================================================================
echo "--- Consensus Layer Checks ---"
# 1. Beacon API connectivity
result=$(beacon_get "/eth/v1/beacon/headers" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.data' > /dev/null 2>&1; then
check_pass "Beacon API reachable"
((CL_PASS++))
else
check_fail "Beacon API - connection failed or invalid response"
((CL_FAIL++))
fi
# 2. Head slot
result=$(beacon_get "/eth/v1/beacon/headers/head" 2>/dev/null || echo '{"error":"connection failed"}')
HEAD_SLOT=0
HEAD_ROOT=""
if echo "$result" | jq -e '.data' > /dev/null 2>&1; then
HEAD_SLOT=$(echo "$result" | jq -r '.data.header.message.slot // 0')
HEAD_ROOT=$(echo "$result" | jq -r '.data.root // empty')
check_pass "Head slot: $HEAD_SLOT"
((CL_PASS++))
else
check_fail "Head slot - request failed"
((CL_FAIL++))
fi
# 3. Slot freshness
if [[ "$HEAD_SLOT" -gt 0 ]]; then
current_time=$(date +%s)
expected_slot=$(( (current_time - GENESIS_TIME) / SLOT_DURATION ))
slot_diff=$((expected_slot - HEAD_SLOT))
if [[ "$slot_diff" -le 2 ]]; then
check_pass "Slot freshness (${slot_diff} slots behind)"
((CL_PASS++))
else
check_fail "Slot freshness - ${slot_diff} slots behind (max 2)"
((CL_FAIL++))
fi
else
check_fail "Slot freshness - cannot calculate (no head slot)"
((CL_FAIL++))
fi
# 4. Recent blob_sidecars
if [[ "$HEAD_SLOT" -gt 0 ]]; then
# Try a few recent slots (some may be missed blocks)
blob_found=false
for offset in 1 2 3 4 5; do
test_slot=$((HEAD_SLOT - offset))
result=$(beacon_get "/eth/v1/beacon/blob_sidecars/$test_slot" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.data' > /dev/null 2>&1; then
blob_count=$(echo "$result" | jq -r '.data | length')
check_pass "Recent blob_sidecars available (slot $test_slot: $blob_count blobs)"
((CL_PASS++))
blob_found=true
break
fi
done
if [[ "$blob_found" == "false" ]]; then
check_fail "Recent blob_sidecars - not available in last 5 slots"
((CL_FAIL++))
fi
else
check_fail "Recent blob_sidecars - skipped (no head slot)"
((CL_FAIL++))
fi
# 5. Historical blob_sidecars (tests blob retention)
if [[ "$HEAD_SLOT" -gt 1000 ]]; then
historical_slot=$((HEAD_SLOT - 1000))
result=$(beacon_get "/eth/v1/beacon/blob_sidecars/$historical_slot" 2>/dev/null || echo '{"error":"connection failed"}')
http_code=$(curl -s -o /dev/null -w "%{http_code}" "${CL_URL}/eth/v1/beacon/blob_sidecars/$historical_slot" 2>/dev/null || echo "000")
if [[ "$http_code" == "200" ]]; then
blob_count=$(echo "$result" | jq -r '.data | length // 0')
check_pass "Historical blob_sidecars available (slot $historical_slot: $blob_count blobs)"
((CL_PASS++))
elif [[ "$http_code" == "404" ]]; then
check_warn "Historical blob_sidecars - slot $historical_slot not found (may be missed block)"
((CL_WARN++))
elif [[ "$http_code" == "500" ]]; then
error_msg=$(echo "$result" | jq -r '.message // "server error"' 2>/dev/null)
check_fail "Historical blob_sidecars - server error: $error_msg"
((CL_FAIL++))
else
check_fail "Historical blob_sidecars - HTTP $http_code"
((CL_FAIL++))
fi
else
check_warn "Historical blob_sidecars - skipped (head slot too low)"
((CL_WARN++))
fi
# 6. Headers by block root
if [[ -n "$HEAD_ROOT" ]]; then
result=$(beacon_get "/eth/v1/beacon/headers/$HEAD_ROOT" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$result" | jq -e '.data' > /dev/null 2>&1; then
check_pass "Headers by block root"
((CL_PASS++))
else
check_fail "Headers by block root - request failed"
((CL_FAIL++))
fi
else
check_warn "Headers by block root - skipped (no head root)"
((CL_WARN++))
fi
echo ""
# =============================================================================
# EL/CL PAIRING VALIDATION (Critical for Aztec)
# =============================================================================
echo "--- EL/CL Pairing Checks ---"
PAIR_PASS=0
PAIR_FAIL=0
PAIR_WARN=0
# 1. Validate parentBeaconBlockRoot exists in CL (EIP-4788 correlation)
# This is CRITICAL - Aztec uses parentBeaconBlockRoot to find the CL slot for blob fetching
if [[ -n "$PARENT_BEACON_ROOT" && "$PARENT_BEACON_ROOT" != "null" ]]; then
# Query CL for the beacon block header using parentBeaconBlockRoot
pairing_result=$(beacon_get "/eth/v1/beacon/headers/$PARENT_BEACON_ROOT" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$pairing_result" | jq -e '.data' > /dev/null 2>&1; then
cl_slot=$(echo "$pairing_result" | jq -r '.data.header.message.slot // empty')
if [[ -n "$cl_slot" ]]; then
# The actual block slot is parentBeaconBlockRoot's slot + 1
actual_slot=$((cl_slot + 1))
check_pass "EL/CL pairing: parentBeaconBlockRoot found in CL (slot $actual_slot)"
((PAIR_PASS++))
# 2. Verify blob_sidecars are available for that slot
blob_result=$(beacon_get "/eth/v1/beacon/blob_sidecars/$actual_slot" 2>/dev/null || echo '{"error":"connection failed"}')
if echo "$blob_result" | jq -e '.data' > /dev/null 2>&1; then
blob_count=$(echo "$blob_result" | jq -r '.data | length')
check_pass "EL/CL pairing: blob_sidecars available for correlated slot (count: $blob_count)"
((PAIR_PASS++))
else
http_code=$(curl -s -o /dev/null -w "%{http_code}" "${CL_URL}/eth/v1/beacon/blob_sidecars/$actual_slot" 2>/dev/null || echo "000")
if [[ "$http_code" == "404" ]]; then
check_warn "EL/CL pairing: No blobs at slot $actual_slot (may be empty block)"
((PAIR_WARN++))
else
check_fail "EL/CL pairing: Cannot fetch blob_sidecars for slot $actual_slot (HTTP $http_code)"
((PAIR_FAIL++))
fi
fi
else
check_fail "EL/CL pairing: CL returned invalid slot for parentBeaconBlockRoot"
((PAIR_FAIL++))
fi
else
# This is the critical failure - CL doesn't have the beacon block that EL references
error_code=$(echo "$pairing_result" | jq -r '.code // empty')
if [[ "$error_code" == "404" ]]; then
check_fail "EL/CL pairing: parentBeaconBlockRoot NOT FOUND in CL - NODES ARE NOT PAIRED!"
((PAIR_FAIL++))
else
check_fail "EL/CL pairing: Cannot verify parentBeaconBlockRoot in CL"
((PAIR_FAIL++))
fi
fi
else
check_warn "EL/CL pairing: Skipped (no parentBeaconBlockRoot from EL)"
((PAIR_WARN++))
fi
# 3. Validate EL timestamp aligns with CL slot timing
if [[ -n "$LATEST_BLOCK_HASH" && "$HEAD_SLOT" -gt 0 ]]; then
# Get the EL block timestamp
el_block=$(rpc_call "eth_getBlockByHash" "[\"$LATEST_BLOCK_HASH\", false]" 2>/dev/null)
el_timestamp_hex=$(echo "$el_block" | jq -r '.result.timestamp // empty')
if [[ -n "$el_timestamp_hex" ]]; then
el_timestamp=$((el_timestamp_hex))
# Calculate expected slot from EL timestamp
expected_slot=$(( (el_timestamp - GENESIS_TIME) / SLOT_DURATION ))
# Allow 2 slot drift tolerance
slot_drift=$((HEAD_SLOT - expected_slot))
slot_drift_abs=${slot_drift#-} # Absolute value
if [[ "$slot_drift_abs" -le 2 ]]; then
check_pass "EL/CL timing: EL timestamp aligns with CL slot (drift: $slot_drift slots)"
((PAIR_PASS++))
else
check_fail "EL/CL timing: EL timestamp diverges from CL slot (drift: $slot_drift slots)"
((PAIR_FAIL++))
fi
else
check_warn "EL/CL timing: Cannot get EL block timestamp"
((PAIR_WARN++))
fi
else
check_warn "EL/CL timing: Skipped (missing block hash or head slot)"
((PAIR_WARN++))
fi
echo ""
# =============================================================================
# SUMMARY
# =============================================================================
EL_TOTAL=$((EL_PASS + EL_FAIL + EL_WARN))
CL_TOTAL=$((CL_PASS + CL_FAIL + CL_WARN))
PAIR_TOTAL=$((PAIR_PASS + PAIR_FAIL + PAIR_WARN))
echo "========================================"
if [[ "$EL_FAIL" -eq 0 && "$CL_FAIL" -eq 0 && "$PAIR_FAIL" -eq 0 ]]; then
echo -e " ${GREEN}RESULT: SUITABLE FOR AZTEC VALIDATION${NC}"
else
echo -e " ${RED}RESULT: NOT SUITABLE FOR AZTEC VALIDATION${NC}"
fi
echo "========================================"
echo ""
echo "EL: $EL_PASS/$EL_TOTAL checks passed ($EL_WARN warnings, $EL_FAIL failures)"
echo "CL: $CL_PASS/$CL_TOTAL checks passed ($CL_WARN warnings, $CL_FAIL failures)"
echo "Pairing: $PAIR_PASS/$PAIR_TOTAL checks passed ($PAIR_WARN warnings, $PAIR_FAIL failures)"
echo ""
# Notes
if [[ "$EL_WARN" -gt 0 || "$CL_WARN" -gt 0 || "$PAIR_WARN" -gt 0 ]]; then
echo "Notes:"
if [[ "$EL_WARN" -gt 0 ]]; then
echo "- Some EL warnings may be acceptable (e.g., debug_traceTransaction is optional)"
fi
if [[ "$CL_WARN" -gt 0 ]]; then
echo "- Some CL warnings may indicate pruned data or missed blocks"
fi
if [[ "$PAIR_WARN" -gt 0 ]]; then
echo "- Pairing warnings may indicate empty blocks or missing blob data"
fi
echo ""
fi
# Exit code
if [[ "$EL_FAIL" -gt 0 || "$CL_FAIL" -gt 0 || "$PAIR_FAIL" -gt 0 ]]; then
exit 1
else
exit 0
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment