99 lines
3.0 KiB
Bash
Executable File
99 lines
3.0 KiB
Bash
Executable File
#!/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
|
|
|