diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..8c427131 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,27 @@ +# Exclude database and execution data directories from Docker build context +blockscout-postgres-data/ +execution-data/ +blockscout-db-data/ +mysql-data/ +rabbitmq/ + +# Exclude git directory +.git/ +.gitmodules + +# Exclude deployment artifacts +deployment/ + +# Exclude environment files +.env +.env.* + +# Exclude docker compose files (not needed in build context) +docker-compose*.yml + +# Exclude any other data directories +*-data/ +data/ + +# Exclude temporary files +tmp/ diff --git a/.github/workflows/devnet-test-no-provers.yml b/.github/workflows/devnet-test-no-provers.yml new file mode 100644 index 00000000..cf03ef2e --- /dev/null +++ b/.github/workflows/devnet-test-no-provers.yml @@ -0,0 +1,131 @@ +name: Devnet Provision Check (No Provers) + +on: + schedule: + # Run nightly at 2 AM UTC + - cron: '0 2 * * *' + workflow_dispatch: + # Allow manual trigger + pull_request: + paths: + - 'docker-compose*.yml' + - 'surge-*.sh' + - 'script/devnet-provision-check.sh' + - 'script/devnet-provision-check-ci.sh' + - 'script/util/common.sh' + - '.github/workflows/devnet-test-no-provers.yml' + +env: + SURGE_ETHEREUM_PACKAGE_REPO: 'NethermindEth/surge-ethereum-package' + SURGE_ETHEREUM_PACKAGE_REF: 'main' + +jobs: + devnet-provision-check-no-provers: + name: Devnet Provision Check (No Provers) + permissions: + contents: read + issues: write + runs-on: ubuntu-22.04 + timeout-minutes: 45 + + steps: + - name: Checkout simple-surge-node + uses: actions/checkout@v4 + with: + path: simple-surge-node + + - name: Checkout surge-ethereum-package + uses: actions/checkout@v4 + with: + repository: ${{ env.SURGE_ETHEREUM_PACKAGE_REPO }} + ref: ${{ env.SURGE_ETHEREUM_PACKAGE_REF }} + path: surge-ethereum-package + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y curl jq + + - name: Install Kurtosis CLI + run: | + echo "deb [trusted=yes] https://apt.fury.io/kurtosis-tech/ /" | sudo tee /etc/apt/sources.list.d/kurtosis.list + sudo apt-get update + sudo apt-get install -y kurtosis-cli + kurtosis version + + - name: Verify Docker installation + run: | + docker --version + docker compose version + docker info + + - name: Run Devnet Provision Check (No Provers) + working-directory: simple-surge-node + env: + L1_PACKAGE_DIR: ../surge-ethereum-package + L1_ENVIRONMENT: local + L1_MODE: silence + L1_RPC_URL: http://localhost:32003 + L1_STABILIZE_WAIT: 20 + ENABLE_PROVER: false + run: | + ./script/devnet-provision-check-ci.sh + + - name: Collect Docker logs on failure + if: failure() + working-directory: simple-surge-node + run: | + echo "Docker Compose Services Status" + docker compose ps || true + + echo "Docker Compose Logs (last 100 lines)" + docker compose logs --tail=100 || true + + echo "Kurtosis Enclaves" + kurtosis enclave ls || true + + echo "Kurtosis Services (surge-devnet)" + kurtosis enclave inspect surge-devnet || true + + - name: Cleanup - Stop L2 services + if: always() + working-directory: simple-surge-node + run: | + ./surge-remover.sh --devnet-non-interactive || true + + - name: Cleanup - Stop L1 devnet + if: always() + run: | + cd surge-ethereum-package && ./remove-surge-devnet-l1.sh --force || true + + - name: Cleanup - Docker system prune + if: always() + run: | + docker system prune -af --volumes || true + + - name: Upload test artifacts + if: failure() + uses: actions/upload-artifact@v4 + with: + name: devnet-provision-check-no-provers-logs + path: | + simple-surge-node/deployment/*.json + simple-surge-node/*.log + retention-days: 7 + if-no-files-found: ignore + + - name: Notify on failure + if: failure() && github.event_name == 'schedule' + uses: actions/github-script@v7 + with: + script: | + github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: 'Nightly Devnet Provision Check (No Provers) Failed', + body: 'The nightly devnet provision check (no provers) failed on ' + new Date().toISOString() + '\n\nWorkflow run: ' + context.serverUrl +'/' + context.repo.owner + '/' + context.repo.repo + '/actions/runs/' + context.runId, + labels: ['bug', 'devnet', 'provision-check', 'automated'] + }) \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8b21338f..1ea3574a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,10 +3,14 @@ .idea/ -/mysql-data/ -/rabbitmq/ -/execution-data/ +/mysql-data/* +!/mysql-data/.gitkeep +/rabbitmq/* +!/rabbitmq/.gitkeep +/execution-data/* +!/execution-data/.gitkeep /deployment/*.json /deployment/*.lock /configs/*.json -/blockscout-postgres-data/ +/blockscout-postgres-data/* +!/blockscout-postgres-data/.gitkeep diff --git a/blockscout-postgres-data/.gitkeep b/blockscout-postgres-data/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose-relayer.yml b/docker-compose-relayer.yml index caca2c1c..f738b132 100644 --- a/docker-compose-relayer.yml +++ b/docker-compose-relayer.yml @@ -3,6 +3,8 @@ services: relayer-db: image: mysql:8.0 container_name: relayer-db + # Only set user if DOCKER_USER is explicitly provided (local dev), not in CI + user: "${DOCKER_USER:-}" cap_add: - SYS_NICE restart: always diff --git a/docker-compose.yml b/docker-compose.yml index 52f3711b..856d76d7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -256,6 +256,8 @@ services: blockscout-postgres: image: postgres:alpine container_name: l2-blockscout-postgres + # Only set user if DOCKER_USER is explicitly provided (local dev), not in CI + user: "${DOCKER_USER:-}" restart: unless-stopped pull_policy: always volumes: diff --git a/execution-data/.gitkeep b/execution-data/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/mysql-data/.gitkeep b/mysql-data/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/rabbitmq/.gitkeep b/rabbitmq/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/script/devnet-provision-check-ci.sh b/script/devnet-provision-check-ci.sh new file mode 100755 index 00000000..ae56e863 --- /dev/null +++ b/script/devnet-provision-check-ci.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Source common utilities +source "$SCRIPT_DIR/util/common.sh" + +# Configuration with defaults +L1_PACKAGE_DIR="${L1_PACKAGE_DIR:-$PROJECT_ROOT/../surge-ethereum-package}" +L1_ENVIRONMENT="${L1_ENVIRONMENT:-local}" +L1_MODE="${L1_MODE:-silence}" +L1_RPC_URL="${L1_RPC_URL:-http://localhost:32003}" +L1_STABILIZE_WAIT="${L1_STABILIZE_WAIT:-20}" +ENABLE_PROVER="${ENABLE_PROVER:-false}" +ENV_FILE="${ENV_FILE:-$PROJECT_ROOT/.env.devnet}" + +echo "Starting CI Devnet Provision Check (No Provers)" +echo + +# Step 1: Deploy L1 Devnet +echo "Step 1: Deploy L1 Devnet" +deploy_l1 "$L1_PACKAGE_DIR" "$L1_ENVIRONMENT" "$L1_MODE" +echo + +# Step 2: Verify L1 is ready +echo "Step 2: Verify L1 is ready" +print_info "Waiting ${L1_STABILIZE_WAIT} seconds for L1 to stabilize..." +sleep "$L1_STABILIZE_WAIT" + +wait_for_rpc "$L1_RPC_URL" +echo + +# Step 3: Configure environment for no-prover testing +if [ "$ENABLE_PROVER" = "false" ]; then + echo "Step 3: Configure environment for no-prover testing" + configure_env_no_provers "$ENV_FILE" + echo +fi + +# Step 4: Run L2 Devnet Provision Check +echo "Step 4: Run L2 Devnet Provision Check" +cd "$PROJECT_ROOT" +"$SCRIPT_DIR/devnet-provision-check.sh" diff --git a/script/devnet-provision-check.sh b/script/devnet-provision-check.sh new file mode 100755 index 00000000..28239796 --- /dev/null +++ b/script/devnet-provision-check.sh @@ -0,0 +1,156 @@ +#!/bin/bash + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Source common utilities if available, otherwise define locally +if [ -f "$SCRIPT_DIR/util/common.sh" ]; then + source "$SCRIPT_DIR/util/common.sh" +else + print_success() { echo "[SUCCESS] $1"; } + print_error() { echo "[ERROR] $1"; } + print_info() { echo "[INFO] $1"; } +fi + +# Ensure we're in the project root +cd "$PROJECT_ROOT" + +echo "Starting Devnet Provision Check (No Provers)" +echo + +# Step 1: Clean up any existing deployment +echo "Step 1: Cleanup existing deployment" +if [ -f "deployment/deploy_l1.json" ] || docker compose ps --services 2>/dev/null | grep -q .; then + print_info "Found existing deployment, running cleanup" + if ./surge-remover.sh --devnet-non-interactive; then + print_success "Cleanup completed" + else + print_error "Cleanup failed" + exit 1 + fi +else + print_info "No existing deployment found, skipping cleanup" +fi +echo + +# Step 2: Prepare environment +echo "Step 2: Prepare environment" +if [ ! -f .env ]; then + print_info "Copying .env.devnet to .env" + cp .env.devnet .env + print_success ".env file created" +else + print_info ".env file already exists" +fi +echo + +# Step 3: Deploy protocol +echo "Step 3: Deploy protocol (L1 contracts)" +print_info "Running surge-protocol-deployer.sh --devnet-non-interactive" +if ./surge-protocol-deployer.sh --devnet-non-interactive; then + print_success "Protocol deployment completed" +else + print_error "Protocol deployment failed" + exit 1 +fi +echo + +# Step 4: Verify protocol deployment artifacts +echo "Step 4: Verify protocol deployment" +if [ ! -f "deployment/deploy_l1.json" ]; then + print_error "deploy_l1.json not found" + exit 1 +else + print_success "deploy_l1.json found" +fi + +if [ ! -f "deployment/proposer_wrappers.json" ]; then + print_error "proposer_wrappers.json not found" + exit 1 +else + print_success "proposer_wrappers.json found" +fi +echo + +# Step 5: Deploy stack +echo "Step 5: Deploy L2 stack" +print_info "Running surge-stack-deployer.sh --devnet-non-interactive" +if ./surge-stack-deployer.sh --devnet-non-interactive; then + print_success "Stack deployment completed" +else + print_error "Stack deployment failed" + exit 1 +fi +echo + +# Step 6: Verify services are running +echo "Step 6: Verify services" +print_info "Checking running containers" +docker compose ps +echo + +print_info "Checking critical containers are healthy..." +# Check L2 execution client container +if docker compose ps | grep "l2-nethermind-execution-client" | grep -q "(healthy)"; then + print_success "L2 execution client container is healthy" +else + print_error "L2 execution client container is not healthy" + exit 1 +fi + +# Check other critical containers are running +CRITICAL_CONTAINERS=("l2-taiko-consensus-client" "l2-taiko-proposer-client" "relayer-l1-indexer" "relayer-l2-indexer") +for container in "${CRITICAL_CONTAINERS[@]}"; do + if docker compose ps | grep "$container" | grep -q "Up"; then + print_success "$container is running" + else + print_error "$container is not running" + exit 1 + fi +done +echo + +# Step 7: Health check L2 RPC endpoint +echo "Step 7: Health check L2 RPC endpoint" +print_info "Waiting 30 seconds for services to stabilize..." +sleep 30 + +print_info "Testing L2 RPC endpoint at http://localhost:8547" +if curl -f http://localhost:8547 -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' 2>/dev/null; then + echo + print_success "L2 execution client RPC is responding" +else + echo + print_error "L2 execution client RPC health check failed" + exit 1 +fi +echo + +# Step 8: Check for errors in logs +echo "Step 8: Check for errors in logs" +print_info "Checking for errors in container logs (last 50 lines)" +if docker compose logs --tail=50 | grep -i "error\|fatal\|panic" | grep -v "error_code" | head -20; then + print_info "Found some errors in logs (review above)" +else + print_success "No critical errors found in recent logs" +fi +echo + +# Final summary +echo "==========================================" +echo "Provision Check Summary" +echo "==========================================" +print_success "All provision checks passed!" +echo +print_info "Services are running. You can now:" +echo " - Access L2 RPC: http://localhost:8547" +echo " - Access L2 Blockscout: http://localhost:3000" +echo " - Access L1 RPC: http://localhost:32003" +echo " - View logs: docker compose logs -f" +echo +print_info "To clean up when done:" +echo " ./surge-remover.sh --devnet-non-interactive" +echo diff --git a/script/util/common.sh b/script/util/common.sh new file mode 100755 index 00000000..a1c86569 --- /dev/null +++ b/script/util/common.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +# Common utility functions for Surge devnet scripts + +set -o pipefail + +print_success() { + echo "[SUCCESS] $1" +} + +print_error() { + echo "[ERROR] $1" +} + +print_info() { + echo "[INFO] $1" +} + +wait_for_rpc() { + local rpc_url="$1" + local max_retries="${2:-10}" + local retry_delay="${3:-10}" + + print_info "Testing RPC endpoint at $rpc_url" + local retry_count=0 + + while [ $retry_count -lt $max_retries ]; do + if curl -f "$rpc_url" -X POST -H "Content-Type: application/json" \ + --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' 2>/dev/null; then + echo + print_success "RPC is responding" + return 0 + else + retry_count=$((retry_count + 1)) + if [ $retry_count -eq $max_retries ]; then + echo + print_error "RPC failed to respond after $max_retries retries" + return 1 + fi + print_info "Retry $retry_count/$max_retries - waiting ${retry_delay}s..." + sleep "$retry_delay" + fi + done +} + +deploy_l1() { + local l1_package_dir="${1:-../surge-ethereum-package}" + local environment="${2:-local}" + local mode="${3:-silence}" + + echo "Deploying L1 Devnet" + + if [ ! -d "$l1_package_dir" ]; then + print_error "surge-ethereum-package directory not found at $l1_package_dir" + print_info "Current directory: $(pwd)" + ls -la ../ + return 1 + fi + + print_info "Running L1 deployment from $l1_package_dir" + pushd "$l1_package_dir" > /dev/null + + if ./deploy-surge-devnet-l1.sh --environment "$environment" --mode "$mode"; then + popd > /dev/null + print_success "L1 deployment completed" + return 0 + else + popd > /dev/null + print_error "L1 deployment failed" + return 1 + fi +} + +configure_env_no_provers() { + local env_file="${1:-.env.devnet}" + + echo "Configuring environment for no-prover testing" + print_info "Disabling provers in $env_file" + + if [ ! -f "$env_file" ]; then + print_error "$env_file not found" + return 1 + fi + + sed -i 's/^ENABLE_PROVER=true/ENABLE_PROVER=false/' "$env_file" + print_success "Provers disabled" + return 0 +} diff --git a/surge-protocol-deployer.sh b/surge-protocol-deployer.sh index 0f8b87a1..20f4d198 100755 --- a/surge-protocol-deployer.sh +++ b/surge-protocol-deployer.sh @@ -4,41 +4,59 @@ set -e git submodule update --init --recursive -# Select which Surge environment to use -echo -echo "╔══════════════════════════════════════════════════════════════╗" -echo " ⚠️ Select which Surge environment to use: " -echo "║══════════════════════════════════════════════════════════════║" -echo "║ 1 for Devnet ║" -echo "║ 2 for Staging ║" -echo "║ 3 for Testnet ║" -echo "║ [default: Devnet] ║" -echo "╚══════════════════════════════════════════════════════════════╝" -echo -read -r surge_environment - -SURGE_ENVIRONMENT=${surge_environment:-1} +NON_INTERACTIVE=false +if [ "$1" = "--devnet-non-interactive" ]; then + NON_INTERACTIVE=true +fi -if [ "$SURGE_ENVIRONMENT" = "1" ]; then +# Export DOCKER_USER for local development to avoid permission issues with database containers +# In CI (NON_INTERACTIVE=true), this remains unset so containers run as root for proper initialization +if [ "$NON_INTERACTIVE" = "false" ] && [ -z "$DOCKER_USER" ]; then + export DOCKER_USER="$(id -u):$(id -g)" +fi + +if [ "$NON_INTERACTIVE" = "true" ]; then + SURGE_ENVIRONMENT=1 + REMOTE_OR_LOCAL=0 +else + # Select which Surge environment to use echo echo "╔══════════════════════════════════════════════════════════════╗" - echo " 🚀 Using Devnet Environment " + echo " ⚠️ Select which Surge environment to use: " + echo "║══════════════════════════════════════════════════════════════║" + echo "║ 1 for Devnet ║" + echo "║ 2 for Staging ║" + echo "║ 3 for Testnet ║" + echo "║ [default: Devnet] ║" echo "╚══════════════════════════════════════════════════════════════╝" echo + read -r surge_environment + + SURGE_ENVIRONMENT=${surge_environment:-1} +fi - # Select remote or local +if [ "$SURGE_ENVIRONMENT" = "1" ]; then echo echo "╔══════════════════════════════════════════════════════════════╗" - echo " ⚠️ Select remote or local: " - echo "║══════════════════════════════════════════════════════════════║" - echo "║ 0 for local ║" - echo "║ 1 for remote ║" - echo "║ [default: local] ║" + echo " 🚀 Using Devnet Environment " echo "╚══════════════════════════════════════════════════════════════╝" echo - read -r remote_or_local -REMOTE_OR_LOCAL=${remote_or_local:-0} + if [ "$NON_INTERACTIVE" = "false" ]; then + # Select remote or local + echo + echo "╔══════════════════════════════════════════════════════════════╗" + echo " ⚠️ Select remote or local: " + echo "║══════════════════════════════════════════════════════════════║" + echo "║ 0 for local ║" + echo "║ 1 for remote ║" + echo "║ [default: local] ║" + echo "╚══════════════════════════════════════════════════════════════╝" + echo + read -r remote_or_local + + REMOTE_OR_LOCAL=${remote_or_local:-0} + fi if [ "$REMOTE_OR_LOCAL" = "1" ]; then # Select which devnet machine to use echo @@ -344,17 +362,21 @@ deploy_l1() { # Check if deployment is already completed if [ -f "deployment/deploy_l1.json" ]; then - # Prompt user for starting a new deployment if the deployment results are already present - echo - echo "╔══════════════════════════════════════════════════════════════╗" - echo " ⚠️ Surge L1 deployment already completed " - echo " (deploy_l1.json exists) " - echo "║══════════════════════════════════════════════════════════════║" - echo "║ Start a new deployment? (true/false) [default: false] ║" - echo "╚══════════════════════════════════════════════════════════════╝" - echo - read -r start_new_deployment - START_NEW_DEPLOYMENT=${start_new_deployment:-false} + if [ "$NON_INTERACTIVE" = "true" ]; then + START_NEW_DEPLOYMENT=false + else + # Prompt user for starting a new deployment if the deployment results are already present + echo + echo "╔══════════════════════════════════════════════════════════════╗" + echo " ⚠️ Surge L1 deployment already completed " + echo " (deploy_l1.json exists) " + echo "║══════════════════════════════════════════════════════════════║" + echo "║ Start a new deployment? (true/false) [default: false] ║" + echo "╚══════════════════════════════════════════════════════════════╝" + echo + read -r start_new_deployment + START_NEW_DEPLOYMENT=${start_new_deployment:-false} + fi if [ "$START_NEW_DEPLOYMENT" = "true" ]; then echo @@ -400,15 +422,19 @@ deploy_l1() { echo "╚══════════════════════════════════════════════════════════════╝" echo - # Prompt user for USE_TIMELOCKED_OWNER with default to false - echo - echo "╔══════════════════════════════════════════════════════════════╗" - echo "║ Use timelocked owner? (true/false) [default: false] ║" - echo "╚══════════════════════════════════════════════════════════════╝" - echo - read -r timelocked_owner + if [ "$NON_INTERACTIVE" = "true" ]; then + export USE_TIMELOCKED_OWNER=false + else + # Prompt user for USE_TIMELOCKED_OWNER with default to false + echo + echo "╔══════════════════════════════════════════════════════════════╗" + echo "║ Use timelocked owner? (true/false) [default: false] ║" + echo "╚══════════════════════════════════════════════════════════════╝" + echo + read -r timelocked_owner - export USE_TIMELOCKED_OWNER=${timelocked_owner:-false} + export USE_TIMELOCKED_OWNER=${timelocked_owner:-false} + fi # Update USE_TIMELOCKED_OWNER in env file for other functions and scripts to use update_env_var ".env" "USE_TIMELOCKED_OWNER" "$USE_TIMELOCKED_OWNER" @@ -569,15 +595,19 @@ extract_surge_proposer_wrapper() { } deploy_provers() { - # Prompt user for RUNNING_PROVERS with default to false - echo - echo "╔══════════════════════════════════════════════════════════════╗" - echo "║ Running provers? (true/false) [default: false] ║" - echo "╚══════════════════════════════════════════════════════════════╝" - echo - read -r running_provers + if [ "$NON_INTERACTIVE" = "true" ]; then + RUNNING_PROVERS=false + else + # Prompt user for RUNNING_PROVERS with default to false + echo + echo "╔══════════════════════════════════════════════════════════════╗" + echo "║ Running provers? (true/false) [default: false] ║" + echo "╚══════════════════════════════════════════════════════════════╝" + echo + read -r running_provers - RUNNING_PROVERS=${running_provers:-false} + RUNNING_PROVERS=${running_provers:-false} + fi # If running provers is true, set up the verifiers if [ "$RUNNING_PROVERS" = "true" ]; then @@ -783,26 +813,34 @@ deposit_bond() { echo "╚══════════════════════════════════════════════════════════════╝" echo - # Prompt user for deposit bond - echo - echo "╔══════════════════════════════════════════════════════════════╗" - echo "║ Deposit bond? (true/false) [default: true] ║" - echo "╚══════════════════════════════════════════════════════════════╝" - echo - read -r deposit_bond - - DEPOSIT_BOND=${deposit_bond:-true} - - if [ "$DEPOSIT_BOND" = "true" ]; then - # Prompt user for BOND_AMOUNT + if [ "$NON_INTERACTIVE" = "true" ]; then + DEPOSIT_BOND=true + else + # Prompt user for deposit bond echo echo "╔══════════════════════════════════════════════════════════════╗" - echo "║ Enter bond amount (in ETH, default: 1000) ║" + echo "║ Deposit bond? (true/false) [default: true] ║" echo "╚══════════════════════════════════════════════════════════════╝" echo - read -r bond_amount + read -r deposit_bond + + DEPOSIT_BOND=${deposit_bond:-true} + fi - BOND_AMOUNT=${bond_amount:-1000} + if [ "$DEPOSIT_BOND" = "true" ]; then + if [ "$NON_INTERACTIVE" = "true" ]; then + BOND_AMOUNT=1000 + else + # Prompt user for BOND_AMOUNT + echo + echo "╔══════════════════════════════════════════════════════════════╗" + echo "║ Enter bond amount (in ETH, default: 1000) ║" + echo "╚══════════════════════════════════════════════════════════════╝" + echo + read -r bond_amount + + BOND_AMOUNT=${bond_amount:-1000} + fi # Convert to wei export BOND_AMOUNT=$(echo "$BOND_AMOUNT * 1000000000000000000" | bc | cut -d. -f1) diff --git a/surge-remover.sh b/surge-remover.sh index a40e8b6c..dce63052 100755 --- a/surge-remover.sh +++ b/surge-remover.sh @@ -2,6 +2,11 @@ set -e +NON_INTERACTIVE=false +if [ "$1" = "--devnet-non-interactive" ]; then + NON_INTERACTIVE=true +fi + remove_l2_stack() { echo echo "╔══════════════════════════════════════════════════════════════╗" @@ -49,11 +54,32 @@ remove_db() { echo "╚══════════════════════════════════════════════════════════════╝" echo - # Remove DB - rm -rf ./execution-data - rm -rf ./blockscout-postgres-data - rm -rf ./mysql-data - rm -rf ./rabbitmq + # Remove DB contents but preserve directory structure with .gitkeep + if [ -d "./execution-data" ] && [ -n "$(ls -A ./execution-data 2>/dev/null)" ]; then + rm -rf ./execution-data/* || echo "Warning: Could not remove some execution-data files" + fi + + if [ -d "./blockscout-postgres-data" ] && [ -n "$(ls -A ./blockscout-postgres-data 2>/dev/null)" ]; then + rm -rf ./blockscout-postgres-data/* || echo "Warning: Could not remove some blockscout-postgres-data files" + fi + + if [ -d "./mysql-data" ] && [ -n "$(ls -A ./mysql-data 2>/dev/null)" ]; then + rm -rf ./mysql-data/* || echo "Warning: Could not remove some mysql-data files" + fi + + if [ -d "./rabbitmq" ] && [ -n "$(ls -A ./rabbitmq 2>/dev/null)" ]; then + rm -rf ./rabbitmq/* || echo "Warning: Could not remove some rabbitmq files" + fi + + # Recreate .gitkeep files + mkdir -p ./execution-data + touch ./execution-data/.gitkeep + mkdir -p ./blockscout-postgres-data + touch ./blockscout-postgres-data/.gitkeep + mkdir -p ./mysql-data + touch ./mysql-data/.gitkeep + mkdir -p ./rabbitmq + touch ./rabbitmq/.gitkeep echo echo "╔══════════════════════════════════════════════════════════════╗" diff --git a/surge-stack-deployer.sh b/surge-stack-deployer.sh index e6c606ef..0607401b 100755 --- a/surge-stack-deployer.sh +++ b/surge-stack-deployer.sh @@ -4,6 +4,17 @@ set -e git submodule update --init --recursive +NON_INTERACTIVE=false +if [ "$1" = "--devnet-non-interactive" ]; then + NON_INTERACTIVE=true +fi + +# Export DOCKER_USER for local development to avoid permission issues with database containers +# In CI (NON_INTERACTIVE=true), this remains unset so containers run as root for proper initialization +if [ "$NON_INTERACTIVE" = "false" ] && [ -z "$DOCKER_USER" ]; then + export DOCKER_USER="$(id -u):$(id -g)" +fi + check_env_file() { if [ -f .env ]; then echo @@ -63,34 +74,39 @@ prepare_blockscout_for_remote() { sed -i.bak 's/^BLOCKSCOUT_L2_HOST=.*/BLOCKSCOUT_L2_HOST='$MACHINE_IP'/g' .env } -# Select which Surge environment to use -echo -echo "╔══════════════════════════════════════════════════════════════╗" -echo " ⚠️ Select which Surge environment to use: " -echo "║══════════════════════════════════════════════════════════════║" -echo "║ 1 for Devnet ║" -echo "║ 2 for Staging ║" -echo "║ 3 for Testnet ║" -echo "║ [default: Devnet] ║" -echo "╚══════════════════════════════════════════════════════════════╝" -echo -read -r surge_environment - -SURGE_ENVIRONMENT=${surge_environment:-1} - -# Select remote or local -echo -echo "╔══════════════════════════════════════════════════════════════╗" -echo " ⚠️ Select remote or local: " -echo "║══════════════════════════════════════════════════════════════║" -echo "║ 0 for local ║" -echo "║ 1 for remote ║" -echo "║ [default: local] ║" -echo "╚══════════════════════════════════════════════════════════════╝" -echo -read -r remote_or_local - -REMOTE_OR_LOCAL=${remote_or_local:-0} +if [ "$NON_INTERACTIVE" = "true" ]; then + SURGE_ENVIRONMENT=1 + REMOTE_OR_LOCAL=0 +else + # Select which Surge environment to use + echo + echo "╔══════════════════════════════════════════════════════════════╗" + echo " ⚠️ Select which Surge environment to use: " + echo "║══════════════════════════════════════════════════════════════║" + echo "║ 1 for Devnet ║" + echo "║ 2 for Staging ║" + echo "║ 3 for Testnet ║" + echo "║ [default: Devnet] ║" + echo "╚══════════════════════════════════════════════════════════════╝" + echo + read -r surge_environment + + SURGE_ENVIRONMENT=${surge_environment:-1} + + # Select remote or local + echo + echo "╔══════════════════════════════════════════════════════════════╗" + echo " ⚠️ Select remote or local: " + echo "║══════════════════════════════════════════════════════════════║" + echo "║ 0 for local ║" + echo "║ 1 for remote ║" + echo "║ [default: local] ║" + echo "╚══════════════════════════════════════════════════════════════╝" + echo + read -r remote_or_local + + REMOTE_OR_LOCAL=${remote_or_local:-0} +fi if [ "$REMOTE_OR_LOCAL" = "1" ]; then echo @@ -208,19 +224,23 @@ start_l2_stack() { echo "╚══════════════════════════════════════════════════════════════╝" echo - # Prompt user for L2_STACK_OPTION - echo - echo "╔══════════════════════════════════════════════════════════════╗" - echo "║ Enter L2 stack option: ║" - echo "║ 1 for driver only ║" - echo "║ 2 for driver + proposer ║" - echo "║ 3 for driver + proposer + spammer ║" - echo "║ 4 for driver + proposer + prover + spammer ║" - echo "║ 5 for all except spammer ║" - echo "║ [default: all] ║" - echo "╚══════════════════════════════════════════════════════════════╝" - echo - read -r l2_stack_option + if [ "$NON_INTERACTIVE" = "true" ]; then + l2_stack_option="" + else + # Prompt user for L2_STACK_OPTION + echo + echo "╔══════════════════════════════════════════════════════════════╗" + echo "║ Enter L2 stack option: ║" + echo "║ 1 for driver only ║" + echo "║ 2 for driver + proposer ║" + echo "║ 3 for driver + proposer + spammer ║" + echo "║ 4 for driver + proposer + prover + spammer ║" + echo "║ 5 for all except spammer ║" + echo "║ [default: all] ║" + echo "╚══════════════════════════════════════════════════════════════╝" + echo + read -r l2_stack_option + fi if [ "$l2_stack_option" = "1" ]; then docker compose --profile driver --profile blockscout up -d --remove-orphans @@ -261,15 +281,19 @@ deploy_l2() { } start_relayers() { - # Prompt user for START_RELAYERS - echo - echo "╔══════════════════════════════════════════════════════════════╗" - echo "║ Start relayers? (true/false) [default: true] ║" - echo "╚══════════════════════════════════════════════════════════════╝" - echo - read -r start_relayers + if [ "$NON_INTERACTIVE" = "true" ]; then + START_RELAYERS=true + else + # Prompt user for START_RELAYERS + echo + echo "╔══════════════════════════════════════════════════════════════╗" + echo "║ Start relayers? (true/false) [default: true] ║" + echo "╚══════════════════════════════════════════════════════════════╝" + echo + read -r start_relayers - START_RELAYERS=${start_relayers:-true} + START_RELAYERS=${start_relayers:-true} + fi if [ "$START_RELAYERS" = "true" ]; then if [ "$SURGE_ENVIRONMENT" = "1" ]; then