From f39261bb7fc96c2a0935c94bd5d138c4f0e100fe Mon Sep 17 00:00:00 2001 From: Dijar Llozana Date: Thu, 28 Aug 2025 19:32:01 -0400 Subject: [PATCH 01/18] Modified pipeline to update image names and add hashes --- .github/workflows/docker-build.yaml | 100 ++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 27 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 2b1139e..e9fdbe3 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -1,4 +1,3 @@ -# .github/workflows/docker-build.yml name: Build & Push Docker Images permissions: @@ -8,25 +7,44 @@ permissions: on: push: branches: + - main - dev - - k8s + - staging paths: - 'docker/eigenlayer/**' - 'docker/ethereum/**' workflow_dispatch: jobs: - build-images: - runs-on: ubuntu-latest + build-and-push: + runs-on: self-hosted + container: + image: docker:24.0.1-cli + options: >- + -v /var/run/docker.sock:/var/run/docker.sock steps: - name: Check out code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - - name: Set up lowercase owner & short SHA + - name: Set build vars + id: vars + shell: sh run: | - echo "OWNER_LOWER=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV - echo "SHORT_SHA=${GITHUB_SHA:0:7}" >> $GITHUB_ENV + OWNER_LOWER="$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]')" + SHORT_SHA="$(echo "${GITHUB_SHA}" | cut -c1-7)" + + # channel tag from branch + case "${GITHUB_REF_NAME}" in + main) CHANNEL_TAG="latest" ;; + dev) CHANNEL_TAG="dev" ;; + staging) CHANNEL_TAG="staging" ;; + *) echo "Unsupported branch: ${GITHUB_REF_NAME}"; exit 1 ;; + esac + + echo "OWNER_LOWER=${OWNER_LOWER}" >> "$GITHUB_ENV" + echo "SHORT_SHA=${SHORT_SHA}" >> "$GITHUB_ENV" + echo "CHANNEL_TAG=${CHANNEL_TAG}" >> "$GITHUB_ENV" - name: Detect which Dockerfiles changed id: changes @@ -39,30 +57,58 @@ jobs: - 'docker/ethereum/**' - name: Log in to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build & Push Eigenlayer image + # ---------- Eigenlayer ---------- + - name: Build eigenlayer (multi-tag) if: steps.changes.outputs.eigenlayer == 'true' - uses: docker/build-push-action@v3 - with: - context: docker/eigenlayer - file: docker/eigenlayer/Dockerfile.eigenlayer - push: true - tags: | - ghcr.io/${{ env.OWNER_LOWER }}/eigenlayer:${{ github.ref_name }} - ghcr.io/${{ env.OWNER_LOWER }}/eigenlayer:${{ github.ref_name }}-${{ env.SHORT_SHA }} + shell: sh + run: | + IMAGE="ghcr.io/${OWNER_LOWER}/eigenlayer" + echo "Building ${IMAGE}:${CHANNEL_TAG}" + docker build \ + --label org.opencontainers.image.revision="${GITHUB_SHA}" \ + --label org.opencontainers.image.source="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ + -t "${IMAGE}:${CHANNEL_TAG}" \ + -t "${IMAGE}:${CHANNEL_TAG}-${SHORT_SHA}" \ + -f docker/eigenlayer/Dockerfile.eigenlayer \ + docker/eigenlayer + + - name: Push eigenlayer tags + if: steps.changes.outputs.eigenlayer == 'true' + shell: sh + run: | + IMAGE="ghcr.io/${OWNER_LOWER}/eigenlayer" + for TAG in "${CHANNEL_TAG}" "${CHANNEL_TAG}-${SHORT_SHA}"; do + echo "Pushing ${IMAGE}:${TAG}" + docker push "${IMAGE}:${TAG}" + done - - name: Build & Push Ethereum image + # ---------- Ethereum ---------- + - name: Build ethereum (multi-tag) if: steps.changes.outputs.ethereum == 'true' - uses: docker/build-push-action@v3 - with: - context: . - file: docker/ethereum/Dockerfile.ethereum - push: true - tags: | - ghcr.io/${{ env.OWNER_LOWER }}/ethereum:${{ github.ref_name }} - ghcr.io/${{ env.OWNER_LOWER }}/ethereum:${{ github.ref_name }}-${{ env.SHORT_SHA }} + shell: sh + run: | + IMAGE="ghcr.io/${OWNER_LOWER}/ethereum" + echo "Building ${IMAGE}:${CHANNEL_TAG}" + docker build \ + --label org.opencontainers.image.revision="${GITHUB_SHA}" \ + --label org.opencontainers.image.source="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ + -t "${IMAGE}:${CHANNEL_TAG}" \ + -t "${IMAGE}:${CHANNEL_TAG}-${SHORT_SHA}" \ + -f docker/ethereum/Dockerfile.ethereum \ + . + + - name: Push ethereum tags + if: steps.changes.outputs.ethereum == 'true' + shell: sh + run: | + IMAGE="ghcr.io/${OWNER_LOWER}/ethereum" + for TAG in "${CHANNEL_TAG}" "${CHANNEL_TAG}-${SHORT_SHA}"; do + echo "Pushing ${IMAGE}:${TAG}" + docker push "${IMAGE}:${TAG}" + done From 33e3dca3b018f0a43b051b054fdd129cd37cdca9 Mon Sep 17 00:00:00 2001 From: Dijar Llozana Date: Thu, 28 Aug 2025 19:33:51 -0400 Subject: [PATCH 02/18] Fixed pipeline image --- .github/workflows/docker-build.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index e9fdbe3..d268462 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -16,12 +16,8 @@ on: workflow_dispatch: jobs: - build-and-push: - runs-on: self-hosted - container: - image: docker:24.0.1-cli - options: >- - -v /var/run/docker.sock:/var/run/docker.sock + build-images: + runs-on: ubuntu-latest steps: - name: Check out code From 4d9259101229256cda39fdbcfc16392511d3af95 Mon Sep 17 00:00:00 2001 From: Dijar Llozana Date: Thu, 28 Aug 2025 20:02:34 -0400 Subject: [PATCH 03/18] Fixed labels in docker images --- .github/workflows/docker-build.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index d268462..1a8cbe5 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -67,8 +67,8 @@ jobs: IMAGE="ghcr.io/${OWNER_LOWER}/eigenlayer" echo "Building ${IMAGE}:${CHANNEL_TAG}" docker build \ - --label org.opencontainers.image.revision="${GITHUB_SHA}" \ - --label org.opencontainers.image.source="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ + --label breadchaincoop.eigenlayer.image.revision="${GITHUB_SHA}" \ + --label breadchaincoop.eigenlayer.image.source="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ -t "${IMAGE}:${CHANNEL_TAG}" \ -t "${IMAGE}:${CHANNEL_TAG}-${SHORT_SHA}" \ -f docker/eigenlayer/Dockerfile.eigenlayer \ @@ -92,8 +92,8 @@ jobs: IMAGE="ghcr.io/${OWNER_LOWER}/ethereum" echo "Building ${IMAGE}:${CHANNEL_TAG}" docker build \ - --label org.opencontainers.image.revision="${GITHUB_SHA}" \ - --label org.opencontainers.image.source="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ + --label breadchaincoop.ethereum.image.revision="${GITHUB_SHA}" \ + --label breadchaincoop.ethereum.image.source="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ -t "${IMAGE}:${CHANNEL_TAG}" \ -t "${IMAGE}:${CHANNEL_TAG}-${SHORT_SHA}" \ -f docker/ethereum/Dockerfile.ethereum \ From b9ecfa49c8a3e0899d9a2af93d30d3c5becf7d15 Mon Sep 17 00:00:00 2001 From: bagelface Date: Wed, 3 Sep 2025 18:33:47 -0400 Subject: [PATCH 04/18] feat: deploy array summation contract and refactor docker environment --- README.md | 4 +- docker-compose.yml | 13 +- docker/eigenlayer/Dockerfile | 51 +++++ docker/eigenlayer/Dockerfile.eigenlayer | 28 --- .../counter_and_sig_check_deploy.sh | 85 ------- docker/eigenlayer/get_bls_key.sh | 28 --- docker/eigenlayer/main.sh | 207 +++++++++++++++++- docker/eigenlayer/register.sh | 26 ++- docker/ethereum/Dockerfile | 16 ++ docker/ethereum/Dockerfile.ethereum | 4 - example.env | 2 + 11 files changed, 305 insertions(+), 159 deletions(-) create mode 100644 docker/eigenlayer/Dockerfile delete mode 100644 docker/eigenlayer/Dockerfile.eigenlayer delete mode 100644 docker/eigenlayer/counter_and_sig_check_deploy.sh delete mode 100644 docker/eigenlayer/get_bls_key.sh create mode 100644 docker/ethereum/Dockerfile delete mode 100644 docker/ethereum/Dockerfile.ethereum diff --git a/README.md b/README.md index 407c500..2f7bd3d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Relies on [BLS-middleware](https://github.com/BreadchainCoop/bls-middleware) ## Setup -2. Create a `.env` file in the root directory and add the following environment variables: +1. Create a `.env` file in the root directory and add the following environment variables: ``` cp example.env .env ``` @@ -54,7 +54,7 @@ Relies on [BLS-middleware](https://github.com/BreadchainCoop/bls-middleware) RUST_LOG=debug # Set Rust logging level ``` -3. Build and start the services: +2. Build and start the services: ``` # First, build the services with no cache docker-compose build --no-cache diff --git a/docker-compose.yml b/docker-compose.yml index 8ff2440..6dd08c8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,23 +1,26 @@ services: ethereum: platform: linux/amd64 - image: ghcr.io/breadchaincoop/ethereum:dev + build: + context: . + dockerfile: docker/ethereum/Dockerfile env_file: - .env ports: - "8545:8545" - + eigenlayer: platform: linux/amd64 - image: ghcr.io/breadchaincoop/eigenlayer:dev + build: + context: . + dockerfile: docker/eigenlayer/Dockerfile depends_on: - ethereum env_file: - .env volumes: - ./.nodes:/root/.nodes - - ./docker/eigenlayer/config.json:/bls-middleware/contracts/docker/eigenlayer/config.json - + signer: image: ghcr.io/layr-labs/cerberus:0.0.2 platform: linux/amd64 diff --git a/docker/eigenlayer/Dockerfile b/docker/eigenlayer/Dockerfile new file mode 100644 index 0000000..a474fe0 --- /dev/null +++ b/docker/eigenlayer/Dockerfile @@ -0,0 +1,51 @@ +# ============================================================================ +# Multi-stage Docker build for EigenLayer BLS Local Setup +# ============================================================================ + +# Go Builder Stage - Install Go tools +FROM golang:1.21 AS go-builder + +# Install EigenLayer CLI +RUN go install github.com/Layr-Labs/eigenlayer-cli/cmd/eigenlayer@v0.10.3 + +# Install gRPC tools +RUN go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest + +# Foundry Stage - Main application container +FROM ghcr.io/foundry-rs/foundry:stable + +# Switch to root user for package installation +USER root + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + lsof \ + jq \ + tmux \ + bash \ + && rm -rf /var/lib/apt/lists/* + +# Copy Go binaries from builder stage +COPY --from=go-builder /go/bin/eigenlayer /usr/local/bin/ +COPY --from=go-builder /go/bin/grpcurl /usr/local/bin/ + +# Clone and build BLS middleware contracts +RUN git clone --recurse-submodules https://github.com/BreadchainCoop/bls-middleware.git && \ + cd bls-middleware/contracts && \ + forge build + +# Set working directory to root (scripts handle navigation internally) +WORKDIR / + +# Copy and setup application scripts +COPY docker/eigenlayer/main.sh /main.sh +RUN chmod +x /main.sh + +COPY docker/eigenlayer/register.sh /register.sh +RUN chmod +x /register.sh + +COPY docker/eigenlayer/eject.sh /eject.sh +RUN chmod +x /eject.sh + +# Set entrypoint +ENTRYPOINT ["/main.sh"] diff --git a/docker/eigenlayer/Dockerfile.eigenlayer b/docker/eigenlayer/Dockerfile.eigenlayer deleted file mode 100644 index 1f177cc..0000000 --- a/docker/eigenlayer/Dockerfile.eigenlayer +++ /dev/null @@ -1,28 +0,0 @@ -# Go builder stage -FROM golang:1.21 AS go-builder -RUN go install github.com/Layr-Labs/eigenlayer-cli/cmd/eigenlayer@v0.10.3 -RUN go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest -# Final stage - -FROM ghcr.io/foundry-rs/foundry:latest -USER root -RUN apt update && apt install -y lsof jq tmux bash -COPY --from=go-builder /go/bin/eigenlayer /bin/ -COPY --from=go-builder /go/bin/grpcurl /bin/ -RUN git clone --recurse-submodules https://github.com/BreadchainCoop/bls-middleware.git -RUN cd bls-middleware/contracts && forge build -WORKDIR /bls-middleware -WORKDIR / - -COPY ./main.sh /main.sh -RUN chmod +x /main.sh -COPY ./register.sh /register.sh -RUN chmod +x /register.sh -COPY ./eject.sh /eject.sh -RUN chmod +x /eject.sh -COPY ./get_bls_key.sh /get_bls_key.sh -RUN chmod +x /get_bls_key.sh -COPY ./counter_and_sig_check_deploy.sh /counter_and_sig_check_deploy.sh -RUN chmod +x /counter_and_sig_check_deploy.sh - -ENTRYPOINT ["/main.sh"] diff --git a/docker/eigenlayer/counter_and_sig_check_deploy.sh b/docker/eigenlayer/counter_and_sig_check_deploy.sh deleted file mode 100644 index 83d9003..0000000 --- a/docker/eigenlayer/counter_and_sig_check_deploy.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash -set -Eeuo pipefail - -############################################################################### -# Prerequisites (export these before running or put them in a `.env` file) -# RPC_URL – JSON-RPC endpoint of the target chain -# PRIVATE_KEY / FOUNDRY_PRIVATE_KEY – deployer key -# REGISTRY_COORDINATOR_ADDRESS – address used by CounterScript -############################################################################### - -if [ -z "$RPC_URL" ]; then - echo "Error: RPC_URL is not set in the environment variables." - exit 1 -fi - -if [ -z "$PRIVATE_KEY" ] && [ -z "$FOUNDRY_PRIVATE_KEY" ]; then - echo "Error: Neither PRIVATE_KEY nor FOUNDRY_PRIVATE_KEY is set in the environment variables." - exit 1 -fi - -if [ -z "$REGISTRY_COORDINATOR_ADDRESS" ]; then - echo "Error: REGISTRY_COORDINATOR_ADDRESS is not set in the environment variables." - exit 1 -fi - -# Use FOUNDRY_PRIVATE_KEY if PRIVATE_KEY is not set -if [ -z "$PRIVATE_KEY" ]; then - PRIVATE_KEY="$FOUNDRY_PRIVATE_KEY" -fi - -############################################################################### -# 1. Build + deploy BLSSigCheckOperatorStateRetriever -############################################################################### -cd bls-middleware/contracts/lib/avs-commonware-counter - -forge script script/DeployBLSSigCheck.s.sol:DeployBLSSigCheckScript \ - --rpc-url "$RPC_URL" \ - --private-key "$PRIVATE_KEY" \ - --broadcast \ - > /dev/null 2>&1 -if [ $? -ne 0 ]; then - echo "Error: Failed to deploy BLSSigCheckOperatorStateRetriever"; exit 1 -fi -echo "BLSSigCheckOperatorStateRetriever deployed" - -############################################################################### -# 2. Deploy Counter (needs REGISTRY_COORDINATOR_ADDRESS env var) -############################################################################### -forge script script/Counter.s.sol:CounterScript \ - --rpc-url "$RPC_URL" \ - --private-key "$PRIVATE_KEY" \ - --broadcast \ - > /dev/null 2>&1 -if [ $? -ne 0 ]; then - echo "Error: Failed to deploy Counter"; exit 1 -fi -echo "Counter deployed" - -############################################################################### -# 3. Merge deployment JSONs -############################################################################### -chain_id=$(cast chain-id --rpc-url $RPC_URL) -if [ -f "script/deployments/bls-sig-check/$chain_id.json" ] && [ -f "script/deployments/counter/$chain_id.json" ]; then - # Read the deployment JSONs - bls_sig_check_json=$(cat "script/deployments/bls-sig-check/$chain_id.json") - counter_json=$(cat "script/deployments/counter/$chain_id.json") - - # Create temporary files in the current directory - echo "$bls_sig_check_json" > bls_sig_check.json - echo "$counter_json" > counter.json - - # Merge the JSONs with the existing avs_deploy.json - merged_json=$(jq -s '.[0] * .[1] * .[2]' ~/.nodes/avs_deploy.json counter.json bls_sig_check.json) - - # Save to both locations - echo "$merged_json" > ~/.nodes/avs_deploy.json - echo "$merged_json" > ../../avs_deploy.json - rm bls_sig_check.json counter.json -else - echo "Error: Could not find deployment JSONs for BLS sig checker or Counter" - exit 1 -fi - -echo "-----------------------------------------------------------------" -echo "Counter deploy and run complete" diff --git a/docker/eigenlayer/get_bls_key.sh b/docker/eigenlayer/get_bls_key.sh deleted file mode 100644 index 5e8c579..0000000 --- a/docker/eigenlayer/get_bls_key.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -if [ $# -ne 2 ]; then - echo "Usage: $0 " - exit 1 -fi - -PASSWORD="$1" -ACCOUNT="$2" -# Create a new tmux session -tmux new-session -d -s export_key - -# Send the export command -tmux send-keys -t export_key "eigenlayer keys export --key-type bls $ACCOUNT" C-m - -# Wait a bit and send "y" -sleep 1 -tmux send-keys -t export_key "y" C-m - -# Wait a bit and send password -sleep 1 -tmux send-keys -t export_key "$PASSWORD" C-m - -# Capture the output and format it -sleep 1 -tmux capture-pane -t export_key -S - -E - -p | grep -A1 "Private key:" | tr -d 'Private key: \n' - -# Kill the session -tmux kill-session -t export_key \ No newline at end of file diff --git a/docker/eigenlayer/main.sh b/docker/eigenlayer/main.sh index 9eb2c69..a7ba3a0 100644 --- a/docker/eigenlayer/main.sh +++ b/docker/eigenlayer/main.sh @@ -21,6 +21,32 @@ if [ -z "$RPC_URL" ]; then exit 1 fi +if [ -z "$ARRAY_SUMMATION_FACTORY_ADDRESS" ]; then + echo "Error: ARRAY_SUMMATION_FACTORY_ADDRESS is not set in the environment variables." + exit 1 +fi + +if [ -z "$PRIVATE_KEY" ] && [ -z "$FOUNDRY_PRIVATE_KEY" ]; then + echo "Error: Neither PRIVATE_KEY nor FOUNDRY_PRIVATE_KEY is set in the environment variables." + exit 1 +fi + +# Use FOUNDRY_PRIVATE_KEY if PRIVATE_KEY is not set +if [ -z "$PRIVATE_KEY" ]; then + PRIVATE_KEY="$FOUNDRY_PRIVATE_KEY" +fi + +# Set default values for ArraySummation deployment parameters +if [ -z "$ARRAY_SIZE" ]; then + ARRAY_SIZE=1000 +fi +if [ -z "$MAX_VALUE" ]; then + MAX_VALUE=10000 +fi +if [ -z "$SEED" ]; then + SEED=0 +fi + if [ "$ENVIRONMENT" = "TESTNET" ]; then if [ -z "$FUNDED_KEY" ]; then echo "Error: FUNDED_KEY is not set in the environment variables. This is required for testnet." @@ -77,16 +103,187 @@ cp script/deployments/incredible-squaring/$chain_id.json ~/.nodes/avs_deploy.jso cp script/deployments/incredible-squaring/$chain_id.json avs_deploy.json # Get the latest registry coordinator from deployment JSON -REGISTRY_COORDINATOR_ADDRESS=$(cat avs_deploy.json | jq -r '.addresses.registryCoordinator') +REGISTRY_COORDINATOR_ADDRESS=$(cat ~/.nodes/avs_deploy.json | jq -r '.addresses.registryCoordinator') if [ -z "$REGISTRY_COORDINATOR_ADDRESS" ] || [ "$REGISTRY_COORDINATOR_ADDRESS" = "null" ]; then echo "Error: Failed to get registry coordinator address from deployment JSON" exit 1 fi export REGISTRY_COORDINATOR_ADDRESS -echo "Deploying counter..." -cd / -/counter_and_sig_check_deploy.sh +############################################################################### +# Deploy BLS Signature Check +############################################################################### +echo "Deploying BLSSigCheckOperatorStateRetriever..." + +# Debug: Check if the directory exists and what's in it +echo "Checking bls-middleware directory structure..." +if [ ! -d "/bls-middleware" ]; then + echo "Error: /bls-middleware directory not found" + exit 1 +fi + +if [ ! -d "/bls-middleware/contracts" ]; then + echo "Error: /bls-middleware/contracts directory not found" + ls -la /bls-middleware/ + exit 1 +fi + +if [ ! -d "/bls-middleware/contracts/lib" ]; then + echo "Error: /bls-middleware/contracts/lib directory not found" + ls -la /bls-middleware/contracts/ + exit 1 +fi + +if [ ! -d "/bls-middleware/contracts/lib/avs-commonware-counter" ]; then + echo "Error: /bls-middleware/contracts/lib/avs-commonware-counter directory not found" + ls -la /bls-middleware/contracts/lib/ + exit 1 +fi + +cd /bls-middleware/contracts/lib/avs-commonware-counter +echo "Successfully changed to avs-commonware-counter directory" + +forge script script/DeployBLSSigCheck.s.sol:DeployBLSSigCheckScript \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" \ + --broadcast \ + > /dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "Error: Failed to deploy BLSSigCheckOperatorStateRetriever"; exit 1 +fi +echo "BLSSigCheckOperatorStateRetriever deployed" + +############################################################################### +# Deploy Counter +############################################################################### +echo "Deploying Counter..." + +forge script script/Counter.s.sol:CounterScript \ + --rpc-url "$RPC_URL" \ + --private-key "$PRIVATE_KEY" \ + --broadcast \ + > /dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "Error: Failed to deploy Counter"; exit 1 +fi +echo "Counter deployed" + +############################################################################### +# Deploy ArraySummation +############################################################################### +echo "Deploying ArraySummation..." + +# Get the AVS address and BLS sig check address from deployment JSONs +AVS_ADDRESS=$(cat ~/.nodes/avs_deploy.json | jq -r '.addresses.IncredibleSquaringServiceManager') +if [ -z "$AVS_ADDRESS" ] || [ "$AVS_ADDRESS" = "null" ]; then + echo "Error: Failed to get IncredibleSquaringServiceManager address from deployment JSON" + exit 1 +fi + +# Get BLS sig check address from the deployment +BLS_SIG_CHECK_ADDRESS=$(cat "script/deployments/bls-sig-check/$chain_id.json" | jq -r '.addresses.blsSigCheck') +if [ -z "$BLS_SIG_CHECK_ADDRESS" ] || [ "$BLS_SIG_CHECK_ADDRESS" = "null" ]; then + echo "Error: Failed to get BLS sig check address from deployment JSON" + exit 1 +fi + +echo "ArraySummation parameters:" +echo " AVS Address: $AVS_ADDRESS" +echo " BLS Sig Check: $BLS_SIG_CHECK_ADDRESS" +echo " Array Size: $ARRAY_SIZE" +echo " Max Value: $MAX_VALUE" +echo " Seed: $SEED" + +# Get the contract count before deployment +CONTRACT_COUNT_BEFORE=$(cast call $ARRAY_SUMMATION_FACTORY_ADDRESS \ + "getDeployedContractCount()(uint256)" \ + --rpc-url $RPC_URL) + +if [ $? -ne 0 ]; then + echo "Error: Failed to get deployed contract count" + exit 1 +fi + +echo "Contract count before deployment: $CONTRACT_COUNT_BEFORE" + +# Deploy ArraySummation using the factory +echo "Sending deployment transaction..." +TX_HASH=$(cast send $ARRAY_SUMMATION_FACTORY_ADDRESS \ + "deployArraySummation(address,address,uint256,uint256,uint256)" \ + $AVS_ADDRESS \ + $BLS_SIG_CHECK_ADDRESS \ + $ARRAY_SIZE \ + $MAX_VALUE \ + $SEED \ + --private-key $PRIVATE_KEY \ + --rpc-url $RPC_URL \ + --json | jq -r '.transactionHash') + +if [ $? -ne 0 ] || [ -z "$TX_HASH" ]; then + echo "Error: Failed to deploy ArraySummation contract" + exit 1 +fi + +echo "Transaction sent: $TX_HASH" + +# Wait for transaction to be mined +echo "Waiting for transaction to be mined..." +cast receipt $TX_HASH --rpc-url $RPC_URL > /dev/null 2>&1 + +if [ $? -ne 0 ]; then + echo "Error: Transaction failed or was not mined" + exit 1 +fi + +echo "Transaction confirmed!" + +# Get the deployed contract address by querying the factory at the expected index +ARRAY_SUMMATION_ADDRESS=$(cast call $ARRAY_SUMMATION_FACTORY_ADDRESS \ + "deployedContracts(uint256)(address)" \ + $CONTRACT_COUNT_BEFORE \ + --rpc-url $RPC_URL) + +if [ $? -ne 0 ] || [ -z "$ARRAY_SUMMATION_ADDRESS" ] || [ "$ARRAY_SUMMATION_ADDRESS" = "0x0000000000000000000000000000000000000000" ]; then + echo "Error: Failed to get deployed ArraySummation contract address" + exit 1 +fi + +echo "ArraySummation deployed at: $ARRAY_SUMMATION_ADDRESS" + +############################################################################### +# Merge deployment JSONs +############################################################################### +chain_id=$(cast chain-id --rpc-url $RPC_URL) +if [ -f "script/deployments/bls-sig-check/$chain_id.json" ] && [ -f "script/deployments/counter/$chain_id.json" ]; then + # Read the deployment JSONs + bls_sig_check_json=$(cat "script/deployments/bls-sig-check/$chain_id.json") + counter_json=$(cat "script/deployments/counter/$chain_id.json") + + # Create temporary files in the current directory + echo "$bls_sig_check_json" > bls_sig_check.json + echo "$counter_json" > counter.json + + # Merge the JSONs with the existing avs_deploy.json + merged_json=$(jq -s '.[0] * .[1] * .[2]' ~/.nodes/avs_deploy.json counter.json bls_sig_check.json) + + # Add ARRAY_SUMMATION_FACTORY_ADDRESS to the merged JSON + merged_json=$(echo "$merged_json" | jq --arg addr "$ARRAY_SUMMATION_FACTORY_ADDRESS" '.addresses.arraySummationFactory = $addr') + + # Add deployed ARRAY_SUMMATION_ADDRESS to the merged JSON + merged_json=$(echo "$merged_json" | jq --arg addr "$ARRAY_SUMMATION_ADDRESS" '.addresses.arraySummation = $addr') + + # Save to both locations + echo "$merged_json" > ~/.nodes/avs_deploy.json + echo "$merged_json" > ../../avs_deploy.json + rm bls_sig_check.json counter.json +else + echo "Error: Could not find deployment JSONs for BLS sig checker or Counter" + exit 1 +fi + +echo "-----------------------------------------------------------------" +echo "Counter deploy and run complete" +echo "-----------------------------------------------------------------" cd /bls-middleware/contracts forge script script/UAMPermissions.s.sol --rpc-url $RPC_URL --broadcast --private-key $PRIVATE_KEY > /dev/null 2>&1 @@ -99,7 +296,7 @@ if [ $? -ne 0 ]; then fi # Get stake registry address once -STAKE_REGISTRY=$(cat avs_deploy.json | jq -r '.addresses.stakeRegistry') +STAKE_REGISTRY=$(cat ~/.nodes/avs_deploy.json | jq -r '.addresses.stakeRegistry') if [ -z "$STAKE_REGISTRY" ] || [ "$STAKE_REGISTRY" = "null" ]; then echo "Error: Failed to get stake registry address from deployment JSON" exit 1 diff --git a/docker/eigenlayer/register.sh b/docker/eigenlayer/register.sh index 6ef5672..2a7bf4e 100644 --- a/docker/eigenlayer/register.sh +++ b/docker/eigenlayer/register.sh @@ -81,8 +81,30 @@ if [ $? -ne 0 ]; then echo "Error: Failed to create bls key for $new_account" exit 1 fi -private_bls_key=$(./get_bls_key.sh $password $new_account) -if [ $? -ne 0 ]; then + +# Extract BLS private key using tmux automation +# Create a new tmux session +tmux new-session -d -s export_key + +# Send the export command +tmux send-keys -t export_key "eigenlayer keys export --key-type bls $new_account" C-m + +# Wait a bit and send "y" +sleep 1 +tmux send-keys -t export_key "y" C-m + +# Wait a bit and send password +sleep 1 +tmux send-keys -t export_key "$password" C-m + +# Capture the output and format it +sleep 1 +private_bls_key=$(tmux capture-pane -t export_key -S - -E - -p | grep -A1 "Private key:" | tr -d 'Private key: \n') + +# Kill the session +tmux kill-session -t export_key + +if [ -z "$private_bls_key" ]; then echo "Error: Failed to get bls key for $new_account" exit 1 fi diff --git a/docker/ethereum/Dockerfile b/docker/ethereum/Dockerfile new file mode 100644 index 0000000..bac8116 --- /dev/null +++ b/docker/ethereum/Dockerfile @@ -0,0 +1,16 @@ +# ----------------------------------------------------------------------------- +# Dockerfile for Ethereum Anvil Node +# ----------------------------------------------------------------------------- + +# Use the stable version of the official Foundry image +FROM ghcr.io/foundry-rs/foundry:stable + +# Set the working directory inside the container +WORKDIR /ethereum + +# Start Anvil with custom options: +# --fork-url: The upstream Ethereum node to fork from (set via environment variable) +# --host: Listen on all interfaces (for Docker networking) +# --port: Expose Anvil on port 8545 +# --code-size-limit: Increase contract code size limit (useful for large contracts) +ENTRYPOINT anvil --fork-url $FORK_URL --host 0.0.0.0 --port 8545 --code-size-limit 65536 \ No newline at end of file diff --git a/docker/ethereum/Dockerfile.ethereum b/docker/ethereum/Dockerfile.ethereum deleted file mode 100644 index 002f529..0000000 --- a/docker/ethereum/Dockerfile.ethereum +++ /dev/null @@ -1,4 +0,0 @@ -FROM ghcr.io/foundry-rs/foundry -WORKDIR /ethereum - -ENTRYPOINT anvil --fork-url $FORK_URL --host 0.0.0.0 --port 8545 --code-size-limit 65536 \ No newline at end of file diff --git a/example.env b/example.env index c8ba3ef..6d3f0ba 100644 --- a/example.env +++ b/example.env @@ -6,6 +6,7 @@ #BLS_SIGNATURE_CHECKER_ADDRESS=0xb7ba8bbc36AA5684fC44D02aD666dF8E23BEEbF8 #OPERATOR_STATE_RETRIEVER_ADDRESS=0xD5D7fB4647cE79740E6e83819EFDf43fa74F8C31 #ALLOCATION_MANAGER_ADDRESS=0x948a420b8CC1d6BFd0B6087C2E7c344a2CD0bc39 +#ARRAY_SUMMATION_FACTORY_ADDRESS= # Holesky Configuration #DELEGATION_MANAGER_ADDRESS=0xA44151489861Fe9e3055d95adC98FbD462B948e7 @@ -15,6 +16,7 @@ #BLS_SIGNATURE_CHECKER_ADDRESS=0xca249215e082e17c12bb3c4881839a3f883e5c6b #OPERATOR_STATE_RETRIEVER_ADDRESS=0xB4baAfee917fb4449f5ec64804217bccE9f46C67 #ALLOCATION_MANAGER_ADDRESS=0x78469728304326CBc65f8f95FA756B0B73164462 +#ARRAY_SUMMATION_FACTORY_ADDRESS=0xF7ded769418Ec1Db4DA3bd2d47ab72ce2296A032 # Network Configuration # Refers to a live RPC that forms the basis of the simulated chain (Ethereum \ Holesky) From c1842c887ae116717f33c90eec8d303ccbd24504 Mon Sep 17 00:00:00 2001 From: bagelface Date: Thu, 4 Sep 2025 11:47:31 -0400 Subject: [PATCH 05/18] fix: use stable foundry version and mount config file as volume --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 6dd08c8..f731ab9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,7 @@ services: - .env volumes: - ./.nodes:/root/.nodes + - ./docker/eigenlayer/config.json:/bls-middleware/contracts/docker/eigenlayer/config.json signer: image: ghcr.io/layr-labs/cerberus:0.0.2 From 9fc717e0b42e3e76fde07f9dbe2ff322738cd019 Mon Sep 17 00:00:00 2001 From: bagelface Date: Thu, 4 Sep 2025 14:23:08 -0400 Subject: [PATCH 06/18] fix: make key extraction more reliable --- docker/eigenlayer/main.sh | 17 ++++++----------- docker/eigenlayer/register.sh | 22 ++++++++++------------ 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/docker/eigenlayer/main.sh b/docker/eigenlayer/main.sh index a7ba3a0..1910ce0 100644 --- a/docker/eigenlayer/main.sh +++ b/docker/eigenlayer/main.sh @@ -153,9 +153,7 @@ if [ $? -ne 0 ]; then fi echo "BLSSigCheckOperatorStateRetriever deployed" -############################################################################### # Deploy Counter -############################################################################### echo "Deploying Counter..." forge script script/Counter.s.sol:CounterScript \ @@ -168,9 +166,7 @@ if [ $? -ne 0 ]; then fi echo "Counter deployed" -############################################################################### # Deploy ArraySummation -############################################################################### echo "Deploying ArraySummation..." # Get the AVS address and BLS sig check address from deployment JSONs @@ -248,11 +244,10 @@ if [ $? -ne 0 ] || [ -z "$ARRAY_SUMMATION_ADDRESS" ] || [ "$ARRAY_SUMMATION_ADDR exit 1 fi -echo "ArraySummation deployed at: $ARRAY_SUMMATION_ADDRESS" +echo "ArraySummation deployed" +echo "Contract deployment and run complete" -############################################################################### # Merge deployment JSONs -############################################################################### chain_id=$(cast chain-id --rpc-url $RPC_URL) if [ -f "script/deployments/bls-sig-check/$chain_id.json" ] && [ -f "script/deployments/counter/$chain_id.json" ]; then # Read the deployment JSONs @@ -281,15 +276,14 @@ else exit 1 fi -echo "-----------------------------------------------------------------" -echo "Counter deploy and run complete" -echo "-----------------------------------------------------------------" - +# Setup middleware cd /bls-middleware/contracts + forge script script/UAMPermissions.s.sol --rpc-url $RPC_URL --broadcast --private-key $PRIVATE_KEY > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: Failed to run UAMPermissions script" fi + forge script script/SetupMiddleware.s.sol --rpc-url $RPC_URL --broadcast --private-key $PRIVATE_KEY > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: Failed to run SetupMiddleware script" @@ -302,6 +296,7 @@ if [ -z "$STAKE_REGISTRY" ] || [ "$STAKE_REGISTRY" = "null" ]; then exit 1 fi +# Register operators for i in $(seq 1 $num_accounts); do echo "Processing operator $i..." diff --git a/docker/eigenlayer/register.sh b/docker/eigenlayer/register.sh index 2a7bf4e..74969ae 100644 --- a/docker/eigenlayer/register.sh +++ b/docker/eigenlayer/register.sh @@ -70,17 +70,13 @@ ecdsa_keystore_path="${HOME}/.nodes/operator_keys/${new_account}.ecdsa.key.json" bls_keystore_path="${HOME}/.nodes/operator_keys/${new_account}.bls.key.json" password="Testacc1Testacc1" -echo $password | eigenlayer keys import --insecure --key-type ecdsa $new_account $PRIVATE_KEY > /dev/null 2>&1 -if [ $? -ne 0 ]; then - echo "Error: Failed to import ecdsa key for $new_account" - exit 1 -fi +# Import ECDSA key +echo $password | eigenlayer keys import --insecure --key-type ecdsa $new_account $PRIVATE_KEY + cp $HOME/.eigenlayer/operator_keys/${new_account}.ecdsa.key.json $HOME/.nodes/operator_keys/${new_account}.ecdsa.key.json -echo $password | eigenlayer keys create --key-type bls --insecure $new_account > /dev/null 2>&1 -if [ $? -ne 0 ]; then - echo "Error: Failed to create bls key for $new_account" - exit 1 -fi + +# Create BLS key +echo $password | eigenlayer keys create --key-type bls --insecure $new_account # Extract BLS private key using tmux automation # Create a new tmux session @@ -99,21 +95,23 @@ tmux send-keys -t export_key "$password" C-m # Capture the output and format it sleep 1 -private_bls_key=$(tmux capture-pane -t export_key -S - -E - -p | grep -A1 "Private key:" | tr -d 'Private key: \n') +private_bls_key=$(tmux capture-pane -t export_key -S - -E - -p 2>/dev/null | grep -A1 "Private key:" | tr -d 'Private key: \n') # Kill the session -tmux kill-session -t export_key +tmux kill-session -t export_key 2>/dev/null || true if [ -z "$private_bls_key" ]; then echo "Error: Failed to get bls key for $new_account" exit 1 fi + result=$(grpcurl -plaintext -d '{"privateKey": "'"$private_bls_key"'", "password": "'"$password"'"}' signer:50051 keymanager.v1.KeyManager/ImportKey | jq -r '.publicKey' | tr -d '\n') if [ $? -ne 0 ]; then echo "Error: Failed to import bls key for $new_account" echo $result exit 1 fi + echo -n $result > $HOME/.nodes/operator_keys/${new_account}.bls.identifier echo -n "{\"privateKey\":\"$private_bls_key\"}" > $HOME/.nodes/operator_keys/${new_account}.private.bls.key.json echo -n "{\"privateKey\":\"$PRIVATE_KEY\",\"publicKey\":\"$ADDRESS\"}" > $HOME/.nodes/operator_keys/${new_account}.private.ecdsa.key.json From 95101478d152c491a05264953e42177c45bb47e8 Mon Sep 17 00:00:00 2001 From: bagelface Date: Thu, 4 Sep 2025 14:37:11 -0400 Subject: [PATCH 07/18] fix: use more explicit names for array summation envars --- docker/eigenlayer/main.sh | 17 +++++++++++------ example.env | 5 +++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/docker/eigenlayer/main.sh b/docker/eigenlayer/main.sh index 1910ce0..7afc7dc 100644 --- a/docker/eigenlayer/main.sh +++ b/docker/eigenlayer/main.sh @@ -37,16 +37,21 @@ if [ -z "$PRIVATE_KEY" ]; then fi # Set default values for ArraySummation deployment parameters -if [ -z "$ARRAY_SIZE" ]; then - ARRAY_SIZE=1000 +if [ -z "$ARRAY_SUMMATION_ARRAY_SIZE" ]; then + ARRAY_SUMMATION_ARRAY_SIZE=1000 fi -if [ -z "$MAX_VALUE" ]; then - MAX_VALUE=10000 +if [ -z "$ARRAY_SUMMATION_MAX_VALUE" ]; then + ARRAY_SUMMATION_MAX_VALUE=10000 fi -if [ -z "$SEED" ]; then - SEED=0 +if [ -z "$ARRAY_SUMMATION_SEED" ]; then + ARRAY_SUMMATION_SEED=0 fi +# Use shorter variable names for convenience +ARRAY_SIZE=$ARRAY_SUMMATION_ARRAY_SIZE +MAX_VALUE=$ARRAY_SUMMATION_MAX_VALUE +SEED=$ARRAY_SUMMATION_SEED + if [ "$ENVIRONMENT" = "TESTNET" ]; then if [ -z "$FUNDED_KEY" ]; then echo "Error: FUNDED_KEY is not set in the environment variables. This is required for testnet." diff --git a/example.env b/example.env index 6d3f0ba..2098b92 100644 --- a/example.env +++ b/example.env @@ -28,6 +28,11 @@ RPC_URL=http://ethereum:8545 ENVIRONMENT=LOCAL # ENVIRONMENT=TESTNET +# Array Summation Configuration +ARRAY_SUMMATION_ARRAY_SIZE= +ARRAY_SUMMATION_MAX_VALUE= +ARRAY_SUMMATION_SEED= + # Operator Configuration PRIVATE_KEY=0xba35a33f95b443f059e794e4f440d22021400267fff05df4f4d3d2d8eee07215 FUNDED_KEY=0xba35a33f95b443f059e794e4f440d22021400267fff05df4f4d3d2d8eee07215 From 7f77454d944bab843d8eec4ba5f53d416e4636d2 Mon Sep 17 00:00:00 2001 From: bagelface Date: Fri, 5 Sep 2025 13:50:39 -0400 Subject: [PATCH 08/18] fix: remove array summation deploy and add steps to make key extraction more reliable --- docker/eigenlayer/main.sh | 107 ---------------------------------- docker/eigenlayer/register.sh | 58 ++++++++++++------ example.env | 9 +-- 3 files changed, 42 insertions(+), 132 deletions(-) diff --git a/docker/eigenlayer/main.sh b/docker/eigenlayer/main.sh index 7afc7dc..37a2330 100644 --- a/docker/eigenlayer/main.sh +++ b/docker/eigenlayer/main.sh @@ -21,11 +21,6 @@ if [ -z "$RPC_URL" ]; then exit 1 fi -if [ -z "$ARRAY_SUMMATION_FACTORY_ADDRESS" ]; then - echo "Error: ARRAY_SUMMATION_FACTORY_ADDRESS is not set in the environment variables." - exit 1 -fi - if [ -z "$PRIVATE_KEY" ] && [ -z "$FOUNDRY_PRIVATE_KEY" ]; then echo "Error: Neither PRIVATE_KEY nor FOUNDRY_PRIVATE_KEY is set in the environment variables." exit 1 @@ -36,22 +31,6 @@ if [ -z "$PRIVATE_KEY" ]; then PRIVATE_KEY="$FOUNDRY_PRIVATE_KEY" fi -# Set default values for ArraySummation deployment parameters -if [ -z "$ARRAY_SUMMATION_ARRAY_SIZE" ]; then - ARRAY_SUMMATION_ARRAY_SIZE=1000 -fi -if [ -z "$ARRAY_SUMMATION_MAX_VALUE" ]; then - ARRAY_SUMMATION_MAX_VALUE=10000 -fi -if [ -z "$ARRAY_SUMMATION_SEED" ]; then - ARRAY_SUMMATION_SEED=0 -fi - -# Use shorter variable names for convenience -ARRAY_SIZE=$ARRAY_SUMMATION_ARRAY_SIZE -MAX_VALUE=$ARRAY_SUMMATION_MAX_VALUE -SEED=$ARRAY_SUMMATION_SEED - if [ "$ENVIRONMENT" = "TESTNET" ]; then if [ -z "$FUNDED_KEY" ]; then echo "Error: FUNDED_KEY is not set in the environment variables. This is required for testnet." @@ -170,86 +149,6 @@ if [ $? -ne 0 ]; then echo "Error: Failed to deploy Counter"; exit 1 fi echo "Counter deployed" - -# Deploy ArraySummation -echo "Deploying ArraySummation..." - -# Get the AVS address and BLS sig check address from deployment JSONs -AVS_ADDRESS=$(cat ~/.nodes/avs_deploy.json | jq -r '.addresses.IncredibleSquaringServiceManager') -if [ -z "$AVS_ADDRESS" ] || [ "$AVS_ADDRESS" = "null" ]; then - echo "Error: Failed to get IncredibleSquaringServiceManager address from deployment JSON" - exit 1 -fi - -# Get BLS sig check address from the deployment -BLS_SIG_CHECK_ADDRESS=$(cat "script/deployments/bls-sig-check/$chain_id.json" | jq -r '.addresses.blsSigCheck') -if [ -z "$BLS_SIG_CHECK_ADDRESS" ] || [ "$BLS_SIG_CHECK_ADDRESS" = "null" ]; then - echo "Error: Failed to get BLS sig check address from deployment JSON" - exit 1 -fi - -echo "ArraySummation parameters:" -echo " AVS Address: $AVS_ADDRESS" -echo " BLS Sig Check: $BLS_SIG_CHECK_ADDRESS" -echo " Array Size: $ARRAY_SIZE" -echo " Max Value: $MAX_VALUE" -echo " Seed: $SEED" - -# Get the contract count before deployment -CONTRACT_COUNT_BEFORE=$(cast call $ARRAY_SUMMATION_FACTORY_ADDRESS \ - "getDeployedContractCount()(uint256)" \ - --rpc-url $RPC_URL) - -if [ $? -ne 0 ]; then - echo "Error: Failed to get deployed contract count" - exit 1 -fi - -echo "Contract count before deployment: $CONTRACT_COUNT_BEFORE" - -# Deploy ArraySummation using the factory -echo "Sending deployment transaction..." -TX_HASH=$(cast send $ARRAY_SUMMATION_FACTORY_ADDRESS \ - "deployArraySummation(address,address,uint256,uint256,uint256)" \ - $AVS_ADDRESS \ - $BLS_SIG_CHECK_ADDRESS \ - $ARRAY_SIZE \ - $MAX_VALUE \ - $SEED \ - --private-key $PRIVATE_KEY \ - --rpc-url $RPC_URL \ - --json | jq -r '.transactionHash') - -if [ $? -ne 0 ] || [ -z "$TX_HASH" ]; then - echo "Error: Failed to deploy ArraySummation contract" - exit 1 -fi - -echo "Transaction sent: $TX_HASH" - -# Wait for transaction to be mined -echo "Waiting for transaction to be mined..." -cast receipt $TX_HASH --rpc-url $RPC_URL > /dev/null 2>&1 - -if [ $? -ne 0 ]; then - echo "Error: Transaction failed or was not mined" - exit 1 -fi - -echo "Transaction confirmed!" - -# Get the deployed contract address by querying the factory at the expected index -ARRAY_SUMMATION_ADDRESS=$(cast call $ARRAY_SUMMATION_FACTORY_ADDRESS \ - "deployedContracts(uint256)(address)" \ - $CONTRACT_COUNT_BEFORE \ - --rpc-url $RPC_URL) - -if [ $? -ne 0 ] || [ -z "$ARRAY_SUMMATION_ADDRESS" ] || [ "$ARRAY_SUMMATION_ADDRESS" = "0x0000000000000000000000000000000000000000" ]; then - echo "Error: Failed to get deployed ArraySummation contract address" - exit 1 -fi - -echo "ArraySummation deployed" echo "Contract deployment and run complete" # Merge deployment JSONs @@ -266,12 +165,6 @@ if [ -f "script/deployments/bls-sig-check/$chain_id.json" ] && [ -f "script/depl # Merge the JSONs with the existing avs_deploy.json merged_json=$(jq -s '.[0] * .[1] * .[2]' ~/.nodes/avs_deploy.json counter.json bls_sig_check.json) - # Add ARRAY_SUMMATION_FACTORY_ADDRESS to the merged JSON - merged_json=$(echo "$merged_json" | jq --arg addr "$ARRAY_SUMMATION_FACTORY_ADDRESS" '.addresses.arraySummationFactory = $addr') - - # Add deployed ARRAY_SUMMATION_ADDRESS to the merged JSON - merged_json=$(echo "$merged_json" | jq --arg addr "$ARRAY_SUMMATION_ADDRESS" '.addresses.arraySummation = $addr') - # Save to both locations echo "$merged_json" > ~/.nodes/avs_deploy.json echo "$merged_json" > ../../avs_deploy.json diff --git a/docker/eigenlayer/register.sh b/docker/eigenlayer/register.sh index 74969ae..099916e 100644 --- a/docker/eigenlayer/register.sh +++ b/docker/eigenlayer/register.sh @@ -78,30 +78,54 @@ cp $HOME/.eigenlayer/operator_keys/${new_account}.ecdsa.key.json $HOME/.nodes/op # Create BLS key echo $password | eigenlayer keys create --key-type bls --insecure $new_account -# Extract BLS private key using tmux automation -# Create a new tmux session -tmux new-session -d -s export_key +# Extract BLS private key using direct export first, fallback to tmux +if command -v script >/dev/null 2>&1; then + script_output="/tmp/bls_export_$$.log" + echo -e "y\n$password" | script -q -c "timeout 10 eigenlayer keys export --key-type bls $new_account" "$script_output" >/dev/null 2>&1 -# Send the export command -tmux send-keys -t export_key "eigenlayer keys export --key-type bls $new_account" C-m + if [ -f "$script_output" ]; then + private_bls_key=$(cat "$script_output" | grep -E '[0-9a-fA-F]{64,}' | head -1 | tr -d '[:space:]') + fi + rm -f "$script_output" +fi + +# Fallback to tmux method if direct export failed +if [ -z "$private_bls_key" ]; then + # Create a new tmux session + tmux new-session -d -s export_key -# Wait a bit and send "y" -sleep 1 -tmux send-keys -t export_key "y" C-m + # Send the export command + tmux send-keys -t export_key "eigenlayer keys export --key-type bls $new_account" C-m -# Wait a bit and send password -sleep 1 -tmux send-keys -t export_key "$password" C-m + # Wait a bit and send "y" + sleep 1 + tmux send-keys -t export_key "y" C-m -# Capture the output and format it -sleep 1 -private_bls_key=$(tmux capture-pane -t export_key -S - -E - -p 2>/dev/null | grep -A1 "Private key:" | tr -d 'Private key: \n') + # Wait a bit and send password + sleep 1 + tmux send-keys -t export_key "$password" C-m +fi -# Kill the session -tmux kill-session -t export_key 2>/dev/null || true +# Capture the output and format it (only if using tmux method) +if [ -z "$private_bls_key" ]; then + sleep 3 # Increased wait time for key output + tmux_output=$(tmux capture-pane -t export_key -S - -E - -p 2>/dev/null) + private_bls_key=$(echo "$tmux_output" | grep -A 5 "Private key:" | grep -v "Private key:" | grep -E '^[0-9a-fA-F]+$' | head -1 | tr -d '[:space:]') + + # Also try alternative patterns in case the output format is different + if [ -z "$private_bls_key" ]; then + private_bls_key=$(echo "$tmux_output" | grep -E '[0-9a-fA-F]{64,}' | head -1 | tr -d '[:space:]') + fi + + + # Kill the session + tmux kill-session -t export_key 2>/dev/null || true +fi if [ -z "$private_bls_key" ]; then - echo "Error: Failed to get bls key for $new_account" + echo "Error: Failed to extract BLS private key for $new_account" + echo "BLS key file exists at: $HOME/.eigenlayer/operator_keys/${new_account}.bls.key.json" + echo "Try running the container again or check the eigenlayer CLI version" exit 1 fi diff --git a/example.env b/example.env index 2098b92..076bf12 100644 --- a/example.env +++ b/example.env @@ -6,7 +6,6 @@ #BLS_SIGNATURE_CHECKER_ADDRESS=0xb7ba8bbc36AA5684fC44D02aD666dF8E23BEEbF8 #OPERATOR_STATE_RETRIEVER_ADDRESS=0xD5D7fB4647cE79740E6e83819EFDf43fa74F8C31 #ALLOCATION_MANAGER_ADDRESS=0x948a420b8CC1d6BFd0B6087C2E7c344a2CD0bc39 -#ARRAY_SUMMATION_FACTORY_ADDRESS= # Holesky Configuration #DELEGATION_MANAGER_ADDRESS=0xA44151489861Fe9e3055d95adC98FbD462B948e7 @@ -16,7 +15,6 @@ #BLS_SIGNATURE_CHECKER_ADDRESS=0xca249215e082e17c12bb3c4881839a3f883e5c6b #OPERATOR_STATE_RETRIEVER_ADDRESS=0xB4baAfee917fb4449f5ec64804217bccE9f46C67 #ALLOCATION_MANAGER_ADDRESS=0x78469728304326CBc65f8f95FA756B0B73164462 -#ARRAY_SUMMATION_FACTORY_ADDRESS=0xF7ded769418Ec1Db4DA3bd2d47ab72ce2296A032 # Network Configuration # Refers to a live RPC that forms the basis of the simulated chain (Ethereum \ Holesky) @@ -28,13 +26,8 @@ RPC_URL=http://ethereum:8545 ENVIRONMENT=LOCAL # ENVIRONMENT=TESTNET -# Array Summation Configuration -ARRAY_SUMMATION_ARRAY_SIZE= -ARRAY_SUMMATION_MAX_VALUE= -ARRAY_SUMMATION_SEED= - # Operator Configuration -PRIVATE_KEY=0xba35a33f95b443f059e794e4f440d22021400267fff05df4f4d3d2d8eee07215 +PRIVATE_KEY=0xba35a33f95b443f059e794e4f440d22021400267fff05df4f4d3d2d8eee07215 FUNDED_KEY=0xba35a33f95b443f059e794e4f440d22021400267fff05df4f4d3d2d8eee07215 # These keys are the default anvil private key #1 TEST_ACCOUNTS=3 From afaabc0b1c61bdf8faa76cf73b96b1dca6139707 Mon Sep 17 00:00:00 2001 From: "bagelface.eth" <87501783+bagelface@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:56:49 -0400 Subject: [PATCH 09/18] Nothing commit to force Docker image build action From b1dab70db46669bb59097b3977924aa004fc47fa Mon Sep 17 00:00:00 2001 From: "bagelface.eth" <87501783+bagelface@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:57:57 -0400 Subject: [PATCH 10/18] Nothing update to force Docker build action --- docker/eigenlayer/eject.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/eigenlayer/eject.sh b/docker/eigenlayer/eject.sh index 2dd02fa..37bc2a7 100644 --- a/docker/eigenlayer/eject.sh +++ b/docker/eigenlayer/eject.sh @@ -1,4 +1,5 @@ #!/bin/sh + if [ -z "$REGISTRY_COORDINATOR_ADDRESS" ]; then echo "Error: REGISTRY_COORDINATOR_ADDRESS is not set in the environment variables." exit 1 From 8c5a9a983ec3e9c5aead305424a910aacbb8f583 Mon Sep 17 00:00:00 2001 From: bagelface Date: Fri, 5 Sep 2025 17:01:09 -0400 Subject: [PATCH 11/18] fix: reference correct Dockerfile name --- .github/workflows/docker-build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 1a8cbe5..dda8106 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -71,7 +71,7 @@ jobs: --label breadchaincoop.eigenlayer.image.source="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ -t "${IMAGE}:${CHANNEL_TAG}" \ -t "${IMAGE}:${CHANNEL_TAG}-${SHORT_SHA}" \ - -f docker/eigenlayer/Dockerfile.eigenlayer \ + -f docker/eigenlayer/Dockerfile \ docker/eigenlayer - name: Push eigenlayer tags @@ -96,7 +96,7 @@ jobs: --label breadchaincoop.ethereum.image.source="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \ -t "${IMAGE}:${CHANNEL_TAG}" \ -t "${IMAGE}:${CHANNEL_TAG}-${SHORT_SHA}" \ - -f docker/ethereum/Dockerfile.ethereum \ + -f docker/ethereum/Dockerfile \ . - name: Push ethereum tags From 74c1b1665b5546e26444cf8c6cc6d05490bc7bac Mon Sep 17 00:00:00 2001 From: "bagelface.eth" <87501783+bagelface@users.noreply.github.com> Date: Fri, 5 Sep 2025 17:04:44 -0400 Subject: [PATCH 12/18] Add workflow path to paths that will trigger run --- .github/workflows/docker-build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index dda8106..6702280 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -11,6 +11,7 @@ on: - dev - staging paths: + - '.github/workflows/**' - 'docker/eigenlayer/**' - 'docker/ethereum/**' workflow_dispatch: From d9a55e65444c1a569f8dd1b1d76c2213cc72d91c Mon Sep 17 00:00:00 2001 From: bagelface Date: Fri, 5 Sep 2025 17:39:30 -0400 Subject: [PATCH 13/18] build: change context of build command --- .github/workflows/docker-build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 6702280..1e59067 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -17,7 +17,7 @@ on: workflow_dispatch: jobs: - build-images: + build-images: runs-on: ubuntu-latest steps: @@ -73,7 +73,7 @@ jobs: -t "${IMAGE}:${CHANNEL_TAG}" \ -t "${IMAGE}:${CHANNEL_TAG}-${SHORT_SHA}" \ -f docker/eigenlayer/Dockerfile \ - docker/eigenlayer + . - name: Push eigenlayer tags if: steps.changes.outputs.eigenlayer == 'true' From 86751f19d1f71b1201b40d3887f69e1aaab5c4de Mon Sep 17 00:00:00 2001 From: bagelface Date: Mon, 8 Sep 2025 11:49:12 -0400 Subject: [PATCH 14/18] fix: add retry logic to increase reliability --- docker/eigenlayer/register.sh | 78 ++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/docker/eigenlayer/register.sh b/docker/eigenlayer/register.sh index 099916e..13164fc 100644 --- a/docker/eigenlayer/register.sh +++ b/docker/eigenlayer/register.sh @@ -78,49 +78,51 @@ cp $HOME/.eigenlayer/operator_keys/${new_account}.ecdsa.key.json $HOME/.nodes/op # Create BLS key echo $password | eigenlayer keys create --key-type bls --insecure $new_account -# Extract BLS private key using direct export first, fallback to tmux -if command -v script >/dev/null 2>&1; then - script_output="/tmp/bls_export_$$.log" - echo -e "y\n$password" | script -q -c "timeout 10 eigenlayer keys export --key-type bls $new_account" "$script_output" >/dev/null 2>&1 - - if [ -f "$script_output" ]; then - private_bls_key=$(cat "$script_output" | grep -E '[0-9a-fA-F]{64,}' | head -1 | tr -d '[:space:]') +# Extract BLS private key with retries: try non-interactive first, then interactive via tmux +private_bls_key="" +attempt=1 +max_attempts=5 +while [ -z "$private_bls_key" ] && [ $attempt -le $max_attempts ]; do + # Try non-interactive export using `script` if available + if command -v script >/dev/null 2>&1; then + script_output="/tmp/bls_export_$$.$attempt.log" + printf "y\n%s\n" "$password" | script -q -c "timeout 15 eigenlayer keys export --key-type bls $new_account" "$script_output" >/dev/null 2>&1 + if [ -f "$script_output" ]; then + private_bls_key=$(grep -Eo '[0-9a-fA-F]{64,}' "$script_output" | head -1 | tr -d '[:space:]') + rm -f "$script_output" + fi fi - rm -f "$script_output" -fi - -# Fallback to tmux method if direct export failed -if [ -z "$private_bls_key" ]; then - # Create a new tmux session - tmux new-session -d -s export_key - - # Send the export command - tmux send-keys -t export_key "eigenlayer keys export --key-type bls $new_account" C-m - # Wait a bit and send "y" - sleep 1 - tmux send-keys -t export_key "y" C-m - - # Wait a bit and send password - sleep 1 - tmux send-keys -t export_key "$password" C-m -fi - -# Capture the output and format it (only if using tmux method) -if [ -z "$private_bls_key" ]; then - sleep 3 # Increased wait time for key output - tmux_output=$(tmux capture-pane -t export_key -S - -E - -p 2>/dev/null) - private_bls_key=$(echo "$tmux_output" | grep -A 5 "Private key:" | grep -v "Private key:" | grep -E '^[0-9a-fA-F]+$' | head -1 | tr -d '[:space:]') - - # Also try alternative patterns in case the output format is different + # If still not found, fall back to tmux-based interactive export if [ -z "$private_bls_key" ]; then - private_bls_key=$(echo "$tmux_output" | grep -E '[0-9a-fA-F]{64,}' | head -1 | tr -d '[:space:]') + tmux has-session -t export_key 2>/dev/null && tmux kill-session -t export_key >/dev/null 2>&1 + tmux new-session -d -s export_key + tmux send-keys -t export_key "eigenlayer keys export --key-type bls $new_account" C-m + sleep 1 + tmux send-keys -t export_key "y" C-m + sleep 1 + tmux send-keys -t export_key "$password" C-m + + # Poll for output with incremental waits + waited=0 + while [ $waited -lt 12 ] && [ -z "$private_bls_key" ]; do + sleep 2 + waited=$((waited + 2)) + tmux_output=$(tmux capture-pane -t export_key -S - -E - -p 2>/dev/null) + private_bls_key=$(printf "%s\n" "$tmux_output" | awk '/Private key:/{getline; print; exit}' | tr -d '[:space:]') + if [ -z "$private_bls_key" ]; then + private_bls_key=$(printf "%s\n" "$tmux_output" | grep -Eo '[0-9a-fA-F]{64,}' | head -1 | tr -d '[:space:]') + fi + done + + tmux kill-session -t export_key 2>/dev/null || true fi - - # Kill the session - tmux kill-session -t export_key 2>/dev/null || true -fi + if [ -z "$private_bls_key" ]; then + attempt=$((attempt + 1)) + sleep 2 + fi +done if [ -z "$private_bls_key" ]; then echo "Error: Failed to extract BLS private key for $new_account" From df5c5bedb02863f1c86e5d5a0255a24f98728cea Mon Sep 17 00:00:00 2001 From: bagelface Date: Mon, 8 Sep 2025 13:03:43 -0400 Subject: [PATCH 15/18] fix: add additional loggin messages for clearer idea of where script is at --- docker/eigenlayer/register.sh | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/docker/eigenlayer/register.sh b/docker/eigenlayer/register.sh index 13164fc..82bd427 100644 --- a/docker/eigenlayer/register.sh +++ b/docker/eigenlayer/register.sh @@ -16,16 +16,20 @@ if [ -z "$RPC_URL" ]; then exit 1 fi +echo "[register] Creating new ECDSA account..." ACCOUNT_INFO=$(cast wallet new --json) PRIVATE_KEY=$(echo "$ACCOUNT_INFO" | jq -r '.[0].private_key') ADDRESS=$(echo "$ACCOUNT_INFO" | jq -r '.[0].address') +echo "[register] New account: $ADDRESS" if [ "$ENVIRONMENT" = "TESTNET" ]; then + echo "[register] Funding $ADDRESS on TESTNET..." cast s $ADDRESS --value 500000000000000000 --private-key "$FUNDED_KEY" -r "$RPC_URL" > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: Failed to give operator $index balance" exit 1 fi else + echo "[register] Setting local balance for $ADDRESS..." cast rpc anvil_setBalance $ADDRESS 0x10000000000000000000 --rpc-url $RPC_URL > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: Failed to set balance for $ADDRESS" @@ -35,21 +39,25 @@ if [ "$ENVIRONMENT" = "TESTNET" ]; then MINT_FUNCTION="submit(address _referral)" +echo "[register] Minting LST via $LST_CONTRACT_ADDRESS..." cast send $LST_CONTRACT_ADDRESS "$MINT_FUNCTION" $ADDRESS "0x0000000000000000000000000000000000000000" --private-key $PRIVATE_KEY --value 10000000000000000 --rpc-url $RPC_URL > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: Failed to mint LST for $ADDRESS" exit 1 fi +echo "[register] Approving LST for strategy manager $STRATEGY_MANAGER_ADDRESS..." cast send $LST_CONTRACT_ADDRESS "approve(address,uint256)" $STRATEGY_MANAGER_ADDRESS 1000000000000000000000000 --private-key $PRIVATE_KEY --rpc-url $RPC_URL > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: Failed to approve LST for $STRATEGY_MANAGER_ADDRESS" exit 1 fi +echo "[register] Depositing into strategy $LST_STRATEGY_ADDRESS via $STRATEGY_MANAGER_ADDRESS..." cast send $STRATEGY_MANAGER_ADDRESS "depositIntoStrategy(address,address,uint256)" $LST_STRATEGY_ADDRESS $LST_CONTRACT_ADDRESS 10000000000000000 --private-key $PRIVATE_KEY --rpc-url $RPC_URL > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: Failed to deposit into strategy for $LST_STRATEGY_ADDRESS" exit 1 fi +echo "[register] Registering as operator at $DELEGATION_MANAGER_ADDRESS..." cast send $DELEGATION_MANAGER_ADDRESS "registerAsOperator(address,uint32,string)" "$ADDRESS" "1" "foo.bar" --private-key $PRIVATE_KEY --rpc-url $RPC_URL > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Error: Failed to register as operator for $DELEGATION_MANAGER_ADDRESS" @@ -70,22 +78,25 @@ ecdsa_keystore_path="${HOME}/.nodes/operator_keys/${new_account}.ecdsa.key.json" bls_keystore_path="${HOME}/.nodes/operator_keys/${new_account}.bls.key.json" password="Testacc1Testacc1" -# Import ECDSA key +echo "[register] Importing ECDSA key for $new_account..." echo $password | eigenlayer keys import --insecure --key-type ecdsa $new_account $PRIVATE_KEY cp $HOME/.eigenlayer/operator_keys/${new_account}.ecdsa.key.json $HOME/.nodes/operator_keys/${new_account}.ecdsa.key.json -# Create BLS key +echo "[register] Creating BLS key for $new_account..." echo $password | eigenlayer keys create --key-type bls --insecure $new_account +echo "[register] Exporting BLS private key (with retries)..." # Extract BLS private key with retries: try non-interactive first, then interactive via tmux private_bls_key="" attempt=1 max_attempts=5 while [ -z "$private_bls_key" ] && [ $attempt -le $max_attempts ]; do + echo "[register] BLS export attempt $attempt of $max_attempts" # Try non-interactive export using `script` if available if command -v script >/dev/null 2>&1; then script_output="/tmp/bls_export_$$.$attempt.log" + echo "[register] Trying non-interactive export via script..." printf "y\n%s\n" "$password" | script -q -c "timeout 15 eigenlayer keys export --key-type bls $new_account" "$script_output" >/dev/null 2>&1 if [ -f "$script_output" ]; then private_bls_key=$(grep -Eo '[0-9a-fA-F]{64,}' "$script_output" | head -1 | tr -d '[:space:]') @@ -95,6 +106,7 @@ while [ -z "$private_bls_key" ] && [ $attempt -le $max_attempts ]; do # If still not found, fall back to tmux-based interactive export if [ -z "$private_bls_key" ]; then + echo "[register] Falling back to tmux-based export..." tmux has-session -t export_key 2>/dev/null && tmux kill-session -t export_key >/dev/null 2>&1 tmux new-session -d -s export_key tmux send-keys -t export_key "eigenlayer keys export --key-type bls $new_account" C-m @@ -119,6 +131,7 @@ while [ -z "$private_bls_key" ] && [ $attempt -le $max_attempts ]; do fi if [ -z "$private_bls_key" ]; then + echo "[register] Export attempt $attempt failed; retrying..." attempt=$((attempt + 1)) sleep 2 fi @@ -134,7 +147,7 @@ fi result=$(grpcurl -plaintext -d '{"privateKey": "'"$private_bls_key"'", "password": "'"$password"'"}' signer:50051 keymanager.v1.KeyManager/ImportKey | jq -r '.publicKey' | tr -d '\n') if [ $? -ne 0 ]; then echo "Error: Failed to import bls key for $new_account" - echo $result + echo "$result" exit 1 fi From efd0e0900d5838cc95079c34b9f42fe84328ce93 Mon Sep 17 00:00:00 2001 From: bagelface Date: Tue, 9 Sep 2025 14:27:51 -0400 Subject: [PATCH 16/18] fix: remove non-interactive command since it never works --- docker/eigenlayer/register.sh | 60 +++++++++++++++-------------------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/docker/eigenlayer/register.sh b/docker/eigenlayer/register.sh index 82bd427..9f0baf5 100644 --- a/docker/eigenlayer/register.sh +++ b/docker/eigenlayer/register.sh @@ -87,48 +87,38 @@ echo "[register] Creating BLS key for $new_account..." echo $password | eigenlayer keys create --key-type bls --insecure $new_account echo "[register] Exporting BLS private key (with retries)..." -# Extract BLS private key with retries: try non-interactive first, then interactive via tmux +# Extract BLS private key using tmux-based interactive export with retries private_bls_key="" attempt=1 max_attempts=5 while [ -z "$private_bls_key" ] && [ $attempt -le $max_attempts ]; do echo "[register] BLS export attempt $attempt of $max_attempts" - # Try non-interactive export using `script` if available - if command -v script >/dev/null 2>&1; then - script_output="/tmp/bls_export_$$.$attempt.log" - echo "[register] Trying non-interactive export via script..." - printf "y\n%s\n" "$password" | script -q -c "timeout 15 eigenlayer keys export --key-type bls $new_account" "$script_output" >/dev/null 2>&1 - if [ -f "$script_output" ]; then - private_bls_key=$(grep -Eo '[0-9a-fA-F]{64,}' "$script_output" | head -1 | tr -d '[:space:]') - rm -f "$script_output" + + # Clean up any existing tmux session + tmux has-session -t export_key 2>/dev/null && tmux kill-session -t export_key >/dev/null 2>&1 + + # Create new tmux session and run export command + tmux new-session -d -s export_key + tmux send-keys -t export_key "eigenlayer keys export --key-type bls $new_account" C-m + sleep 1 + tmux send-keys -t export_key "y" C-m + sleep 1 + tmux send-keys -t export_key "$password" C-m + + # Poll for output with incremental waits + waited=0 + while [ $waited -lt 12 ] && [ -z "$private_bls_key" ]; do + sleep 2 + waited=$((waited + 2)) + tmux_output=$(tmux capture-pane -t export_key -S - -E - -p 2>/dev/null) + private_bls_key=$(printf "%s\n" "$tmux_output" | awk '/Private key:/{getline; print; exit}' | tr -d '[:space:]') + if [ -z "$private_bls_key" ]; then + private_bls_key=$(printf "%s\n" "$tmux_output" | grep -Eo '[0-9a-fA-F]{64,}' | head -1 | tr -d '[:space:]') fi - fi + done - # If still not found, fall back to tmux-based interactive export - if [ -z "$private_bls_key" ]; then - echo "[register] Falling back to tmux-based export..." - tmux has-session -t export_key 2>/dev/null && tmux kill-session -t export_key >/dev/null 2>&1 - tmux new-session -d -s export_key - tmux send-keys -t export_key "eigenlayer keys export --key-type bls $new_account" C-m - sleep 1 - tmux send-keys -t export_key "y" C-m - sleep 1 - tmux send-keys -t export_key "$password" C-m - - # Poll for output with incremental waits - waited=0 - while [ $waited -lt 12 ] && [ -z "$private_bls_key" ]; do - sleep 2 - waited=$((waited + 2)) - tmux_output=$(tmux capture-pane -t export_key -S - -E - -p 2>/dev/null) - private_bls_key=$(printf "%s\n" "$tmux_output" | awk '/Private key:/{getline; print; exit}' | tr -d '[:space:]') - if [ -z "$private_bls_key" ]; then - private_bls_key=$(printf "%s\n" "$tmux_output" | grep -Eo '[0-9a-fA-F]{64,}' | head -1 | tr -d '[:space:]') - fi - done - - tmux kill-session -t export_key 2>/dev/null || true - fi + # Clean up tmux session + tmux kill-session -t export_key 2>/dev/null || true if [ -z "$private_bls_key" ]; then echo "[register] Export attempt $attempt failed; retrying..." From 27e25683433f9eb6d55cbb04b8f7174668f5803e Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Mon, 15 Sep 2025 21:08:34 -0400 Subject: [PATCH 17/18] fix: make eigenlayer container exit on completion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove infinite loop at the end of main.sh to allow container to exit normally when script finishes executing. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- docker/eigenlayer/main.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docker/eigenlayer/main.sh b/docker/eigenlayer/main.sh index 37a2330..c93da05 100644 --- a/docker/eigenlayer/main.sh +++ b/docker/eigenlayer/main.sh @@ -250,6 +250,4 @@ for i in $(seq 1 $num_accounts); do echo "Operator $i weight in quorum 0: $WEIGHT" done -# Keep container open for debugging -echo "Script execution finished. Keeping container open..." -while true; do sleep 1; done +echo "Script execution finished. Container will now exit." From dc59cc83e9bd011896e77d8d1c91e53d76b4f878 Mon Sep 17 00:00:00 2001 From: Ron Turetzky Date: Mon, 15 Sep 2025 21:13:07 -0400 Subject: [PATCH 18/18] feat: build test Docker images for PRs to dev branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add pull_request trigger for dev branch PRs - Generate PR-specific tags using branch names (pr-) - Add job summary output showing image tags for PR builds - Sanitize branch names for use as Docker tags 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .github/workflows/docker-build.yaml | 41 ++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 1e59067..52b73e2 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -14,6 +14,13 @@ on: - '.github/workflows/**' - 'docker/eigenlayer/**' - 'docker/ethereum/**' + pull_request: + branches: + - dev + paths: + - '.github/workflows/**' + - 'docker/eigenlayer/**' + - 'docker/ethereum/**' workflow_dispatch: jobs: @@ -31,13 +38,21 @@ jobs: OWNER_LOWER="$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]')" SHORT_SHA="$(echo "${GITHUB_SHA}" | cut -c1-7)" - # channel tag from branch - case "${GITHUB_REF_NAME}" in - main) CHANNEL_TAG="latest" ;; - dev) CHANNEL_TAG="dev" ;; - staging) CHANNEL_TAG="staging" ;; - *) echo "Unsupported branch: ${GITHUB_REF_NAME}"; exit 1 ;; - esac + # Determine if this is a pull request + if [ "${{ github.event_name }}" = "pull_request" ]; then + # For PRs, use the branch name as the tag + BRANCH_NAME="${{ github.head_ref }}" + # Sanitize branch name for use as Docker tag (replace / with -) + CHANNEL_TAG="pr-$(echo "${BRANCH_NAME}" | sed 's/[^a-zA-Z0-9._-]/-/g')" + else + # For pushes, use channel tag from branch + case "${GITHUB_REF_NAME}" in + main) CHANNEL_TAG="latest" ;; + dev) CHANNEL_TAG="dev" ;; + staging) CHANNEL_TAG="staging" ;; + *) echo "Unsupported branch: ${GITHUB_REF_NAME}"; exit 1 ;; + esac + fi echo "OWNER_LOWER=${OWNER_LOWER}" >> "$GITHUB_ENV" echo "SHORT_SHA=${SHORT_SHA}" >> "$GITHUB_ENV" @@ -60,6 +75,18 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Output image info for PR + if: github.event_name == 'pull_request' + shell: sh + run: | + echo "## Docker Images for this PR" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "Images will be built with the following tags:" >> $GITHUB_STEP_SUMMARY + echo "- \`ghcr.io/${OWNER_LOWER}/eigenlayer:${CHANNEL_TAG}\`" >> $GITHUB_STEP_SUMMARY + echo "- \`ghcr.io/${OWNER_LOWER}/eigenlayer:${CHANNEL_TAG}-${SHORT_SHA}\`" >> $GITHUB_STEP_SUMMARY + echo "- \`ghcr.io/${OWNER_LOWER}/ethereum:${CHANNEL_TAG}\`" >> $GITHUB_STEP_SUMMARY + echo "- \`ghcr.io/${OWNER_LOWER}/ethereum:${CHANNEL_TAG}-${SHORT_SHA}\`" >> $GITHUB_STEP_SUMMARY + # ---------- Eigenlayer ---------- - name: Build eigenlayer (multi-tag) if: steps.changes.outputs.eigenlayer == 'true'