#!/usr/bin/env bash # Retry Transaction with Exponential Backoff # Usage: ./retry-with-backoff.sh [max_retries] [initial_delay] set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" # 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"; } # Load environment variables if [ -f "$PROJECT_ROOT/.env" ]; then source "$PROJECT_ROOT/.env" elif [ -f "$PROJECT_ROOT/../.env" ]; then source "$PROJECT_ROOT/../.env" fi # Configuration COMMAND="${1:-}" MAX_RETRIES="${2:-3}" INITIAL_DELAY="${3:-5}" GAS_MULTIPLIER=1.5 if [ -z "$COMMAND" ]; then log_error "Command required" log_info "Usage: $0 '' [max_retries] [initial_delay]" log_info "Example: $0 'cast send ... --gas-price \$GAS' 3 5" exit 1 fi RPC_URL="${RPC_URL_138:-http://192.168.11.250:8545}" # Get optimal gas price (increasing with each retry) get_optimal_gas() { local retry_count="$1" local current_gas=$(cast gas-price --rpc-url "$RPC_URL" 2>/dev/null || echo "1000000000") local multiplier=$(echo "scale=2; $GAS_MULTIPLIER * (1 + $retry_count * 0.5)" | bc 2>/dev/null || echo "$GAS_MULTIPLIER") local optimal_gas=$(echo "scale=0; $current_gas * $multiplier / 1" | bc 2>/dev/null || echo "$current_gas") echo "$optimal_gas" } log_info "=========================================" log_info "Retry with Exponential Backoff" log_info "=========================================" log_info "" log_info "Command: $COMMAND" log_info "Max Retries: $MAX_RETRIES" log_info "Initial Delay: $INITIAL_DELAY seconds" log_info "" RETRY=0 DELAY=$INITIAL_DELAY while [ $RETRY -lt $MAX_RETRIES ]; do log_info "Attempt $((RETRY + 1))/$MAX_RETRIES" # Get optimal gas for this retry OPTIMAL_GAS=$(get_optimal_gas $RETRY) OPTIMAL_GAS_GWEI=$(echo "scale=2; $OPTIMAL_GAS / 1000000000" | bc 2>/dev/null || echo "1") log_info "Using gas price: $OPTIMAL_GAS_GWEI gwei" # Replace GAS_PRICE in command if present COMMAND_WITH_GAS=$(echo "$COMMAND" | sed "s/\$GAS_PRICE/$OPTIMAL_GAS/g" | sed "s/\${GAS_PRICE}/$OPTIMAL_GAS/g") # Execute command if eval "$COMMAND_WITH_GAS" 2>&1; then log_success "Command succeeded on attempt $((RETRY + 1))" exit 0 else EXIT_CODE=$? log_warn "Command failed (exit code: $EXIT_CODE)" if [ $RETRY -lt $((MAX_RETRIES - 1)) ]; then log_info "Waiting $DELAY seconds before retry..." sleep $DELAY DELAY=$((DELAY * 2)) # Exponential backoff ((RETRY++)) || true else log_error "Command failed after $MAX_RETRIES attempts" exit $EXIT_CODE fi fi done log_error "All retry attempts exhausted" exit 1