Files
explorer-monorepo/scripts/retry-with-backoff.sh

99 lines
3.0 KiB
Bash
Raw Permalink Normal View History

#!/usr/bin/env bash
# Retry Transaction with Exponential Backoff
# Usage: ./retry-with-backoff.sh <command> [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 '<command>' [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