Files
proxmox/scripts/archive/consolidated/deploy/deploy-with-retry-and-status-check.sh
defiQUG fbda1b4beb
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
docs: Ledger Live integration, contract deploy learnings, NEXT_STEPS updates
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands
- CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround
- CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check
- NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere
- MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates
- LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 15:46:57 -08:00

233 lines
8.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Deploy Contracts with Retry Logic and Status Checking
# Includes transaction status verification and exponential backoff retry
set -euo pipefail
# Load IP configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$PROJECT_ROOT"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
log_error() { echo -e "${RED}[✗]${NC} $1"; }
log_section() { echo -e "\n${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"; echo -e "${CYAN}$1${NC}"; echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"; }
# Load environment
if [ -f "$PROJECT_ROOT/smom-dbis-138/.env" ]; then
set +e
source "$PROJECT_ROOT/smom-dbis-138/.env" 2>/dev/null || true
set -e
fi
PRIVATE_KEY="${PRIVATE_KEY:-}"
RPC_URL="${RPC_URL_138:-http://${RPC_CORE_1}:8545}"
GAS_PRICE="${GAS_PRICE:-5000000000}" # 5 gwei default (higher for replacements)
if [ -z "$PRIVATE_KEY" ]; then
log_error "PRIVATE_KEY not set"
exit 1
fi
DEPLOYER=$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || echo "")
if [ -z "$DEPLOYER" ]; then
log_error "Failed to derive deployer address"
exit 1
fi
# Retry configuration
MAX_RETRIES=3
INITIAL_RETRY_DELAY=5
MAX_RETRY_DELAY=30
log_section "Deploy with Retry and Status Check"
# Check transaction status before deployment
check_transaction_status() {
local deployer=$1
local rpc_url=$2
log_info "Checking transaction status for $deployer..."
LATEST_HEX=$(timeout 10 cast rpc eth_getTransactionCount "$deployer" latest --rpc-url "$rpc_url" 2>/dev/null || echo "")
PENDING_HEX=$(timeout 10 cast rpc eth_getTransactionCount "$deployer" pending --rpc-url "$rpc_url" 2>/dev/null || echo "")
if [ -z "$LATEST_HEX" ] || [ -z "$PENDING_HEX" ]; then
log_warn "Could not check transaction status"
return 1
fi
LATEST_CLEAN=$(echo "$LATEST_HEX" | tr -d '"')
PENDING_CLEAN=$(echo "$PENDING_HEX" | tr -d '"')
LATEST_DEC=$(python3 -c "print(int('$LATEST_CLEAN', 16))" 2>/dev/null || echo "0")
PENDING_DEC=$(python3 -c "print(int('$PENDING_CLEAN', 16))" 2>/dev/null || echo "0")
log_info "Latest nonce: $LATEST_DEC"
log_info "Pending nonce: $PENDING_DEC"
if [ "$PENDING_DEC" -gt "$LATEST_DEC" ]; then
local pending_count=$((PENDING_DEC - LATEST_DEC))
log_warn "⚠️ $pending_count pending transaction(s) detected"
log_info "Will use nonce $PENDING_DEC (next available)"
echo "$PENDING_DEC"
return 0
else
log_info "No pending transactions"
echo "$LATEST_DEC"
return 0
fi
}
# Deploy with retry
deploy_with_retry() {
local contract_name=$1
local bytecode=$2
local nonce=$3
local gas_price=$4
local rpc_url=$5
local private_key=$6
local retry_count=0
local retry_delay=$INITIAL_RETRY_DELAY
while [ $retry_count -lt $MAX_RETRIES ]; do
log_info "Deploying $contract_name (attempt $((retry_count + 1))/$MAX_RETRIES)..."
log_info "Nonce: $nonce, Gas Price: $gas_price wei"
DEPLOY_OUTPUT=$(timeout 60 cast send \
--rpc-url "$rpc_url" \
--private-key "$private_key" \
--nonce "$nonce" \
--gas-price "$gas_price" \
--create "$bytecode" \
2>&1 || echo "")
if echo "$DEPLOY_OUTPUT" | grep -q "contractAddress\|transactionHash"; then
log_success "$contract_name deployment transaction sent!"
echo "$DEPLOY_OUTPUT"
return 0
elif echo "$DEPLOY_OUTPUT" | grep -q "Known transaction"; then
log_warn "Known transaction error - transaction already exists"
if [ $retry_count -lt $((MAX_RETRIES - 1)) ]; then
log_info "Increasing gas price for replacement..."
gas_price=$((gas_price * 11 / 10)) # Increase by 10%
log_info "New gas price: $gas_price wei"
fi
elif echo "$DEPLOY_OUTPUT" | grep -q "timeout\|Connection timed out"; then
log_warn "Connection timeout - will retry"
elif echo "$DEPLOY_OUTPUT" | grep -q "Replacement transaction underpriced"; then
log_warn "Replacement transaction underpriced - increasing gas price..."
gas_price=$((gas_price * 12 / 10)) # Increase by 20%
log_info "New gas price: $gas_price wei"
else
log_warn "Deployment failed: $(echo "$DEPLOY_OUTPUT" | tail -3)"
fi
retry_count=$((retry_count + 1))
if [ $retry_count -lt $MAX_RETRIES ]; then
log_info "Waiting $retry_delay seconds before retry..."
sleep $retry_delay
retry_delay=$((retry_delay * 2))
if [ $retry_delay -gt $MAX_RETRY_DELAY ]; then
retry_delay=$MAX_RETRY_DELAY
fi
fi
done
log_error "Failed to deploy $contract_name after $MAX_RETRIES attempts"
return 1
}
# Main deployment function
deploy_contract() {
local contract_name=$1
local contract_file=$2
local constructor_args=$3
log_section "Deploy $contract_name"
# Check status and get nonce
CURRENT_NONCE=$(check_transaction_status "$DEPLOYER" "$RPC_URL")
if [ -z "$CURRENT_NONCE" ]; then
log_error "Failed to get transaction status"
return 1
fi
# Ensure compiled
cd "$PROJECT_ROOT/smom-dbis-138"
if [ ! -f "out/$contract_file/$contract_name.json" ]; then
log_info "Compiling $contract_name..."
forge build --force "contracts/$contract_file/$contract_name.sol" 2>&1 | tail -5
fi
# Extract bytecode
BYTECODE=$(jq -r '.bytecode.object' "out/$contract_file/$contract_name.json" 2>/dev/null || echo "")
if [ -z "$BYTECODE" ] || [ "$BYTECODE" = "null" ]; then
log_error "Failed to extract bytecode"
return 1
fi
# Encode constructor arguments if provided
if [ -n "$constructor_args" ]; then
CONSTRUCTOR_ENCODED=$(eval "cast abi-encode $constructor_args" 2>/dev/null || echo "")
CONSTRUCTOR_ENCODED="${CONSTRUCTOR_ENCODED#0x}"
BYTECODE_CLEAN="${BYTECODE#0x}"
FULL_BYTECODE="0x${BYTECODE_CLEAN}${CONSTRUCTOR_ENCODED}"
else
FULL_BYTECODE="$BYTECODE"
fi
# Deploy with retry
DEPLOY_OUTPUT=$(deploy_with_retry "$contract_name" "$FULL_BYTECODE" "$CURRENT_NONCE" "$GAS_PRICE" "$RPC_URL" "$PRIVATE_KEY")
if [ $? -eq 0 ]; then
# Extract contract address
CONTRACT_ADDR=$(echo "$DEPLOY_OUTPUT" | grep -oE "contractAddress.*0x[a-fA-F0-9]{40}|0x[a-fA-F0-9]{40}" | grep -oE "0x[a-fA-F0-9]{40}" | head -1 || echo "")
if [ -n "$CONTRACT_ADDR" ]; then
log_success "$contract_name deployed to: $CONTRACT_ADDR"
echo "$CONTRACT_ADDR"
return 0
fi
fi
return 1
}
# Deploy WETH9 Bridge
WETH9_BRIDGE=$(deploy_contract "CCIPWETH9Bridge" "bridge/ccip/CCIPWETH9Bridge.sol" \
"constructor(address,address,address) $CCIP_ROUTER 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 $CCIP_FEE_TOKEN" || echo "")
# Deploy WETH10 Bridge
WETH10_BRIDGE=$(deploy_contract "CCIPWETH10Bridge" "bridge/ccip/CCIPWETH10Bridge.sol" \
"constructor(address,address,address) $CCIP_ROUTER 0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f $CCIP_FEE_TOKEN" || echo "")
# Summary
log_section "Deployment Summary"
if [ -n "$WETH9_BRIDGE" ]; then
log_success "WETH9 Bridge: $WETH9_BRIDGE"
else
log_error "WETH9 Bridge: Deployment failed"
fi
if [ -n "$WETH10_BRIDGE" ]; then
log_success "WETH10 Bridge: $WETH10_BRIDGE"
else
log_error "WETH10 Bridge: Deployment failed"
fi