#!/usr/bin/env bash # Flush stuck transaction from RPC (2101) and all validators (1000-1004). # 1. Try txpool_besuClear on RPC first (no restart). # 2. If still pending or TXPOOL not available, clear pools on RPC + validators (stop, delete pool files, start). # Usage: bash scripts/flush-stuck-tx-rpc-and-validators.sh [--full] # --full: skip RPC API clear and do full stop/clear/restart on RPC + validators. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" cd "$PROJECT_ROOT" [ -f config/ip-addresses.conf ] && source config/ip-addresses.conf 2>/dev/null || true RPC_URL="${RPC_URL_138:-http://${RPC_CORE_1:-192.168.11.211}:8545}" DEPLOYER="${DEPLOYER:-0x4A666F96fC8764181194447A7dFdb7d471b301C8}" FULL_ONLY=false [[ "${1:-}" = "--full" ]] && FULL_ONLY=true 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_ok() { echo -e "${GREEN}[✓]${NC} $1"; } log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; } log_err() { echo -e "${RED}[✗]${NC} $1"; } echo "" echo "=== Flush stuck transaction (RPC + validators) ===" echo "" # Pre-check: pending count LATEST_HEX=$(curl -s -X POST -H "Content-Type: application/json" --data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"$DEPLOYER\",\"latest\"],\"id\":1}" "$RPC_URL" 2>/dev/null | jq -r '.result // empty' | tr -d '"' || echo "0x0") PENDING_HEX=$(curl -s -X POST -H "Content-Type: application/json" --data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"$DEPLOYER\",\"pending\"],\"id\":1}" "$RPC_URL" 2>/dev/null | jq -r '.result // empty' | tr -d '"' || echo "0x0") LATEST_DEC=$((LATEST_HEX)) PENDING_DEC=$((PENDING_HEX)) [[ "$LATEST_DEC" -eq 0 ]] && LATEST_DEC=$(printf '%d' "$LATEST_HEX" 2>/dev/null || echo "0") [[ "$PENDING_DEC" -eq 0 ]] && PENDING_DEC=$(printf '%d' "$PENDING_HEX" 2>/dev/null || echo "0") PENDING_COUNT=$((PENDING_DEC - LATEST_DEC)) log_info "Deployer: $DEPLOYER" log_info "Latest nonce: $LATEST_DEC | Pending nonce: $PENDING_DEC | Stuck count: $PENDING_COUNT" echo "" if [ "$PENDING_COUNT" -le 0 ] && [ "$FULL_ONLY" = false ]; then log_ok "No stuck transactions reported by RPC." exit 0 fi # Step 1: Try RPC txpool_besuClear (unless --full) RPC_CLEARED=false if [ "$FULL_ONLY" = false ]; then log_info "Step 1: Try txpool_besuClear on RPC ($RPC_URL)..." MODULES=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"rpc_modules","params":[],"id":1}' "$RPC_URL" 2>/dev/null || echo "{}") if echo "$MODULES" | jq -r '.result | keys[]' 2>/dev/null | grep -qi txpool; then RES=$(curl -s -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"txpool_besuClear","params":[],"id":1}' "$RPC_URL" 2>/dev/null || echo "{}") if echo "$RES" | jq -e '.result == true' >/dev/null 2>&1; then log_ok "RPC txpool_besuClear succeeded." RPC_CLEARED=true else log_warn "txpool_besuClear failed or not supported: $(echo "$RES" | jq -r '.error.message // .result // "unknown"')" fi else log_warn "TXPOOL not enabled on RPC; will use full flush." fi fi # Step 2: Full flush (validators + RPC) if needed if [ "$RPC_CLEARED" = false ] || [ "$FULL_ONLY" = true ]; then log_info "Step 2: Full flush — clear transaction pools on all validators and RPC (stop, clear files, start)..." bash "$SCRIPT_DIR/clear-all-transaction-pools.sh" 2>&1 || { log_err "clear-all-transaction-pools.sh failed"; exit 1; } fi # Step 3: Verify log_info "Step 3: Verify (wait 15s then check pending)..." sleep 15 PENDING_HEX2=$(curl -s -X POST -H "Content-Type: application/json" --data "{\"jsonrpc\":\"2.0\",\"method\":\"eth_getTransactionCount\",\"params\":[\"$DEPLOYER\",\"pending\"],\"id\":1}" "$RPC_URL" 2>/dev/null | jq -r '.result // empty' | tr -d '"' || echo "0x0") PENDING_DEC2=$(printf '%d' "$PENDING_HEX2" 2>/dev/null || echo "0") if [ "$PENDING_DEC2" -eq "$LATEST_DEC" ] || [ "$PENDING_DEC2" -le "$LATEST_DEC" ]; then log_ok "Pending nonce after flush: $PENDING_DEC2 (expected ≤ $LATEST_DEC or same as latest). Next nonce to use: $((LATEST_DEC + 1))." else log_warn "Pending nonce still $PENDING_DEC2. Re-run with --full or check validators/RPC logs." fi echo "" log_ok "Done. Run: bash scripts/monitoring/monitor-blockchain-health.sh" echo ""