From 0c48b04b4fd859ccb0a80a41d07caf97e1ce19c9 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Fri, 8 Aug 2025 05:29:18 +0000 Subject: [PATCH 01/31] a working script without args --- espresso/docker-compose.yml | 49 ++++++++++++++++++++++++++++++ espresso/scripts/prepare-allocs.sh | 2 +- espresso/scripts/reshape-allocs.jq | 1 - 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index f1d540aeded..3a899fd8089 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -409,6 +409,55 @@ services: - --max-channel-duration=1 - --target-num-frames=1 + # op-batcher-tee: + # build: + # context: ../ + # dockerfile: espresso/docker/op-stack/Dockerfile + # target: op-batcher-target + # image: optimism-espresso-integration/op-batcher-enclave:latest + # # It is not necessary to specify all dependencies, but a good practice. + # depends_on: + # l1-geth: + # condition: service_healthy + # op-geth: + # condition: service_started + # op-node-sequencer: + # condition: service_started + # espresso-dev-node: + # condition: service_started + # l2-genesis: + # condition: service_completed_successfully + # environment: + # L1_RPC: http://l1-geth:${L1_HTTP_PORT} + # OP_BATCHER_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT} + # OP_BATCHER_L2_ETH_RPC: http://op-geth:${OP_HTTP_PORT} + # OP_BATCHER_ROLLUP_RPC: http://op-node-sequencer:${ROLLUP_PORT} + # OP_BATCHER_ESPRESSO_URL: http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT},http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT} + # BATCH_INBOX_ADDRESS: ${BATCH_INBOX_ADDRESS:-0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9} + # BATCH_AUTHENTICATOR_ADDRESS: ${BATCH_AUTHENTICATOR_ADDRESS:-0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9} + # ESPRESSO_TEE_VERIFIER_ADDRESS: ${ESPRESSO_TEE_VERIFIER_ADDRESS:-0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0} + # ESPRESSO_RUN_ENCLAVE_TESTS: "true" + # devices: + # - /dev/nitro_enclaves:/dev/nitro_enclaves + # volumes: + # - ../packages/contracts-bedrock/lib/superchain-registry/ops/testdata/monorepo:/config + # - /var/run/docker.sock:/var/run/docker.sock + # deploy: + # resources: + # reservations: + # memory: 4096M + # cpus: '2' + # privileged: true # Required for enclave access + # command: + # - op-batcher + # - --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797 + # - --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 # Default value for testing + # - --mnemonic=test test test test test test test test test test test junk # Arbitrary value for testing + # - --hd-path=m/44'/60'/0'/0/0 # Arbitrary value for testing + # - --throttle-threshold=0 + # - --max-channel-duration=1 + # - --target-num-frames=1 + op-proposer: build: context: ../ diff --git a/espresso/scripts/prepare-allocs.sh b/espresso/scripts/prepare-allocs.sh index fada7be6aec..b19d9ef3fc6 100755 --- a/espresso/scripts/prepare-allocs.sh +++ b/espresso/scripts/prepare-allocs.sh @@ -89,7 +89,7 @@ kill $ANVIL_PID sleep 1 -"${OP_ROOT}/espresso/scripts/reshape-allocs.jq" \ +jq -S -f "${OP_ROOT}/espresso/scripts/reshape-allocs.jq" \ <(jq .accounts "${ANVIL_STATE_FILE}") \ | jq '{ "alloc": map_values(.state) }' \ > "${DEPLOYMENT_DIR}/deployer_allocs.json" diff --git a/espresso/scripts/reshape-allocs.jq b/espresso/scripts/reshape-allocs.jq index f8a775beffc..a092f8fd92b 100755 --- a/espresso/scripts/reshape-allocs.jq +++ b/espresso/scripts/reshape-allocs.jq @@ -1,4 +1,3 @@ -#!/usr/bin/env jq -S -f # Converts output of espresso-dev-node launched with # 'ESPRESSO_DEV_NODE_L1_DEPLOYMENT=dump' to form suitable # for e2e testing harness. From 6a3f29bdbf4f769cf776960006d7f536771a44c1 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Fri, 8 Aug 2025 05:29:54 +0000 Subject: [PATCH 02/31] a working script without args --- espresso/scripts/launch-batcher-enclave.sh | 161 +++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100755 espresso/scripts/launch-batcher-enclave.sh diff --git a/espresso/scripts/launch-batcher-enclave.sh b/espresso/scripts/launch-batcher-enclave.sh new file mode 100755 index 00000000000..e0e2da08697 --- /dev/null +++ b/espresso/scripts/launch-batcher-enclave.sh @@ -0,0 +1,161 @@ +#!/bin/bash +set -euo pipefail + +# Default environment variables if not set +export ESPRESSO_RUN_ENCLAVE_TESTS=1 + +# Required for enclave operations +if [[ ! -e /dev/nitro_enclaves ]]; then + echo "Error: /dev/nitro_enclaves device not found. Are you running on a Nitro-enabled instance?" + exit 1 +fi + +# Check if docker is running +if ! docker info > /dev/null 2>&1; then + echo "Error: Docker is not running or not accessible" + exit 1 +fi + +# Step 1: Check and build the intermediate Docker image (op-batcher-enclave:tests) +# This is the base image that will be used by enclaver to build the enclave image +if ! docker image inspect op-batcher-enclave:tests >/dev/null 2>&1; then + echo "Building intermediate batcher image..." + docker build -t op-batcher-enclave:tests \ + -f docker/op-stack/Dockerfile \ + --target op-batcher-target \ + ../ || { echo "Failed to build batcher image"; exit 1; } +else + echo "Using existing intermediate batcher image" +fi + +# Create enclaver manifest +cat > batcher-manifest.yaml << EOL +version: v1 +name: op-batcher-use-enclaver +target: op-batcher-use-enclaver:tests +sources: + app: op-batcher-enclave:tests +defaults: + cpu_count: 2 + memory_mb: 4096 +egress: + proxy_port: 10000 + allow: + - "0.0.0.0/0" + - "**" + - "::/0" +EOL + +# Step 2: Check and build the final enclave image (op-batcher-use-enclaver:tests) +# This is built by enclaver using the intermediate image as input +if ! docker image inspect op-batcher-use-enclaver:tests >/dev/null 2>&1; then + echo "Building enclaver image..." + echo "Using manifest:" + cat batcher-manifest.yaml + + echo "\nRunning enclaver build..." + ENCLAVER_OUTPUT=$(enclaver build --file batcher-manifest.yaml 2>&1) + if [ $? -ne 0 ]; then + echo "Failed to build enclaver image" + echo "Build output:" + echo "$ENCLAVER_OUTPUT" + exit 1 + fi + echo "Build output:" + echo "$ENCLAVER_OUTPUT" + # Verify the image was built + if ! docker image inspect op-batcher-use-enclaver:tests >/dev/null 2>&1; then + echo "Error: enclaver build succeeded but image not found" + exit 1 + fi +else + echo "Using existing enclaver image" +fi + +# Check if docker is running and containers exist +if ! docker info >/dev/null 2>&1; then + echo "Error: Docker is not running or not accessible" + echo "Please start Docker and ensure you have the necessary permissions" + exit 1 +fi + +echo "This script requires the following containers to be running:" +echo "- l1-geth" +echo "- op-geth" +echo "- op-node-sequencer" +echo "- espresso-dev-node" +echo " +To start all required containers, run:" +echo "cd ../.. && docker compose up -d" +echo "" + +echo "Checking for required containers..." + +# Get container IDs and check they exist +L1_CONTAINER=$(docker ps -q --filter name=espresso-l1-geth) +OP_CONTAINER=$(docker ps -q --filter name=espresso-op-geth) +ROLLUP_CONTAINER=$(docker ps -q --filter name=espresso-op-node-sequencer) +ESPRESSO_CONTAINER=$(docker ps -q --filter name=espresso-espresso-dev-node) + +# Show running containers for debugging +echo "\nCurrently running containers:" +docker ps --format "table {{.Names}}\t{{.Status}}" + +echo "\nChecking required containers:" + +# Check all required containers are running +if [ -z "$L1_CONTAINER" ]; then + echo "❌ espresso-l1-geth container not found" + echo "Please start all containers using 'docker compose up -d'" + exit 1 +else + echo "✓ espresso-l1-geth is running" +fi + +if [ -z "$OP_CONTAINER" ]; then + echo "❌ espresso-op-geth container not found" + echo "Please start all containers using 'docker compose up -d'" + exit 1 +else + echo "✓ espresso-op-geth is running" +fi + +if [ -z "$ROLLUP_CONTAINER" ]; then + echo "❌ espresso-op-node-sequencer container not found" + echo "Please start all containers using 'docker compose up -d'" + exit 1 +else + echo "✓ espresso-op-node-sequencer is running" +fi + +if [ -z "$ESPRESSO_CONTAINER" ]; then + echo "❌ espresso-espresso-dev-node container not found" + echo "Please start all containers using 'docker compose up -d'" + exit 1 +else + echo "✓ espresso-espresso-dev-node is running" +fi + +# Set default ports as used in docker-compose.yml +L1_HTTP_PORT=8545 +OP_HTTP_PORT=8547 +ROLLUP_PORT=8548 +ESPRESSO_SEQUENCER_API_PORT=50051 + +echo "Using ports:" +echo "L1 HTTP: $L1_HTTP_PORT" +echo "OP HTTP: $OP_HTTP_PORT" +echo "Rollup: $ROLLUP_PORT" +echo "Espresso Sequencer: $ESPRESSO_SEQUENCER_API_PORT" + +# Run the batcher in enclave +echo "Running batcher in enclave..." +docker run \ + --rm \ + --privileged \ + --net=host \ + --name=batcher-enclaver-${RANDOM} \ + --device=/dev/nitro_enclaves \ + op-batcher-use-enclaver:tests + +echo "Batcher started in enclave mode" From 5fbd417a85a2f24e9ae9862cde9f29bb834b5588 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Sat, 9 Aug 2025 05:03:37 +0000 Subject: [PATCH 03/31] everything works in the scripts despite the args --- espresso/scripts/launch-batcher-enclave.sh | 119 +++++---------------- 1 file changed, 28 insertions(+), 91 deletions(-) diff --git a/espresso/scripts/launch-batcher-enclave.sh b/espresso/scripts/launch-batcher-enclave.sh index e0e2da08697..163220e71ba 100755 --- a/espresso/scripts/launch-batcher-enclave.sh +++ b/espresso/scripts/launch-batcher-enclave.sh @@ -2,7 +2,8 @@ set -euo pipefail # Default environment variables if not set -export ESPRESSO_RUN_ENCLAVE_TESTS=1 +export ENCLAVE_INTERMEDIATE_IMAGE_TAG="op-batcher-enclave:tests" +export ENCLAVE_IMAGE_TAG="op-batcher-enclaver:tests" # Required for enclave operations if [[ ! -e /dev/nitro_enclaves ]]; then @@ -16,14 +17,26 @@ if ! docker info > /dev/null 2>&1; then exit 1 fi -# Step 1: Check and build the intermediate Docker image (op-batcher-enclave:tests) +# Step 1: Check and build the intermediate Docker image # This is the base image that will be used by enclaver to build the enclave image -if ! docker image inspect op-batcher-enclave:tests >/dev/null 2>&1; then - echo "Building intermediate batcher image..." - docker build -t op-batcher-enclave:tests \ - -f docker/op-stack/Dockerfile \ - --target op-batcher-target \ - ../ || { echo "Failed to build batcher image"; exit 1; } +if ! docker image inspect $ENCLAVE_INTERMEDIATE_IMAGE_TAG >/dev/null 2>&1; then + echo "Building enclave image..." + docker build -t $ENCLAVE_INTERMEDIATE_IMAGE_TAG \ + -f ../ops/docker/op-stack-go/Dockerfile \ + --target op-batcher-enclave-target \ + --build-arg ENCLAVE_BATCHER_ARGS="--l1-eth-rpc=http://l1-geth:8545 \ + --l2-eth-rpc=http://l2-geth:8547 \ + --rollup-rpc=http://rollup-node:8548 \ + --espresso-url=http://op-proposer:50051 \ + --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ + --mnemonic=test\ test\ test\ test\ test\ test\ test\ test\ test\ test\ test\ junk \ + --hd-path=m/44\'/60\'/0\'/0/0 \ + --throttle-threshold=0 --max-channel-duration=1 --target-num-frames=1 \ + --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" \ + ../ + if [ $? -ne 0 ]; then + echo "Failed to build batcher image"; exit 1 + fi else echo "Using existing intermediate batcher image" fi @@ -31,10 +44,10 @@ fi # Create enclaver manifest cat > batcher-manifest.yaml << EOL version: v1 -name: op-batcher-use-enclaver -target: op-batcher-use-enclaver:tests +name: op-batcher-enclaver +target: $ENCLAVE_IMAGE_TAG sources: - app: op-batcher-enclave:tests + app: $ENCLAVE_INTERMEDIATE_IMAGE_TAG defaults: cpu_count: 2 memory_mb: 4096 @@ -46,9 +59,9 @@ egress: - "::/0" EOL -# Step 2: Check and build the final enclave image (op-batcher-use-enclaver:tests) +# Step 2: Check and build the final enclave image (op-batcher-enclaver:tests) # This is built by enclaver using the intermediate image as input -if ! docker image inspect op-batcher-use-enclaver:tests >/dev/null 2>&1; then +if ! docker image inspect $ENCLAVE_IMAGE_TAG >/dev/null 2>&1; then echo "Building enclaver image..." echo "Using manifest:" cat batcher-manifest.yaml @@ -64,7 +77,7 @@ if ! docker image inspect op-batcher-use-enclaver:tests >/dev/null 2>&1; then echo "Build output:" echo "$ENCLAVER_OUTPUT" # Verify the image was built - if ! docker image inspect op-batcher-use-enclaver:tests >/dev/null 2>&1; then + if ! docker image inspect $ENCLAVE_IMAGE_TAG >/dev/null 2>&1; then echo "Error: enclaver build succeeded but image not found" exit 1 fi @@ -72,82 +85,6 @@ else echo "Using existing enclaver image" fi -# Check if docker is running and containers exist -if ! docker info >/dev/null 2>&1; then - echo "Error: Docker is not running or not accessible" - echo "Please start Docker and ensure you have the necessary permissions" - exit 1 -fi - -echo "This script requires the following containers to be running:" -echo "- l1-geth" -echo "- op-geth" -echo "- op-node-sequencer" -echo "- espresso-dev-node" -echo " -To start all required containers, run:" -echo "cd ../.. && docker compose up -d" -echo "" - -echo "Checking for required containers..." - -# Get container IDs and check they exist -L1_CONTAINER=$(docker ps -q --filter name=espresso-l1-geth) -OP_CONTAINER=$(docker ps -q --filter name=espresso-op-geth) -ROLLUP_CONTAINER=$(docker ps -q --filter name=espresso-op-node-sequencer) -ESPRESSO_CONTAINER=$(docker ps -q --filter name=espresso-espresso-dev-node) - -# Show running containers for debugging -echo "\nCurrently running containers:" -docker ps --format "table {{.Names}}\t{{.Status}}" - -echo "\nChecking required containers:" - -# Check all required containers are running -if [ -z "$L1_CONTAINER" ]; then - echo "❌ espresso-l1-geth container not found" - echo "Please start all containers using 'docker compose up -d'" - exit 1 -else - echo "✓ espresso-l1-geth is running" -fi - -if [ -z "$OP_CONTAINER" ]; then - echo "❌ espresso-op-geth container not found" - echo "Please start all containers using 'docker compose up -d'" - exit 1 -else - echo "✓ espresso-op-geth is running" -fi - -if [ -z "$ROLLUP_CONTAINER" ]; then - echo "❌ espresso-op-node-sequencer container not found" - echo "Please start all containers using 'docker compose up -d'" - exit 1 -else - echo "✓ espresso-op-node-sequencer is running" -fi - -if [ -z "$ESPRESSO_CONTAINER" ]; then - echo "❌ espresso-espresso-dev-node container not found" - echo "Please start all containers using 'docker compose up -d'" - exit 1 -else - echo "✓ espresso-espresso-dev-node is running" -fi - -# Set default ports as used in docker-compose.yml -L1_HTTP_PORT=8545 -OP_HTTP_PORT=8547 -ROLLUP_PORT=8548 -ESPRESSO_SEQUENCER_API_PORT=50051 - -echo "Using ports:" -echo "L1 HTTP: $L1_HTTP_PORT" -echo "OP HTTP: $OP_HTTP_PORT" -echo "Rollup: $ROLLUP_PORT" -echo "Espresso Sequencer: $ESPRESSO_SEQUENCER_API_PORT" - # Run the batcher in enclave echo "Running batcher in enclave..." docker run \ @@ -156,6 +93,6 @@ docker run \ --net=host \ --name=batcher-enclaver-${RANDOM} \ --device=/dev/nitro_enclaves \ - op-batcher-use-enclaver:tests + $ENCLAVE_IMAGE_TAG echo "Batcher started in enclave mode" From 5eac458fb7c9b81009c243b6befbeed5de357fa9 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Sun, 10 Aug 2025 00:30:03 +0000 Subject: [PATCH 04/31] fix socat proxy script --- README_ESPRESSO.md | 7 +- espresso/docker-compose.yml | 68 ++++++++---- espresso/scripts/launch-batcher-enclave.sh | 114 +++++++++------------ espresso/scripts/prepare-allocs.sh | 20 ++-- op-batcher/enclave-entrypoint.bash | 90 +++++++++------- 5 files changed, 164 insertions(+), 135 deletions(-) diff --git a/README_ESPRESSO.md b/README_ESPRESSO.md index 40cd4c57039..ace56b659d0 100644 --- a/README_ESPRESSO.md +++ b/README_ESPRESSO.md @@ -294,6 +294,11 @@ docker compose down -v --remove-orphans ./scripts/prepare-allocs.sh ``` +* Build the enclave image. +```console +./scripts/launch-batcher-enclave.sh +``` + * Build and start all services in the background. ```console docker compose up --build -d @@ -338,7 +343,7 @@ docker compose down -v docker volume prune -a ``` -* If you have changed OP contracts, you will have to start the devnet fresh and re-generate +* If you have changed OP contracts, you will have to start the devnet fresh and re-generate the genesis allocations by running `prepare-allocs.sh` diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index 3a899fd8089..bd34066e983 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -284,6 +284,8 @@ services: condition: service_healthy l1-validator: condition: service_started + ports: + - "${ROLLUP_PORT}:${ROLLUP_PORT}" environment: CAFF_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT} OP_NODE_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT} @@ -373,13 +375,44 @@ services: - --l1.epoch-poll-interval=1s restart: "no" + # op-batcher: + # build: + # context: ../ + # dockerfile: espresso/docker/op-stack/Dockerfile + # target: op-batcher-target + # image: op-batcher:espresso + # # It is not necessary to specify all dependencies, but a good practice. + # depends_on: + # l1-geth: + # condition: service_healthy + # op-geth: + # condition: service_started + # op-node-sequencer: + # condition: service_started + # espresso-dev-node: + # condition: service_started + # l2-genesis: + # condition: service_completed_successfully + # environment: + # L1_RPC: http://l1-geth:${L1_HTTP_PORT} + # OP_BATCHER_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT} + # OP_BATCHER_L2_ETH_RPC: http://op-geth:${OP_HTTP_PORT} + # OP_BATCHER_ROLLUP_RPC: http://op-node-sequencer:${ROLLUP_PORT} + # OP_BATCHER_ESPRESSO_URL: http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT},http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT} + # volumes: + # - ../packages/contracts-bedrock/lib/superchain-registry/ops/testdata/monorepo:/config + # command: + # - op-batcher + # - --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797 + # - --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 # Default value for testing + # - --mnemonic=test test test test test test test test test test test junk # Arbitrary value for testing + # - --hd-path=m/44'/60'/0'/0/0 # Arbitrary value for testing + # - --throttle-threshold=0 + # - --max-channel-duration=1 + # - --target-num-frames=1 + op-batcher: - build: - context: ../ - dockerfile: espresso/docker/op-stack/Dockerfile - target: op-batcher-target - image: op-batcher:espresso - # It is not necessary to specify all dependencies, but a good practice. + image: ${OP_BATCHER_ENCLAVE_IMAGE:-op-batcher-enclaver:tests} depends_on: l1-geth: condition: service_healthy @@ -391,23 +424,14 @@ services: condition: service_started l2-genesis: condition: service_completed_successfully + network_mode: "host" + privileged: true + devices: + - /dev/nitro_enclaves:/dev/nitro_enclaves environment: - L1_RPC: http://l1-geth:${L1_HTTP_PORT} - OP_BATCHER_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT} - OP_BATCHER_L2_ETH_RPC: http://op-geth:${OP_HTTP_PORT} - OP_BATCHER_ROLLUP_RPC: http://op-node-sequencer:${ROLLUP_PORT} - OP_BATCHER_ESPRESSO_URL: http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT},http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT} - volumes: - - ../packages/contracts-bedrock/lib/superchain-registry/ops/testdata/monorepo:/config - command: - - op-batcher - - --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797 - - --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 # Default value for testing - - --mnemonic=test test test test test test test test test test test junk # Arbitrary value for testing - - --hd-path=m/44'/60'/0'/0/0 # Arbitrary value for testing - - --throttle-threshold=0 - - --max-channel-duration=1 - - --target-num-frames=1 + ESPRESSO_RUN_ENCLAVE_TESTS: "true" + restart: "no" + # op-batcher-tee: # build: diff --git a/espresso/scripts/launch-batcher-enclave.sh b/espresso/scripts/launch-batcher-enclave.sh index 163220e71ba..9458a3ff791 100755 --- a/espresso/scripts/launch-batcher-enclave.sh +++ b/espresso/scripts/launch-batcher-enclave.sh @@ -1,9 +1,11 @@ #!/bin/bash set -euo pipefail -# Default environment variables if not set -export ENCLAVE_INTERMEDIATE_IMAGE_TAG="op-batcher-enclave:tests" -export ENCLAVE_IMAGE_TAG="op-batcher-enclaver:tests" +# Configuration +export HOST_IP=127.0.0.1 #$(hostname -I | awk '{print $1}') +export ENCLAVE_APP_IMAGE="op-batcher-enclave:app" +export ENCLAVE_TARGET_IMAGE="op-batcher-enclaver:tests" +export MANIFEST_FILE="batcher-enclave.yaml" # Required for enclave operations if [[ ! -e /dev/nitro_enclaves ]]; then @@ -17,82 +19,66 @@ if ! docker info > /dev/null 2>&1; then exit 1 fi -# Step 1: Check and build the intermediate Docker image -# This is the base image that will be used by enclaver to build the enclave image -if ! docker image inspect $ENCLAVE_INTERMEDIATE_IMAGE_TAG >/dev/null 2>&1; then - echo "Building enclave image..." - docker build -t $ENCLAVE_INTERMEDIATE_IMAGE_TAG \ - -f ../ops/docker/op-stack-go/Dockerfile \ - --target op-batcher-enclave-target \ - --build-arg ENCLAVE_BATCHER_ARGS="--l1-eth-rpc=http://l1-geth:8545 \ - --l2-eth-rpc=http://l2-geth:8547 \ - --rollup-rpc=http://rollup-node:8548 \ - --espresso-url=http://op-proposer:50051 \ - --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ - --mnemonic=test\ test\ test\ test\ test\ test\ test\ test\ test\ test\ test\ junk \ - --hd-path=m/44\'/60\'/0\'/0/0 \ - --throttle-threshold=0 --max-channel-duration=1 --target-num-frames=1 \ - --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" \ - ../ - if [ $? -ne 0 ]; then - echo "Failed to build batcher image"; exit 1 - fi -else - echo "Using existing intermediate batcher image" +echo "Using HOST_IP: $HOST_IP" + +# Step 1: Build the Docker image using your existing Dockerfile +echo "Building Docker image..." +docker build -t $ENCLAVE_APP_IMAGE \ + -f ../ops/docker/op-stack-go/Dockerfile \ + --target op-batcher-enclave-target \ + --build-arg ENCLAVE_BATCHER_ARGS="--l1-eth-rpc=http://$HOST_IP:8545 \ + --l2-eth-rpc=http://$HOST_IP:8546 \ + --rollup-rpc=http://$HOST_IP:9545 \ + --espresso-url=http://$HOST_IP:24000,http://$HOST_IP:24000 \ + --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ + --mnemonic=test\ test\ test\ test\ test\ test\ test\ test\ test\ test\ test\ junk \ + --hd-path=m/44\'/60\'/0\'/0/0 \ + --throttle-threshold=0 --max-channel-duration=1 --target-num-frames=1 \ + --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" \ + ../ + +if [ $? -ne 0 ]; then + echo "Failed to build Docker image" + exit 1 fi -# Create enclaver manifest -cat > batcher-manifest.yaml << EOL +# Step 2: Create enclaver manifest +echo "Creating enclaver manifest..." +cat > $MANIFEST_FILE << EOL version: v1 -name: op-batcher-enclaver -target: $ENCLAVE_IMAGE_TAG +name: "op-batcher-enclave" +target: "$ENCLAVE_TARGET_IMAGE" sources: - app: $ENCLAVE_INTERMEDIATE_IMAGE_TAG + app: "$ENCLAVE_APP_IMAGE" defaults: - cpu_count: 2 memory_mb: 4096 + cpu_count: 2 egress: proxy_port: 10000 allow: + - "host" - "0.0.0.0/0" - "**" - "::/0" EOL -# Step 2: Check and build the final enclave image (op-batcher-enclaver:tests) -# This is built by enclaver using the intermediate image as input -if ! docker image inspect $ENCLAVE_IMAGE_TAG >/dev/null 2>&1; then - echo "Building enclaver image..." - echo "Using manifest:" - cat batcher-manifest.yaml +echo "Manifest created:" +cat $MANIFEST_FILE + +# Step 3: Build the enclave +echo "Building enclave..." +sudo enclaver build --file $MANIFEST_FILE - echo "\nRunning enclaver build..." - ENCLAVER_OUTPUT=$(enclaver build --file batcher-manifest.yaml 2>&1) - if [ $? -ne 0 ]; then - echo "Failed to build enclaver image" - echo "Build output:" - echo "$ENCLAVER_OUTPUT" - exit 1 - fi - echo "Build output:" - echo "$ENCLAVER_OUTPUT" - # Verify the image was built - if ! docker image inspect $ENCLAVE_IMAGE_TAG >/dev/null 2>&1; then - echo "Error: enclaver build succeeded but image not found" - exit 1 - fi -else - echo "Using existing enclaver image" +if [ $? -ne 0 ]; then + echo "Failed to build enclave" + exit 1 fi -# Run the batcher in enclave -echo "Running batcher in enclave..." -docker run \ - --rm \ - --privileged \ - --net=host \ - --name=batcher-enclaver-${RANDOM} \ - --device=/dev/nitro_enclaves \ - $ENCLAVE_IMAGE_TAG +# Step 4: Run the enclave +echo "Running enclave..." +docker run --rm --privileged --net=host \ + --name batcher-enclaver-$RANDOM \ + --device=/dev/nitro_enclaves \ + $ENCLAVE_TARGET_IMAGE -echo "Batcher started in enclave mode" +# echo "Enclave execution completed" diff --git a/espresso/scripts/prepare-allocs.sh b/espresso/scripts/prepare-allocs.sh index b19d9ef3fc6..631fe9ed63c 100755 --- a/espresso/scripts/prepare-allocs.sh +++ b/espresso/scripts/prepare-allocs.sh @@ -70,16 +70,16 @@ op-deployer init --l1-chain-id "${L1_CHAIN_ID}" \ --intent-type standard-overrides \ --outdir ${DEPLOYER_DIR} -dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .l1ContractsLocator -v "${ARTIFACTS_DIR}" -dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .l2ContractsLocator -v "${ARTIFACTS_DIR}" -dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .fundDevAccounts -t bool -v true -dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].baseFeeVaultRecipient -v "${OPERATOR_ADDRESS}" -dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].l1FeeVaultRecipient -v "${OPERATOR_ADDRESS}" -dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].sequencerFeeVaultRecipient -v "${OPERATOR_ADDRESS}" -dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.systemConfigOwner -v "${OPERATOR_ADDRESS}" -dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.unsafeBlockSigner -v "${OPERATOR_ADDRESS}" -dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.batcher -v "${OPERATOR_ADDRESS}" -dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.proposer -v "${OPERATOR_ADDRESS}" +dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .l1ContractsLocator -v "${ARTIFACTS_DIR}" +dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .l2ContractsLocator -v "${ARTIFACTS_DIR}" +dasel put bool -f "${DEPLOYER_DIR}/intent.toml" -s .fundDevAccounts -v true +dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].baseFeeVaultRecipient -v "${OPERATOR_ADDRESS}" +dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].l1FeeVaultRecipient -v "${OPERATOR_ADDRESS}" +dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].sequencerFeeVaultRecipient -v "${OPERATOR_ADDRESS}" +dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.systemConfigOwner -v "${OPERATOR_ADDRESS}" +dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.unsafeBlockSigner -v "${OPERATOR_ADDRESS}" +dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.batcher -v "${OPERATOR_ADDRESS}" +dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.proposer -v "${OPERATOR_ADDRESS}" op-deployer apply --l1-rpc-url "${ANVIL_URL}" \ --workdir "${DEPLOYER_DIR}" \ diff --git a/op-batcher/enclave-entrypoint.bash b/op-batcher/enclave-entrypoint.bash index 58e86c3199e..6b51f6618cf 100644 --- a/op-batcher/enclave-entrypoint.bash +++ b/op-batcher/enclave-entrypoint.bash @@ -6,7 +6,7 @@ # to directly pass commandline arguments when starting EIF images) # We will need to start a proxy for each of those urls -URL_ARG="^(--altda\.da-server|--espresso-url|--l1-eth-rpc|--l2-eth-rpc|--rollup-rpc|--signer\.endpoint)$" +URL_ARG_RE='^(--altda\.da-server|--espresso-url|--l1-eth-rpc|--l2-eth-rpc|--rollup-rpc|--signer\.endpoint)(=|$)' # Re-populate the arguments passed through the environment if [ -n "$ENCLAVE_BATCHER_ARGS" ]; then @@ -31,25 +31,25 @@ unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY NC_PORT=8337 received_args=() -echo "Starting nc listener on port $NC_PORT (60 second timeout)" -{ - # Read null-separated arguments until we get \0\0 - while IFS= read -r -d '' arg; do - if [[ -z "$arg" ]]; then - # Empty argument signals end (\0\0) - break - fi - received_args+=("$arg") - done -} < <(nc -l -p "$NC_PORT" -w 60) - -if [ ${#received_args[@]} -eq 0 ]; then - echo "Warning: No arguments received via nc listener within 60 seconds, continuing with existing arguments" -else - echo "Received ${#received_args[@]} arguments via nc, appending to existing arguments" - # Append received arguments to existing positional parameters - set -- "$@" "${received_args[@]}" -fi +# echo "Starting nc listener on port $NC_PORT (60 second timeout)" +# { +# # Read null-separated arguments until we get \0\0 +# while IFS= read -r -d '' arg; do +# if [[ -z "$arg" ]]; then +# # Empty argument signals end (\0\0) +# break +# fi +# received_args+=("$arg") +# done +# } < <(nc -l -p "$NC_PORT" -w 60) + +# if [ ${#received_args[@]} -eq 0 ]; then +# echo "Warning: No arguments received via nc listener within 60 seconds, continuing with existing arguments" +# else +# echo "Received ${#received_args[@]} arguments via nc, appending to existing arguments" +# # Append received arguments to existing positional parameters +# set -- "$@" "${received_args[@]}" +# fi wait_for_port() { local port="$1" @@ -108,36 +108,50 @@ filtered_args=() url_args=() SOCAT_PORT=10001 +echo "Arguments: $@" # Process all arguments while [ $# -gt 0 ]; do + echo "Processing argument: $1" # Check if the argument matches the URL pattern - if [[ $1 =~ $URL_ARG ]]; then - # Extract the flag part and possible value part - flag=${BASH_REMATCH[1]} - - if [ $# -gt 1 ]; then - shift - value="$1" - else - echo "$flag doesn't have a value" - exit 1 - fi + if [[ $1 =~ $URL_ARG_RE ]]; then + echo "Found URL argument: $1" + # Extract the flag part and possible value part + flag=${BASH_REMATCH[1]} + + # extract value from "--flag=value" or "--flag value" + if [[ "$1" == *=* ]]; then + value="${1#*=}" + else + shift || { echo "$flag missing value"; exit 1; } + value="$1" + fi - echo "Rewriting $flag=$value" + # SPECIAL CASE: espresso-url may be a comma list. Either split here, + # or (simpler) pass the flag twice at build time. See note below. + if [[ "$flag" == "--espresso-url" && "$value" == *","* ]]; then + IFS=',' read -r -a parts <<< "$value" + for part in "${parts[@]}"; do + if ! new_url=$(launch_socat "$part" "$SOCAT_PORT"); then + echo "Failed to launch socat for $flag=$part"; exit 1 + fi + echo "Rewritten: $new_url" + url_args+=("$flag" "$new_url") + ((SOCAT_PORT++)) + done + else if ! new_url=$(launch_socat "$value" "$SOCAT_PORT"); then - echo "Failed to launch socat for $flag=$value" - exit 1 + echo "Failed to launch socat for $flag=$value"; exit 1 fi echo "Rewritten: $new_url" url_args+=("$flag" "$new_url") - ((SOCAT_PORT++)) + fi else - # This is not a URL argument, add it to filtered args - filtered_args+=("$1") + filtered_args+=("$1") fi shift -done + done + # Combine the rewritten URL arguments with the other arguments all_args=("${filtered_args[@]}" "${url_args[@]}") From 05e0fe2d55ae85747f4d082fd287c3c10afb7980 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Sun, 10 Aug 2025 02:02:21 +0000 Subject: [PATCH 05/31] working op-batcher inside docker-compose --- espresso/scripts/launch-batcher-enclave.sh | 10 +++++----- espresso/scripts/prepare-allocs.sh | 4 ++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/espresso/scripts/launch-batcher-enclave.sh b/espresso/scripts/launch-batcher-enclave.sh index 9458a3ff791..1104a179309 100755 --- a/espresso/scripts/launch-batcher-enclave.sh +++ b/espresso/scripts/launch-batcher-enclave.sh @@ -75,10 +75,10 @@ if [ $? -ne 0 ]; then fi # Step 4: Run the enclave -echo "Running enclave..." -docker run --rm --privileged --net=host \ - --name batcher-enclaver-$RANDOM \ - --device=/dev/nitro_enclaves \ - $ENCLAVE_TARGET_IMAGE +# echo "Running enclave..." +# docker run --rm --privileged --net=host \ +# --name batcher-enclaver-$RANDOM \ +# --device=/dev/nitro_enclaves \ +# $ENCLAVE_TARGET_IMAGE # echo "Enclave execution completed" diff --git a/espresso/scripts/prepare-allocs.sh b/espresso/scripts/prepare-allocs.sh index 631fe9ed63c..7be9f40e20a 100755 --- a/espresso/scripts/prepare-allocs.sh +++ b/espresso/scripts/prepare-allocs.sh @@ -70,6 +70,10 @@ op-deployer init --l1-chain-id "${L1_CHAIN_ID}" \ --intent-type standard-overrides \ --outdir ${DEPLOYER_DIR} +# turn on Espresso integration for this chain +dasel put bool -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].espressoEnabled -v true +dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].preApprovedBatcherKey -v "${OPERATOR_ADDRESS}" + dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .l1ContractsLocator -v "${ARTIFACTS_DIR}" dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .l2ContractsLocator -v "${ARTIFACTS_DIR}" dasel put bool -f "${DEPLOYER_DIR}/intent.toml" -s .fundDevAccounts -v true From e6a64e710bc94e8f0590a41227bed126f72e0f95 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Sun, 10 Aug 2025 02:07:12 +0000 Subject: [PATCH 06/31] rename the script to build batcher enclave image --- README_ESPRESSO.md | 2 +- .../{launch-batcher-enclave.sh => batcher-enclave-image.sh} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename espresso/scripts/{launch-batcher-enclave.sh => batcher-enclave-image.sh} (100%) diff --git a/README_ESPRESSO.md b/README_ESPRESSO.md index ace56b659d0..b0829051673 100644 --- a/README_ESPRESSO.md +++ b/README_ESPRESSO.md @@ -296,7 +296,7 @@ docker compose down -v --remove-orphans * Build the enclave image. ```console -./scripts/launch-batcher-enclave.sh +./scripts/batcher-enclave-image.sh ``` * Build and start all services in the background. diff --git a/espresso/scripts/launch-batcher-enclave.sh b/espresso/scripts/batcher-enclave-image.sh similarity index 100% rename from espresso/scripts/launch-batcher-enclave.sh rename to espresso/scripts/batcher-enclave-image.sh From ff8fa8adf3d1cafb6d857dd502ee61d0679ac5ad Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Mon, 11 Aug 2025 16:28:11 +0000 Subject: [PATCH 07/31] cleanup and profile the op-batcher-non-tee --- README_ESPRESSO.md | 8 +- espresso/docker-compose.yml | 120 +++++++++-------------------- espresso/scripts/prepare-allocs.sh | 1 - op-batcher/enclave-entrypoint.bash | 38 ++++----- 4 files changed, 61 insertions(+), 106 deletions(-) diff --git a/README_ESPRESSO.md b/README_ESPRESSO.md index b0829051673..1cd655c8fdd 100644 --- a/README_ESPRESSO.md +++ b/README_ESPRESSO.md @@ -294,15 +294,19 @@ docker compose down -v --remove-orphans ./scripts/prepare-allocs.sh ``` -* Build the enclave image. +* Make sure you're on a machine with AWS Nitro Enclaves enabled. Build the enclave image. ```console ./scripts/batcher-enclave-image.sh ``` -* Build and start all services in the background. +* Build and start all services in the background. If you're not running on a machine with AWS Nitro Enclaves enabled, use the `nontee` profile instead. ```console docker compose up --build -d ``` +or +```console +docker compose up --build -d --profile nontee +``` * Run the services and check the log. ```console diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index bd34066e983..402d0cd6184 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -375,41 +375,42 @@ services: - --l1.epoch-poll-interval=1s restart: "no" - # op-batcher: - # build: - # context: ../ - # dockerfile: espresso/docker/op-stack/Dockerfile - # target: op-batcher-target - # image: op-batcher:espresso - # # It is not necessary to specify all dependencies, but a good practice. - # depends_on: - # l1-geth: - # condition: service_healthy - # op-geth: - # condition: service_started - # op-node-sequencer: - # condition: service_started - # espresso-dev-node: - # condition: service_started - # l2-genesis: - # condition: service_completed_successfully - # environment: - # L1_RPC: http://l1-geth:${L1_HTTP_PORT} - # OP_BATCHER_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT} - # OP_BATCHER_L2_ETH_RPC: http://op-geth:${OP_HTTP_PORT} - # OP_BATCHER_ROLLUP_RPC: http://op-node-sequencer:${ROLLUP_PORT} - # OP_BATCHER_ESPRESSO_URL: http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT},http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT} - # volumes: - # - ../packages/contracts-bedrock/lib/superchain-registry/ops/testdata/monorepo:/config - # command: - # - op-batcher - # - --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797 - # - --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 # Default value for testing - # - --mnemonic=test test test test test test test test test test test junk # Arbitrary value for testing - # - --hd-path=m/44'/60'/0'/0/0 # Arbitrary value for testing - # - --throttle-threshold=0 - # - --max-channel-duration=1 - # - --target-num-frames=1 + op-batcher-non-tee: + profiles: ["nontee"] + build: + context: ../ + dockerfile: espresso/docker/op-stack/Dockerfile + target: op-batcher-target + image: op-batcher:espresso + # It is not necessary to specify all dependencies, but a good practice. + depends_on: + l1-geth: + condition: service_healthy + op-geth: + condition: service_started + op-node-sequencer: + condition: service_started + espresso-dev-node: + condition: service_started + l2-genesis: + condition: service_completed_successfully + environment: + L1_RPC: http://l1-geth:${L1_HTTP_PORT} + OP_BATCHER_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT} + OP_BATCHER_L2_ETH_RPC: http://op-geth:${OP_HTTP_PORT} + OP_BATCHER_ROLLUP_RPC: http://op-node-sequencer:${ROLLUP_PORT} + OP_BATCHER_ESPRESSO_URL: http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT},http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT} + volumes: + - ../packages/contracts-bedrock/lib/superchain-registry/ops/testdata/monorepo:/config + command: + - op-batcher + - --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797 + - --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 # Default value for testing + - --mnemonic=test test test test test test test test test test test junk # Arbitrary value for testing + - --hd-path=m/44'/60'/0'/0/0 # Arbitrary value for testing + - --throttle-threshold=0 + - --max-channel-duration=1 + - --target-num-frames=1 op-batcher: image: ${OP_BATCHER_ENCLAVE_IMAGE:-op-batcher-enclaver:tests} @@ -433,55 +434,6 @@ services: restart: "no" - # op-batcher-tee: - # build: - # context: ../ - # dockerfile: espresso/docker/op-stack/Dockerfile - # target: op-batcher-target - # image: optimism-espresso-integration/op-batcher-enclave:latest - # # It is not necessary to specify all dependencies, but a good practice. - # depends_on: - # l1-geth: - # condition: service_healthy - # op-geth: - # condition: service_started - # op-node-sequencer: - # condition: service_started - # espresso-dev-node: - # condition: service_started - # l2-genesis: - # condition: service_completed_successfully - # environment: - # L1_RPC: http://l1-geth:${L1_HTTP_PORT} - # OP_BATCHER_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT} - # OP_BATCHER_L2_ETH_RPC: http://op-geth:${OP_HTTP_PORT} - # OP_BATCHER_ROLLUP_RPC: http://op-node-sequencer:${ROLLUP_PORT} - # OP_BATCHER_ESPRESSO_URL: http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT},http://espresso-dev-node:${ESPRESSO_SEQUENCER_API_PORT} - # BATCH_INBOX_ADDRESS: ${BATCH_INBOX_ADDRESS:-0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9} - # BATCH_AUTHENTICATOR_ADDRESS: ${BATCH_AUTHENTICATOR_ADDRESS:-0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9} - # ESPRESSO_TEE_VERIFIER_ADDRESS: ${ESPRESSO_TEE_VERIFIER_ADDRESS:-0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0} - # ESPRESSO_RUN_ENCLAVE_TESTS: "true" - # devices: - # - /dev/nitro_enclaves:/dev/nitro_enclaves - # volumes: - # - ../packages/contracts-bedrock/lib/superchain-registry/ops/testdata/monorepo:/config - # - /var/run/docker.sock:/var/run/docker.sock - # deploy: - # resources: - # reservations: - # memory: 4096M - # cpus: '2' - # privileged: true # Required for enclave access - # command: - # - op-batcher - # - --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797 - # - --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 # Default value for testing - # - --mnemonic=test test test test test test test test test test test junk # Arbitrary value for testing - # - --hd-path=m/44'/60'/0'/0/0 # Arbitrary value for testing - # - --throttle-threshold=0 - # - --max-channel-duration=1 - # - --target-num-frames=1 - op-proposer: build: context: ../ diff --git a/espresso/scripts/prepare-allocs.sh b/espresso/scripts/prepare-allocs.sh index 7be9f40e20a..e7c7b478b13 100755 --- a/espresso/scripts/prepare-allocs.sh +++ b/espresso/scripts/prepare-allocs.sh @@ -72,7 +72,6 @@ op-deployer init --l1-chain-id "${L1_CHAIN_ID}" \ # turn on Espresso integration for this chain dasel put bool -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].espressoEnabled -v true -dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].preApprovedBatcherKey -v "${OPERATOR_ADDRESS}" dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .l1ContractsLocator -v "${ARTIFACTS_DIR}" dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .l2ContractsLocator -v "${ARTIFACTS_DIR}" diff --git a/op-batcher/enclave-entrypoint.bash b/op-batcher/enclave-entrypoint.bash index 6b51f6618cf..6f72f329a03 100644 --- a/op-batcher/enclave-entrypoint.bash +++ b/op-batcher/enclave-entrypoint.bash @@ -31,25 +31,25 @@ unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY NC_PORT=8337 received_args=() -# echo "Starting nc listener on port $NC_PORT (60 second timeout)" -# { -# # Read null-separated arguments until we get \0\0 -# while IFS= read -r -d '' arg; do -# if [[ -z "$arg" ]]; then -# # Empty argument signals end (\0\0) -# break -# fi -# received_args+=("$arg") -# done -# } < <(nc -l -p "$NC_PORT" -w 60) - -# if [ ${#received_args[@]} -eq 0 ]; then -# echo "Warning: No arguments received via nc listener within 60 seconds, continuing with existing arguments" -# else -# echo "Received ${#received_args[@]} arguments via nc, appending to existing arguments" -# # Append received arguments to existing positional parameters -# set -- "$@" "${received_args[@]}" -# fi +echo "Starting nc listener on port $NC_PORT (60 second timeout)" +{ + # Read null-separated arguments until we get \0\0 + while IFS= read -r -d '' arg; do + if [[ -z "$arg" ]]; then + # Empty argument signals end (\0\0) + break + fi + received_args+=("$arg") + done +} < <(nc -l -p "$NC_PORT" -w 60) + +if [ ${#received_args[@]} -eq 0 ]; then + echo "Warning: No arguments received via nc listener within 60 seconds, continuing with existing arguments" +else + echo "Received ${#received_args[@]} arguments via nc, appending to existing arguments" + # Append received arguments to existing positional parameters + set -- "$@" "${received_args[@]}" +fi wait_for_port() { local port="$1" From bdef714cb52199a9d6fd6fb45288286a17ade9a7 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Mon, 11 Aug 2025 16:54:50 +0000 Subject: [PATCH 08/31] use port number from env and shorten nc listener timeout as it will not be used in most cases --- espresso/scripts/batcher-enclave-image.sh | 24 ++++++++++++++++++----- op-batcher/enclave-entrypoint.bash | 6 +++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/espresso/scripts/batcher-enclave-image.sh b/espresso/scripts/batcher-enclave-image.sh index 1104a179309..37be107cb4e 100755 --- a/espresso/scripts/batcher-enclave-image.sh +++ b/espresso/scripts/batcher-enclave-image.sh @@ -1,8 +1,21 @@ #!/bin/bash set -euo pipefail +# --- load .env --- +SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +ENV_FILE="${SCRIPT_DIR}/../.env" +if [[ ! -f "$ENV_FILE" ]]; then + echo "Error: $ENV_FILE not found"; exit 1 +fi +# export everything we source +set -a +# shellcheck disable=SC1090 +source "$ENV_FILE" +set +a + # Configuration -export HOST_IP=127.0.0.1 #$(hostname -I | awk '{print $1}') +# NOTE: if loopback doesn't work from inside the enclave, set HOST_IP=host +HOST_IP="${HOST_IP:-127.0.0.1}" export ENCLAVE_APP_IMAGE="op-batcher-enclave:app" export ENCLAVE_TARGET_IMAGE="op-batcher-enclaver:tests" export MANIFEST_FILE="batcher-enclave.yaml" @@ -20,16 +33,17 @@ if ! docker info > /dev/null 2>&1; then fi echo "Using HOST_IP: $HOST_IP" +echo "Ports -> L1:$L1_HTTP_PORT L2:$OP_HTTP_PORT Rollup:$ROLLUP_PORT EspressoAPI:$ESPRESSO_SEQUENCER_API_PORT" # Step 1: Build the Docker image using your existing Dockerfile echo "Building Docker image..." docker build -t $ENCLAVE_APP_IMAGE \ -f ../ops/docker/op-stack-go/Dockerfile \ --target op-batcher-enclave-target \ - --build-arg ENCLAVE_BATCHER_ARGS="--l1-eth-rpc=http://$HOST_IP:8545 \ - --l2-eth-rpc=http://$HOST_IP:8546 \ - --rollup-rpc=http://$HOST_IP:9545 \ - --espresso-url=http://$HOST_IP:24000,http://$HOST_IP:24000 \ + --build-arg ENCLAVE_BATCHER_ARGS="--l1-eth-rpc=http://$HOST_IP:$L1_HTTP_PORT \ + --l2-eth-rpc=http://$HOST_IP:$OP_HTTP_PORT \ + --rollup-rpc=http://$HOST_IP:$ROLLUP_PORT \ + --espresso-url=http://$HOST_IP:$ESPRESSO_SEQUENCER_API_PORT,http://$HOST_IP:$ESPRESSO_SEQUENCER_API_PORT \ --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ --mnemonic=test\ test\ test\ test\ test\ test\ test\ test\ test\ test\ test\ junk \ --hd-path=m/44\'/60\'/0\'/0/0 \ diff --git a/op-batcher/enclave-entrypoint.bash b/op-batcher/enclave-entrypoint.bash index 6f72f329a03..763ea5bfc3b 100644 --- a/op-batcher/enclave-entrypoint.bash +++ b/op-batcher/enclave-entrypoint.bash @@ -31,7 +31,7 @@ unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY NC_PORT=8337 received_args=() -echo "Starting nc listener on port $NC_PORT (60 second timeout)" +echo "Starting nc listener on port $NC_PORT (10 second timeout)" { # Read null-separated arguments until we get \0\0 while IFS= read -r -d '' arg; do @@ -41,10 +41,10 @@ echo "Starting nc listener on port $NC_PORT (60 second timeout)" fi received_args+=("$arg") done -} < <(nc -l -p "$NC_PORT" -w 60) +} < <(nc -l -p "$NC_PORT" -w 10) if [ ${#received_args[@]} -eq 0 ]; then - echo "Warning: No arguments received via nc listener within 60 seconds, continuing with existing arguments" + echo "Warning: No arguments received via nc listener within 10 seconds, continuing with existing arguments" else echo "Received ${#received_args[@]} arguments via nc, appending to existing arguments" # Append received arguments to existing positional parameters From e329c7ad376a1a7b7f30868f03642749b833b80f Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Tue, 12 Aug 2025 17:33:07 +0000 Subject: [PATCH 09/31] fix dasel format --- espresso/scripts/prepare-allocs.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/espresso/scripts/prepare-allocs.sh b/espresso/scripts/prepare-allocs.sh index e7c7b478b13..913a2c422fa 100755 --- a/espresso/scripts/prepare-allocs.sh +++ b/espresso/scripts/prepare-allocs.sh @@ -71,18 +71,18 @@ op-deployer init --l1-chain-id "${L1_CHAIN_ID}" \ --outdir ${DEPLOYER_DIR} # turn on Espresso integration for this chain -dasel put bool -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].espressoEnabled -v true - -dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .l1ContractsLocator -v "${ARTIFACTS_DIR}" -dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .l2ContractsLocator -v "${ARTIFACTS_DIR}" -dasel put bool -f "${DEPLOYER_DIR}/intent.toml" -s .fundDevAccounts -v true -dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].baseFeeVaultRecipient -v "${OPERATOR_ADDRESS}" -dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].l1FeeVaultRecipient -v "${OPERATOR_ADDRESS}" -dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].sequencerFeeVaultRecipient -v "${OPERATOR_ADDRESS}" -dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.systemConfigOwner -v "${OPERATOR_ADDRESS}" -dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.unsafeBlockSigner -v "${OPERATOR_ADDRESS}" -dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.batcher -v "${OPERATOR_ADDRESS}" -dasel put string -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.proposer -v "${OPERATOR_ADDRESS}" +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].espressoEnabled -t bool -v true + +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .l1ContractsLocator -v "${ARTIFACTS_DIR}" +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .l2ContractsLocator -v "${ARTIFACTS_DIR}" +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .fundDevAccounts -t bool -v true +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].baseFeeVaultRecipient -v "${OPERATOR_ADDRESS}" +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].l1FeeVaultRecipient -v "${OPERATOR_ADDRESS}" +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].sequencerFeeVaultRecipient -v "${OPERATOR_ADDRESS}" +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.systemConfigOwner -v "${OPERATOR_ADDRESS}" +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.unsafeBlockSigner -v "${OPERATOR_ADDRESS}" +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.batcher -v "${OPERATOR_ADDRESS}" +dasel put -f "${DEPLOYER_DIR}/intent.toml" -s .chains.[0].roles.proposer -v "${OPERATOR_ADDRESS}" op-deployer apply --l1-rpc-url "${ANVIL_URL}" \ --workdir "${DEPLOYER_DIR}" \ From d63c533fa67f743ff6258166c8621d3e110985d7 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Tue, 12 Aug 2025 23:13:37 +0000 Subject: [PATCH 10/31] remove uneeded ESPRESSO_RUN_ENCLAVE_TESTS --- espresso/docker-compose.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index 402d0cd6184..10404ee0c9b 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -429,8 +429,6 @@ services: privileged: true devices: - /dev/nitro_enclaves:/dev/nitro_enclaves - environment: - ESPRESSO_RUN_ENCLAVE_TESTS: "true" restart: "no" From f46212813947922e372d40ee3c4ecb205412e62f Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Thu, 14 Aug 2025 17:31:33 +0000 Subject: [PATCH 11/31] fix scripts --- espresso/scripts/prepare-allocs.sh | 2 +- espresso/scripts/reshape-allocs.jq | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/espresso/scripts/prepare-allocs.sh b/espresso/scripts/prepare-allocs.sh index 85144f4dc4b..b50700f17e1 100755 --- a/espresso/scripts/prepare-allocs.sh +++ b/espresso/scripts/prepare-allocs.sh @@ -95,7 +95,7 @@ kill $ANVIL_PID sleep 1 -jq -S -f "${OP_ROOT}/espresso/scripts/reshape-allocs.jq" \ +"${OP_ROOT}/espresso/scripts/reshape-allocs.jq" \ <(jq .accounts "${ANVIL_STATE_FILE}") \ | jq '{ "alloc": map_values(.state) }' \ > "${DEPLOYMENT_DIR}/deployer_allocs.json" diff --git a/espresso/scripts/reshape-allocs.jq b/espresso/scripts/reshape-allocs.jq index 78a18a4099f..68f54e1daf1 100755 --- a/espresso/scripts/reshape-allocs.jq +++ b/espresso/scripts/reshape-allocs.jq @@ -1,3 +1,4 @@ +#!/bin/bash # Converts output of espresso-dev-node launched with # 'ESPRESSO_DEV_NODE_L1_DEPLOYMENT=dump' to form suitable # for e2e testing harness. From ebb8e766f5f4f53eda4840323e35383ce296af4a Mon Sep 17 00:00:00 2001 From: Sishan Long Date: Wed, 20 Aug 2025 09:21:15 -0700 Subject: [PATCH 12/31] Add op-batcher-tee image in CI (#210) * push op-batcher-tee image init * fix tag and push * test image creation without enclaver * try to use env * fix enclaver download * use env in docker images yml * restore other task * remove unneeded steps --- .github/workflows/docker-images.yml | 97 +++++++++++++++++++++++ espresso/docker/op-stack/Dockerfile | 2 - espresso/scripts/batcher-enclave-image.sh | 21 ++--- 3 files changed, 102 insertions(+), 18 deletions(-) diff --git a/.github/workflows/docker-images.yml b/.github/workflows/docker-images.yml index bdb254c9983..250d22488b1 100644 --- a/.github/workflows/docker-images.yml +++ b/.github/workflows/docker-images.yml @@ -394,3 +394,100 @@ jobs: TARGET_BASE_IMAGE=alpine:3.22 TARGETOS=linux TARGETARCH=amd64 + + build-op-batcher-tee: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + env: + ENCLAVE_APP_IMAGE: op-batcher-enclave:app + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install just + uses: extractions/setup-just@v2 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Install dasel + run: | + curl -sSL "https://github.com/TomWright/dasel/releases/latest/download/dasel_linux_amd64" -o /tmp/dasel + sudo mv /tmp/dasel /usr/local/bin/dasel + sudo chmod +x /usr/local/bin/dasel + dasel --version + + - name: Check for package.json + id: check-package + run: | + if [ -f "package.json" ]; then + echo "has-package=true" >> $GITHUB_OUTPUT + else + echo "has-package=false" >> $GITHUB_OUTPUT + fi + + - name: Setup Node.js + if: steps.check-package.outputs.has-package == 'true' + uses: actions/setup-node@v4 + with: + node-version: '18' + cache: 'npm' + + - name: Run Enclaver installation + run: | + echo "Downloading and installing Enclaver..." + ARCH=$(uname -m) + LATEST_RELEASE=$(curl -s https://api.github.com/repositories/516492075/releases/latest) + DOWNLOAD_URL=$(echo "$LATEST_RELEASE" | jq -r ".assets[] | select(.name | test(\"^enclaver-linux-$ARCH.*tar.gz$\")) | .browser_download_url") + if [ -z "$DOWNLOAD_URL" ]; then + echo "Could not find Enclaver download URL" + exit 1 + fi + curl -L "$DOWNLOAD_URL" -o enclaver.tar.gz + tar xzf enclaver.tar.gz + sudo install enclaver-*/enclaver /usr/local/bin/ + rm -rf enclaver.tar.gz enclaver-* + enclaver --version + + - name: Install dependencies + if: steps.check-package.outputs.has-package == 'true' + run: npm ci + + - name: Build op-batcher enclave image + run: | + cd espresso + ./scripts/batcher-enclave-image.sh + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE_PREFIX }}/op-batcher-tee + tags: | + type=ref,event=branch + type=ref,event=pr + type=sha,prefix={{branch}}-,enable={{is_default_branch}} + type=raw,value=latest,enable={{is_default_branch}} + type=raw,value=pr-${{ github.event.number }},enable=${{ github.event_name == 'pull_request' }} + + - name: Tag and push op-batcher-tee image + run: | + docker tag "${{ env.ENCLAVE_APP_IMAGE }}" ${{ steps.meta.outputs.tags }} + docker push ${{ steps.meta.outputs.tags }} diff --git a/espresso/docker/op-stack/Dockerfile b/espresso/docker/op-stack/Dockerfile index f45e08d9e24..027f4de57ea 100644 --- a/espresso/docker/op-stack/Dockerfile +++ b/espresso/docker/op-stack/Dockerfile @@ -113,8 +113,6 @@ COPY --from=op-node-builder /app/op-node/bin/op-node /usr/local/bin/ # Create config directory RUN mkdir -p /config -# Include the config. -COPY espresso/deployment/l2-config /config CMD ["op-node"] diff --git a/espresso/scripts/batcher-enclave-image.sh b/espresso/scripts/batcher-enclave-image.sh index 37be107cb4e..fd7f976548e 100755 --- a/espresso/scripts/batcher-enclave-image.sh +++ b/espresso/scripts/batcher-enclave-image.sh @@ -20,24 +20,13 @@ export ENCLAVE_APP_IMAGE="op-batcher-enclave:app" export ENCLAVE_TARGET_IMAGE="op-batcher-enclaver:tests" export MANIFEST_FILE="batcher-enclave.yaml" -# Required for enclave operations -if [[ ! -e /dev/nitro_enclaves ]]; then - echo "Error: /dev/nitro_enclaves device not found. Are you running on a Nitro-enabled instance?" - exit 1 -fi - -# Check if docker is running -if ! docker info > /dev/null 2>&1; then - echo "Error: Docker is not running or not accessible" - exit 1 -fi echo "Using HOST_IP: $HOST_IP" echo "Ports -> L1:$L1_HTTP_PORT L2:$OP_HTTP_PORT Rollup:$ROLLUP_PORT EspressoAPI:$ESPRESSO_SEQUENCER_API_PORT" # Step 1: Build the Docker image using your existing Dockerfile echo "Building Docker image..." -docker build -t $ENCLAVE_APP_IMAGE \ +docker build -t "$ENCLAVE_APP_IMAGE" \ -f ../ops/docker/op-stack-go/Dockerfile \ --target op-batcher-enclave-target \ --build-arg ENCLAVE_BATCHER_ARGS="--l1-eth-rpc=http://$HOST_IP:$L1_HTTP_PORT \ @@ -58,7 +47,7 @@ fi # Step 2: Create enclaver manifest echo "Creating enclaver manifest..." -cat > $MANIFEST_FILE << EOL +cat > "$MANIFEST_FILE" << EOL version: v1 name: "op-batcher-enclave" target: "$ENCLAVE_TARGET_IMAGE" @@ -77,18 +66,18 @@ egress: EOL echo "Manifest created:" -cat $MANIFEST_FILE +cat "$MANIFEST_FILE" # Step 3: Build the enclave echo "Building enclave..." -sudo enclaver build --file $MANIFEST_FILE +sudo enclaver build --file "$MANIFEST_FILE" if [ $? -ne 0 ]; then echo "Failed to build enclave" exit 1 fi -# Step 4: Run the enclave +# Step 4: Run the enclave (commented out as in original) # echo "Running enclave..." # docker run --rm --privileged --net=host \ # --name batcher-enclaver-$RANDOM \ From 30d4a4ef496d3c87d2d5e682f175be54f6cb39aa Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Wed, 20 Aug 2025 18:16:26 +0000 Subject: [PATCH 13/31] special case to common case --- op-batcher/enclave-entrypoint.bash | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/op-batcher/enclave-entrypoint.bash b/op-batcher/enclave-entrypoint.bash index 763ea5bfc3b..a536b0d8be4 100644 --- a/op-batcher/enclave-entrypoint.bash +++ b/op-batcher/enclave-entrypoint.bash @@ -126,9 +126,8 @@ while [ $# -gt 0 ]; do value="$1" fi - # SPECIAL CASE: espresso-url may be a comma list. Either split here, - # or (simpler) pass the flag twice at build time. See note below. - if [[ "$flag" == "--espresso-url" && "$value" == *","* ]]; then + # Handle comma-separated values for any flag + if [[ "$value" == *","* ]]; then IFS=',' read -r -a parts <<< "$value" for part in "${parts[@]}"; do if ! new_url=$(launch_socat "$part" "$SOCAT_PORT"); then From 2901aef5a3b03c7a7c86ac76b32f411d22322769 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Wed, 20 Aug 2025 18:33:22 +0000 Subject: [PATCH 14/31] use default for op-batcher and tee for op-batcher-tee --- README_ESPRESSO.md | 6 +++--- espresso/docker-compose.yml | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/README_ESPRESSO.md b/README_ESPRESSO.md index 1cd655c8fdd..2e9538e6e16 100644 --- a/README_ESPRESSO.md +++ b/README_ESPRESSO.md @@ -299,13 +299,13 @@ docker compose down -v --remove-orphans ./scripts/batcher-enclave-image.sh ``` -* Build and start all services in the background. If you're not running on a machine with AWS Nitro Enclaves enabled, use the `nontee` profile instead. +* Build and start all services in the background. ```console docker compose up --build -d ``` -or +If you're on a machine with AWS Nitro Enclaves enabled, use the `tee` profile instead to start the enclave batcher. ```console -docker compose up --build -d --profile nontee +docker compose up --build -d --profile tee ``` * Run the services and check the log. diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index c29d332026f..2bfb095f1ae 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -266,8 +266,8 @@ services: - --l1.epoch-poll-interval=1s restart: "no" - op-batcher-non-tee: - profiles: ["nontee"] + op-batcher: + profiles: ["default"] build: context: ../ dockerfile: espresso/docker/op-stack/Dockerfile @@ -303,7 +303,8 @@ services: - --max-channel-duration=1 - --target-num-frames=1 - op-batcher: + op-batcher-tee: + profiles: ["tee"] image: ${OP_BATCHER_ENCLAVE_IMAGE:-op-batcher-enclaver:tests} depends_on: l1-geth: From 3b31e3075f11c3f1765481cbd5a255d890c89419 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Wed, 20 Aug 2025 18:48:25 +0000 Subject: [PATCH 15/31] fix double ports mapping --- espresso/docker-compose.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index 7eb12b0960a..793182dbd28 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -170,8 +170,6 @@ services: condition: service_healthy l1-validator: condition: service_started - ports: - - "${ROLLUP_PORT}:${ROLLUP_PORT}" environment: OP_NODE_L1_ETH_RPC: http://l1-geth:${L1_HTTP_PORT} OP_NODE_L1_BEACON: http://l1-beacon:${L1_BEACON_PORT} From b411171531cd0d410b0b7f9b298009482e728379 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Wed, 20 Aug 2025 20:00:24 +0000 Subject: [PATCH 16/31] fix batcher restart test --- README_ESPRESSO.md | 2 +- espresso/.env | 2 ++ espresso/docker-compose.yml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README_ESPRESSO.md b/README_ESPRESSO.md index 5b7502f0a07..9d425722d16 100644 --- a/README_ESPRESSO.md +++ b/README_ESPRESSO.md @@ -305,7 +305,7 @@ docker compose up --build -d ``` If you're on a machine with AWS Nitro Enclaves enabled, use the `tee` profile instead to start the enclave batcher. ```console -docker compose up --build -d --profile tee +COMPOSE_PROFILES=tee docker compose up --build -d ``` * Run the services and check the log. diff --git a/espresso/.env b/espresso/.env index d0b0d91360e..2f7f1164279 100644 --- a/espresso/.env +++ b/espresso/.env @@ -36,3 +36,5 @@ OPERATOR_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 L1_CHAIN_ID=11155111 L2_CHAIN_ID=22266222 + +COMPOSE_PROFILES=default diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index 793182dbd28..b19b7078761 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -311,7 +311,7 @@ services: depends_on: l1-geth: condition: service_healthy - op-geth: + op-geth-sequencer: condition: service_started op-node-sequencer: condition: service_started From d28e81a26cd80dd096adf6491760a2d7480d5b93 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Thu, 21 Aug 2025 18:43:10 +0000 Subject: [PATCH 17/31] add a script to use enclave tool --- .../scripts/batcher-enclave-tool-image.sh | 75 +++++++++++++++++++ op-batcher/enclave-entrypoint.bash | 6 +- 2 files changed, 78 insertions(+), 3 deletions(-) create mode 100755 espresso/scripts/batcher-enclave-tool-image.sh diff --git a/espresso/scripts/batcher-enclave-tool-image.sh b/espresso/scripts/batcher-enclave-tool-image.sh new file mode 100755 index 00000000000..e33d024c1b6 --- /dev/null +++ b/espresso/scripts/batcher-enclave-tool-image.sh @@ -0,0 +1,75 @@ +#!/bin/bash +set -euo pipefail + +# --- load .env --- +SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +ENV_FILE="${SCRIPT_DIR}/../.env" +if [[ ! -f "$ENV_FILE" ]]; then + echo "Error: $ENV_FILE not found"; exit 1 +fi +# export everything we source +set -a +# shellcheck disable=SC1090 +source "$ENV_FILE" +set +a + +# Configuration +# NOTE: if loopback doesn't work from inside the enclave, set HOST_IP=host +HOST_IP="${HOST_IP:-127.0.0.1}" +TAG="${TAG:-op-batcher-enclavetool}" + +echo "Using HOST_IP: $HOST_IP" +echo "Ports -> L1:$L1_HTTP_PORT L2:$OP_HTTP_PORT Rollup:$ROLLUP_PORT EspressoAPI:$ESPRESSO_SEQUENCER_API_PORT" + +# Build enclave-tools if not already built +if [[ ! -f "../op-batcher/bin/enclave-tools" ]]; then + echo "Building enclave-tools..." + cd ../op-batcher + just enclave-tools + cd - +fi + +# Batcher arguments for both build and run +BATCHER_ARGS="--l1-eth-rpc=http://$HOST_IP:$L1_HTTP_PORT,--l2-eth-rpc=http://$HOST_IP:$OP_HTTP_PORT,--rollup-rpc=http://$HOST_IP:$ROLLUP_PORT,--espresso-url=http://$HOST_IP:$ESPRESSO_SEQUENCER_API_PORT,--espresso-url=http://$HOST_IP:$ESPRESSO_SEQUENCER_API_PORT,--testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80,--mnemonic=test test test test test test test test test test test junk,--hd-path=m/44'/60'/0'/0/0,--throttle-threshold=0,--max-channel-duration=1,--target-num-frames=1,--espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" + +# Use enclave-tools to build the image +echo "Building enclave image using enclave-tools..." +BUILD_OUTPUT=$(../op-batcher/bin/enclave-tools build \ + --op-root ../ \ + --tag "$TAG" \ + --args "$BATCHER_ARGS" 2>&1) + +if [ $? -ne 0 ]; then + echo "Failed to build enclave image" + exit 1 +fi + +echo "$BUILD_OUTPUT" + +# Extract PCR0 from build output +PCR0=$(echo "$BUILD_OUTPUT" | grep "PCR0:" | sed 's/.*PCR0: //') + +# Get batch authenticator address from deployment state +BATCH_AUTHENTICATOR_ADDRESS=$(jq -r '.opChainDeployments[0].batchAuthenticatorAddress' deployment/deployer/state.json) + +if [[ -n "$PCR0" && -n "$BATCH_AUTHENTICATOR_ADDRESS" && -n "$OPERATOR_PRIVATE_KEY" ]]; then + echo "Registering PCR0: $PCR0 with authenticator: $BATCH_AUTHENTICATOR_ADDRESS" + ../op-batcher/bin/enclave-tools register \ + --authenticator "$BATCH_AUTHENTICATOR_ADDRESS" \ + --l1-url "http://$HOST_IP:$L1_HTTP_PORT" \ + --private-key "$OPERATOR_PRIVATE_KEY" \ + --pcr0 "$PCR0" + + if [ $? -ne 0 ]; then + echo "Failed to register PCR0, continuing anyway..." + fi +else + echo "Skipping registration - missing PCR0 ($PCR0), BATCH_AUTHENTICATOR_ADDRESS ($BATCH_AUTHENTICATOR_ADDRESS), or OPERATOR_PRIVATE_KEY" +fi + +# Run the enclave +echo "Running enclave..." +echo "Command: ../op-batcher/bin/enclave-tools run --image \"$TAG\" --args \"$BATCHER_ARGS\"" +../op-batcher/bin/enclave-tools run \ + --image "$TAG" \ + --args "$BATCHER_ARGS" & diff --git a/op-batcher/enclave-entrypoint.bash b/op-batcher/enclave-entrypoint.bash index a536b0d8be4..f09d11252cd 100644 --- a/op-batcher/enclave-entrypoint.bash +++ b/op-batcher/enclave-entrypoint.bash @@ -31,7 +31,7 @@ unset http_proxy HTTP_PROXY https_proxy HTTPS_PROXY NC_PORT=8337 received_args=() -echo "Starting nc listener on port $NC_PORT (10 second timeout)" +echo "Starting nc listener on port $NC_PORT (60 second timeout)" { # Read null-separated arguments until we get \0\0 while IFS= read -r -d '' arg; do @@ -41,10 +41,10 @@ echo "Starting nc listener on port $NC_PORT (10 second timeout)" fi received_args+=("$arg") done -} < <(nc -l -p "$NC_PORT" -w 10) +} < <(nc -l -p "$NC_PORT" -w 60) if [ ${#received_args[@]} -eq 0 ]; then - echo "Warning: No arguments received via nc listener within 10 seconds, continuing with existing arguments" + echo "Warning: No arguments received via nc listener within 60 seconds, continuing with existing arguments" else echo "Received ${#received_args[@]} arguments via nc, appending to existing arguments" # Append received arguments to existing positional parameters From d0f8ef196bf18c7c11e97edeacfe1685b92d6dfe Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Sat, 23 Aug 2025 00:23:14 +0000 Subject: [PATCH 18/31] works to some extend --- README_ESPRESSO.md | 2 +- espresso/docker-compose.yml | 42 +++++++++++++- espresso/docker/op-stack/Dockerfile | 58 +++++++++++++++++++ .../scripts/batcher-enclave-tool-image.sh | 43 +++++++++----- 4 files changed, 130 insertions(+), 15 deletions(-) diff --git a/README_ESPRESSO.md b/README_ESPRESSO.md index 9d425722d16..f070607a46d 100644 --- a/README_ESPRESSO.md +++ b/README_ESPRESSO.md @@ -296,7 +296,7 @@ docker compose down -v --remove-orphans * Make sure you're on a machine with AWS Nitro Enclaves enabled. Build the enclave image. ```console -./scripts/batcher-enclave-image.sh +./scripts/batcher-enclave-tool-image.sh ``` * Build and start all services in the background. diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index b19b7078761..f1236267376 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -305,9 +305,31 @@ services: - --max-channel-duration=1 - --target-num-frames=1 + # HTTP proxy for enclave Odyn proxy requirement + http-proxy: + image: alpine:latest + command: > + sh -c " + apk add --no-cache tinyproxy && + echo 'Allow 127.0.0.1' >> /etc/tinyproxy/tinyproxy.conf && + echo 'Allow 0.0.0.0/0' >> /etc/tinyproxy/tinyproxy.conf && + echo 'DisableViaHeader Yes' >> /etc/tinyproxy/tinyproxy.conf && + tinyproxy -d + " + ports: + - "3128:8888" + networks: + default: + aliases: + - proxy + op-batcher-tee: profiles: ["tee"] - image: ${OP_BATCHER_ENCLAVE_IMAGE:-op-batcher-enclaver:tests} + build: + context: ../ + dockerfile: espresso/docker/op-stack/Dockerfile + target: op-batcher-enclave-target + image: op-batcher-tee:espresso depends_on: l1-geth: condition: service_healthy @@ -319,11 +341,29 @@ services: condition: service_started l2-genesis: condition: service_completed_successfully + http-proxy: + condition: service_started network_mode: "host" + environment: + L1_RPC: http://127.0.0.1:${L1_HTTP_PORT} + OP_BATCHER_L1_ETH_RPC: http://127.0.0.1:${L1_HTTP_PORT} + OP_BATCHER_L2_ETH_RPC: http://127.0.0.1:${OP_HTTP_PORT} + OP_BATCHER_ROLLUP_RPC: http://127.0.0.1:${ROLLUP_PORT} + OP_BATCHER_ESPRESSO_URL: http://127.0.0.1:${ESPRESSO_SEQUENCER_API_PORT} + HOST_IP: 127.0.0.1 + http_proxy: http://127.0.0.1:3128 + HTTP_PROXY: http://127.0.0.1:3128 + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ..:/source:ro + - ./scripts/batcher-enclave-tool-image.sh:/app/espresso/scripts/batcher-enclave-tool-image.sh:ro + - /tmp:/tmp privileged: true devices: - /dev/nitro_enclaves:/dev/nitro_enclaves restart: "no" + command: + - /app/espresso/scripts/batcher-enclave-tool-image.sh op-proposer: diff --git a/espresso/docker/op-stack/Dockerfile b/espresso/docker/op-stack/Dockerfile index 2f1d8efbd2c..4789b056b31 100644 --- a/espresso/docker/op-stack/Dockerfile +++ b/espresso/docker/op-stack/Dockerfile @@ -91,6 +91,13 @@ WORKDIR /app/op-batcher ENV GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$OP_BATCHER_VERSION" RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build just op-batcher +# Build enclave-tools +FROM op-cgo-builder AS enclave-tools-builder +ARG ENCLAVE_TOOLS_VERSION=v0.0.0 +WORKDIR /app/op-batcher +ENV GOOS=$TARGETOS GOARCH=$TARGETARCH GITCOMMIT=$GIT_COMMIT GITDATE=$GIT_DATE VERSION="$ENCLAVE_TOOLS_VERSION" +RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build just enclave-tools + # Build op-proposer FROM builder AS op-proposer-builder ARG OP_PROPOSER_VERSION=v0.0.0 @@ -122,6 +129,57 @@ ADD "https://github.com/EspressoSystems/ark-srs/releases/download/v0.2.0/kzg10-a COPY --from=op-batcher-builder /app/op-batcher/bin/op-batcher /usr/local/bin/ CMD ["op-batcher"] +FROM $TARGET_BASE_IMAGE AS op-batcher-enclave-target +RUN apk add gcc docker bash jq curl wget +# Install enclaver for EIF creation +RUN curl -L https://github.com/enclaver-io/enclaver/releases/download/v0.5.0/enclaver-linux-x86_64-v0.5.0.tar.gz | tar xz --strip-components=1 -C /usr/local/bin enclaver-linux-x86_64-v0.5.0/enclaver +ENV AZTEC_SRS_PATH /aztec/kzg10-aztec20-srs-1048584.bin +ADD "https://github.com/EspressoSystems/ark-srs/releases/download/v0.2.0/kzg10-aztec20-srs-1048584.bin" /aztec/kzg10-aztec20-srs-1048584.bin +COPY --from=enclave-tools-builder /app/op-batcher/bin/enclave-tools /usr/local/bin/ +# Copy go.mod to establish monorepo root for enclave-tools +COPY --from=enclave-tools-builder /app/go.mod /app/go.mod +# Copy entire packages and op-e2e directories to satisfy op-e2e config dependencies +COPY --from=enclave-tools-builder /app/packages /app/packages +COPY --from=enclave-tools-builder /app/op-e2e /app/op-e2e +# Copy ops directory required by enclave-tools +COPY --from=enclave-tools-builder /app/ops /app/ops +# Copy entire espresso directory and op-batcher to get all dependencies +COPY --from=enclave-tools-builder /app/espresso /app/espresso +COPY --from=enclave-tools-builder /app/op-batcher /app/op-batcher +# Create .env file with necessary variables (since it's excluded by .gitignore) +RUN cat > /app/espresso/.env << 'EOF' +# Environment variables for enclave +ESPRESSO_DEV_NODE_L1_DEPLOYMENT=skip +ESPRESSO_SEQUENCER_ESP_TOKEN_ADDRESS=0x00c042c4d5d913277ce16611a2ce6e9003554ad5 +ESPRESSO_SEQUENCER_PLONK_VERIFIER_V2_ADDRESS=0x422a3492e218383753d8006c7bfa97815b44373f +ESPRESSO_SEQUENCER_STAKE_TABLE_ADDRESS=0x63e6dde6763c3466c7b45be880f7ee5dc2ca3e25 +ESPRESSO_SEQUENCER_LIGHT_CLIENT_PROXY_ADDRESS=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797 +ESPRESSO_SEQUENCER_FEE_CONTRACT_PROXY_ADDRESS=0x72ae2643518179cf01bca3278a37cead408de8b2 +ESPRESSO_SEQUENCER_FEE_CONTRACT_ADDRESS=0x8f0342a7060e76dfc7f6e9debfad9b9ec919952c +ESPRESSO_SEQUENCER_STAKE_TABLE_PROXY_ADDRESS=0x9f5eac3d8e082f47631f1551f1343f23cd427162 +ESPRESSO_SEQUENCER_ESP_TOKEN_PROXY_ADDRESS=0x9fcf7d13d10dedf17d0f24c62f0cf4ed462f65b7 +ESPRESSO_SEQUENCER_PLONK_VERIFIER_ADDRESS=0xb4b46bdaa835f8e4b4d8e208b6559cd267851051 +ESPRESSO_SEQUENCER_API_PORT=24000 +ESPRESSO_DEV_NODE_PORT=24002 +ESPRESSO_BUILDER_PORT=31003 +L1_ENGINE_PORT=8551 +L1_HTTP_PORT=8545 +L1_BEACON_PORT=5052 +ROLLUP_PORT=9545 +VERIFIER_PORT=9546 +CAFF_PORT=9547 +OP_ENGINE_PORT=8552 +OP_HTTP_PORT=8546 +OPERATOR_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +OPERATOR_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 +L1_CHAIN_ID=11155111 +L2_CHAIN_ID=22266222 +COMPOSE_PROFILES=default +EOF +RUN chmod +x /app/espresso/scripts/batcher-enclave-tool-image.sh /app/espresso/scripts/prepare-allocs.sh +WORKDIR /app +CMD ["enclave-tools"] + FROM $TARGET_BASE_IMAGE AS op-proposer-target RUN apk add jq COPY --from=op-proposer-builder /app/op-proposer/bin/op-proposer /usr/local/bin/ diff --git a/espresso/scripts/batcher-enclave-tool-image.sh b/espresso/scripts/batcher-enclave-tool-image.sh index e33d024c1b6..99b1c419759 100755 --- a/espresso/scripts/batcher-enclave-tool-image.sh +++ b/espresso/scripts/batcher-enclave-tool-image.sh @@ -22,9 +22,9 @@ echo "Using HOST_IP: $HOST_IP" echo "Ports -> L1:$L1_HTTP_PORT L2:$OP_HTTP_PORT Rollup:$ROLLUP_PORT EspressoAPI:$ESPRESSO_SEQUENCER_API_PORT" # Build enclave-tools if not already built -if [[ ! -f "../op-batcher/bin/enclave-tools" ]]; then +if [[ ! -f "/app/op-batcher/bin/enclave-tools" ]]; then echo "Building enclave-tools..." - cd ../op-batcher + cd /app/op-batcher just enclave-tools cd - fi @@ -34,27 +34,44 @@ BATCHER_ARGS="--l1-eth-rpc=http://$HOST_IP:$L1_HTTP_PORT,--l2-eth-rpc=http://$HO # Use enclave-tools to build the image echo "Building enclave image using enclave-tools..." -BUILD_OUTPUT=$(../op-batcher/bin/enclave-tools build \ - --op-root ../ \ +echo "Command: /app/op-batcher/bin/enclave-tools build --op-root /source --tag \"$TAG\" --args \"$BATCHER_ARGS\"" +echo "Checking if enclaver is available..." +which enclaver || echo "enclaver not found in PATH" +echo "Checking Docker availability..." +docker version || echo "Docker not accessible" +echo "Starting enclave build..." + +# Change to source directory for build context +cd /source + +# Run the command and capture output while also showing it in real-time +/app/op-batcher/bin/enclave-tools build \ + --op-root /source \ --tag "$TAG" \ - --args "$BATCHER_ARGS" 2>&1) + --args "$BATCHER_ARGS" 2>&1 | tee /tmp/build_output.log + +BUILD_EXIT_CODE=${PIPESTATUS[0]} +BUILD_OUTPUT=$(cat /tmp/build_output.log) -if [ $? -ne 0 ]; then - echo "Failed to build enclave image" +if [ $BUILD_EXIT_CODE -ne 0 ]; then + echo "Failed to build enclave image (exit code: $BUILD_EXIT_CODE)" + echo "Build output was:" + echo "$BUILD_OUTPUT" exit 1 fi -echo "$BUILD_OUTPUT" +echo "Build completed successfully" # Extract PCR0 from build output PCR0=$(echo "$BUILD_OUTPUT" | grep "PCR0:" | sed 's/.*PCR0: //') # Get batch authenticator address from deployment state -BATCH_AUTHENTICATOR_ADDRESS=$(jq -r '.opChainDeployments[0].batchAuthenticatorAddress' deployment/deployer/state.json) +BATCH_AUTHENTICATOR_ADDRESS=$(jq -r '.opChainDeployments[0].batchAuthenticatorAddress' /source/espresso/deployment/deployer/state.json) if [[ -n "$PCR0" && -n "$BATCH_AUTHENTICATOR_ADDRESS" && -n "$OPERATOR_PRIVATE_KEY" ]]; then echo "Registering PCR0: $PCR0 with authenticator: $BATCH_AUTHENTICATOR_ADDRESS" - ../op-batcher/bin/enclave-tools register \ + # Use HOST_IP for network communication + /app/op-batcher/bin/enclave-tools register \ --authenticator "$BATCH_AUTHENTICATOR_ADDRESS" \ --l1-url "http://$HOST_IP:$L1_HTTP_PORT" \ --private-key "$OPERATOR_PRIVATE_KEY" \ @@ -69,7 +86,7 @@ fi # Run the enclave echo "Running enclave..." -echo "Command: ../op-batcher/bin/enclave-tools run --image \"$TAG\" --args \"$BATCHER_ARGS\"" -../op-batcher/bin/enclave-tools run \ +echo "Command: /app/op-batcher/bin/enclave-tools run --image \"$TAG\" --args \"$BATCHER_ARGS\"" +/app/op-batcher/bin/enclave-tools run \ --image "$TAG" \ - --args "$BATCHER_ARGS" & + --args "$BATCHER_ARGS" From 08b335e82589a8323366111a8c71cbc85020d537 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Sat, 23 Aug 2025 05:21:02 +0000 Subject: [PATCH 19/31] also works for passing in arguments from cmd --- espresso/docker-compose.yml | 10 ++-- .../scripts/batcher-enclave-tool-image.sh | 55 ++++++++++++++++--- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index f1236267376..40679c45275 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -345,12 +345,6 @@ services: condition: service_started network_mode: "host" environment: - L1_RPC: http://127.0.0.1:${L1_HTTP_PORT} - OP_BATCHER_L1_ETH_RPC: http://127.0.0.1:${L1_HTTP_PORT} - OP_BATCHER_L2_ETH_RPC: http://127.0.0.1:${OP_HTTP_PORT} - OP_BATCHER_ROLLUP_RPC: http://127.0.0.1:${ROLLUP_PORT} - OP_BATCHER_ESPRESSO_URL: http://127.0.0.1:${ESPRESSO_SEQUENCER_API_PORT} - HOST_IP: 127.0.0.1 http_proxy: http://127.0.0.1:3128 HTTP_PROXY: http://127.0.0.1:3128 volumes: @@ -364,6 +358,10 @@ services: restart: "no" command: - /app/espresso/scripts/batcher-enclave-tool-image.sh + - "http://127.0.0.1:${L1_HTTP_PORT}" + - "http://127.0.0.1:${OP_HTTP_PORT}" + - "http://127.0.0.1:${ROLLUP_PORT}" + - "http://127.0.0.1:${ESPRESSO_SEQUENCER_API_PORT}" op-proposer: diff --git a/espresso/scripts/batcher-enclave-tool-image.sh b/espresso/scripts/batcher-enclave-tool-image.sh index 99b1c419759..9a0daa2d09a 100755 --- a/espresso/scripts/batcher-enclave-tool-image.sh +++ b/espresso/scripts/batcher-enclave-tool-image.sh @@ -1,6 +1,21 @@ #!/bin/bash set -euo pipefail +# Parse command line arguments +if [[ $# -ne 4 ]]; then + echo "Usage: $0 " + echo "Example: $0 http://127.0.0.1:8545 http://127.0.0.1:8546 http://127.0.0.1:9545 http://127.0.0.1:24000" + exit 1 +fi + +L1_RPC_URL="$1" +L2_RPC_URL="$2" +ROLLUP_RPC_URL="$3" +ESPRESSO_URL="$4" + +# Extract HOST_IP from L1_RPC_URL for registration purposes +HOST_IP=$(echo "$L1_RPC_URL" | sed -n 's|^https\?://\([^:]*\).*|\1|p') + # --- load .env --- SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" ENV_FILE="${SCRIPT_DIR}/../.env" @@ -14,12 +29,14 @@ source "$ENV_FILE" set +a # Configuration -# NOTE: if loopback doesn't work from inside the enclave, set HOST_IP=host -HOST_IP="${HOST_IP:-127.0.0.1}" TAG="${TAG:-op-batcher-enclavetool}" -echo "Using HOST_IP: $HOST_IP" -echo "Ports -> L1:$L1_HTTP_PORT L2:$OP_HTTP_PORT Rollup:$ROLLUP_PORT EspressoAPI:$ESPRESSO_SEQUENCER_API_PORT" +echo "Service URLs:" +echo " L1 RPC: $L1_RPC_URL" +echo " L2 RPC: $L2_RPC_URL" +echo " Rollup RPC: $ROLLUP_RPC_URL" +echo " Espresso API: $ESPRESSO_URL" +echo " Host IP (for registration): $HOST_IP" # Build enclave-tools if not already built if [[ ! -f "/app/op-batcher/bin/enclave-tools" ]]; then @@ -30,7 +47,7 @@ if [[ ! -f "/app/op-batcher/bin/enclave-tools" ]]; then fi # Batcher arguments for both build and run -BATCHER_ARGS="--l1-eth-rpc=http://$HOST_IP:$L1_HTTP_PORT,--l2-eth-rpc=http://$HOST_IP:$OP_HTTP_PORT,--rollup-rpc=http://$HOST_IP:$ROLLUP_PORT,--espresso-url=http://$HOST_IP:$ESPRESSO_SEQUENCER_API_PORT,--espresso-url=http://$HOST_IP:$ESPRESSO_SEQUENCER_API_PORT,--testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80,--mnemonic=test test test test test test test test test test test junk,--hd-path=m/44'/60'/0'/0/0,--throttle-threshold=0,--max-channel-duration=1,--target-num-frames=1,--espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" +BATCHER_ARGS="--l1-eth-rpc=$L1_RPC_URL,--l2-eth-rpc=$L2_RPC_URL,--rollup-rpc=$ROLLUP_RPC_URL,--espresso-url=$ESPRESSO_URL,--espresso-url=$ESPRESSO_URL,--testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80,--mnemonic=test test test test test test test test test test test junk,--hd-path=m/44'/60'/0'/0/0,--throttle-threshold=0,--max-channel-duration=1,--target-num-frames=1,--espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" # Use enclave-tools to build the image echo "Building enclave image using enclave-tools..." @@ -70,10 +87,10 @@ BATCH_AUTHENTICATOR_ADDRESS=$(jq -r '.opChainDeployments[0].batchAuthenticatorAd if [[ -n "$PCR0" && -n "$BATCH_AUTHENTICATOR_ADDRESS" && -n "$OPERATOR_PRIVATE_KEY" ]]; then echo "Registering PCR0: $PCR0 with authenticator: $BATCH_AUTHENTICATOR_ADDRESS" - # Use HOST_IP for network communication + # Use L1_RPC_URL for registration /app/op-batcher/bin/enclave-tools register \ --authenticator "$BATCH_AUTHENTICATOR_ADDRESS" \ - --l1-url "http://$HOST_IP:$L1_HTTP_PORT" \ + --l1-url "$L1_RPC_URL" \ --private-key "$OPERATOR_PRIVATE_KEY" \ --pcr0 "$PCR0" @@ -89,4 +106,26 @@ echo "Running enclave..." echo "Command: /app/op-batcher/bin/enclave-tools run --image \"$TAG\" --args \"$BATCHER_ARGS\"" /app/op-batcher/bin/enclave-tools run \ --image "$TAG" \ - --args "$BATCHER_ARGS" + --args "$BATCHER_ARGS" & + +# Get the enclave-tools PID +ENCLAVE_TOOLS_PID=$! +echo "Enclave-tools started with PID: $ENCLAVE_TOOLS_PID" + +# Keep the script running and monitor the enclave +echo "Monitoring enclave..." +while true; do + # Check if enclave-tools process is still running + if ! kill -0 $ENCLAVE_TOOLS_PID 2>/dev/null; then + echo "Enclave-tools process has exited" + break + fi + + # Check if any enclave is running + RUNNING_ENCLAVES=$(sudo nitro-cli describe-enclaves 2>/dev/null | jq length 2>/dev/null || echo "0") + echo "$(date): Running enclaves: $RUNNING_ENCLAVES" + + sleep 10 +done + +echo "Script exiting..." From b8de97266c0acafd6c9c104dfb6318fb75da3663 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Sat, 23 Aug 2025 05:32:31 +0000 Subject: [PATCH 20/31] try to upload the image --- .github/workflows/docker-images.yml | 758 ++++++++++++++-------------- 1 file changed, 379 insertions(+), 379 deletions(-) diff --git a/.github/workflows/docker-images.yml b/.github/workflows/docker-images.yml index 250d22488b1..742d7b366d6 100644 --- a/.github/workflows/docker-images.yml +++ b/.github/workflows/docker-images.yml @@ -19,280 +19,383 @@ env: IMAGE_PREFIX: ghcr.io/${{ github.repository }} jobs: - build-l1-geth: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install just - uses: extractions/setup-just@v2 - - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: 20.x - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Install dasel - run: | - curl -sSL "https://github.com/TomWright/dasel/releases/latest/download/dasel_linux_amd64" -o /tmp/dasel - sudo mv /tmp/dasel /usr/local/bin/dasel - sudo chmod +x /usr/local/bin/dasel - dasel --version - - - name: Build op-deployer - run: | - cd op-deployer - just - echo "$(pwd)/bin" >> $GITHUB_PATH - - - name: Compile contracts - run: just compile-contracts - - - name: Prepare allocations - run: | - cd espresso - ./scripts/prepare-allocs.sh - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.IMAGE_PREFIX }}/l1-geth - tags: | - type=ref,event=branch - type=ref,event=pr - type=sha,prefix={{branch}}-,enable={{is_default_branch}} - type=raw,value=latest,enable={{is_default_branch}} - type=raw,value=pr-${{ github.event.number }},enable=${{ github.event_name == 'pull_request' }} - - - name: Build and push L1 Geth - uses: docker/build-push-action@v5 - with: - context: . - file: espresso/docker/l1-geth/Dockerfile - platforms: linux/amd64 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - build-op-geth: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install just - uses: extractions/setup-just@v2 - - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Install dasel - run: | - curl -sSL "https://github.com/TomWright/dasel/releases/latest/download/dasel_linux_amd64" -o /tmp/dasel - sudo mv /tmp/dasel /usr/local/bin/dasel - sudo chmod +x /usr/local/bin/dasel - - - name: Check for package.json - id: check-package - run: | - if [ -f "package.json" ]; then - echo "has-package=true" >> $GITHUB_OUTPUT - else - echo "has-package=false" >> $GITHUB_OUTPUT - fi - - - name: Setup Node.js - if: steps.check-package.outputs.has-package == 'true' - uses: actions/setup-node@v4 - with: - node-version: '18' - cache: 'npm' - - - name: Install dependencies - if: steps.check-package.outputs.has-package == 'true' - run: npm ci - - - name: Build op-deployer - run: | - cd op-deployer - just - echo "$(pwd)/bin" >> $GITHUB_PATH - - - name: Compile contracts - run: just compile-contracts - - - name: Prepare allocations - run: | - cd espresso - ./scripts/prepare-allocs.sh - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.IMAGE_PREFIX }}/op-geth - tags: | - type=ref,event=branch - type=ref,event=pr - type=sha,prefix={{branch}}-,enable={{is_default_branch}} - type=raw,value=latest,enable={{is_default_branch}} - type=raw,value=pr-${{ github.event.number }},enable=${{ github.event_name == 'pull_request' }} - - - name: Build and push OP Geth - uses: docker/build-push-action@v5 - with: - context: . - file: espresso/docker/op-geth/Dockerfile - platforms: linux/amd64 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - build-op-node: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - steps: - - name: Checkout - uses: actions/checkout@v4 + # build-l1-geth: + # runs-on: ubuntu-latest + # permissions: + # contents: read + # packages: write + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + + # - name: Install just + # uses: extractions/setup-just@v2 + + # - name: Install Rust + # uses: actions-rs/toolchain@v1 + # with: + # toolchain: stable + # override: true + + # - name: Setup Node.js + # uses: actions/setup-node@v4 + # with: + # node-version: 20.x + + # - name: Install Foundry + # uses: foundry-rs/foundry-toolchain@v1 + # with: + # version: nightly + + # - name: Install dasel + # run: | + # curl -sSL "https://github.com/TomWright/dasel/releases/latest/download/dasel_linux_amd64" -o /tmp/dasel + # sudo mv /tmp/dasel /usr/local/bin/dasel + # sudo chmod +x /usr/local/bin/dasel + # dasel --version + + # - name: Build op-deployer + # run: | + # cd op-deployer + # just + # echo "$(pwd)/bin" >> $GITHUB_PATH + + # - name: Compile contracts + # run: just compile-contracts + + # - name: Prepare allocations + # run: | + # cd espresso + # ./scripts/prepare-allocs.sh + + # - name: Login to GitHub Container Registry + # uses: docker/login-action@v3 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + + # - name: Extract metadata + # id: meta + # uses: docker/metadata-action@v5 + # with: + # images: ${{ env.IMAGE_PREFIX }}/l1-geth + # tags: | + # type=ref,event=branch + # type=ref,event=pr + # type=sha,prefix={{branch}}-,enable={{is_default_branch}} + # type=raw,value=latest,enable={{is_default_branch}} + # type=raw,value=pr-${{ github.event.number }},enable=${{ github.event_name == 'pull_request' }} + + # - name: Build and push L1 Geth + # uses: docker/build-push-action@v5 + # with: + # context: . + # file: espresso/docker/l1-geth/Dockerfile + # platforms: linux/amd64 + # push: true + # tags: ${{ steps.meta.outputs.tags }} + # labels: ${{ steps.meta.outputs.labels }} + + # build-op-geth: + # runs-on: ubuntu-latest + # permissions: + # contents: read + # packages: write + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + + # - name: Install just + # uses: extractions/setup-just@v2 + + # - name: Install Rust + # uses: actions-rs/toolchain@v1 + # with: + # toolchain: stable + # override: true + + # - name: Install Foundry + # uses: foundry-rs/foundry-toolchain@v1 + # with: + # version: nightly + + # - name: Install dasel + # run: | + # curl -sSL "https://github.com/TomWright/dasel/releases/latest/download/dasel_linux_amd64" -o /tmp/dasel + # sudo mv /tmp/dasel /usr/local/bin/dasel + # sudo chmod +x /usr/local/bin/dasel + + # - name: Check for package.json + # id: check-package + # run: | + # if [ -f "package.json" ]; then + # echo "has-package=true" >> $GITHUB_OUTPUT + # else + # echo "has-package=false" >> $GITHUB_OUTPUT + # fi + + # - name: Setup Node.js + # if: steps.check-package.outputs.has-package == 'true' + # uses: actions/setup-node@v4 + # with: + # node-version: '18' + # cache: 'npm' + + # - name: Install dependencies + # if: steps.check-package.outputs.has-package == 'true' + # run: npm ci + + # - name: Build op-deployer + # run: | + # cd op-deployer + # just + # echo "$(pwd)/bin" >> $GITHUB_PATH + + # - name: Compile contracts + # run: just compile-contracts + + # - name: Prepare allocations + # run: | + # cd espresso + # ./scripts/prepare-allocs.sh + + # - name: Login to GitHub Container Registry + # uses: docker/login-action@v3 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + + # - name: Extract metadata + # id: meta + # uses: docker/metadata-action@v5 + # with: + # images: ${{ env.IMAGE_PREFIX }}/op-geth + # tags: | + # type=ref,event=branch + # type=ref,event=pr + # type=sha,prefix={{branch}}-,enable={{is_default_branch}} + # type=raw,value=latest,enable={{is_default_branch}} + # type=raw,value=pr-${{ github.event.number }},enable=${{ github.event_name == 'pull_request' }} + + # - name: Build and push OP Geth + # uses: docker/build-push-action@v5 + # with: + # context: . + # file: espresso/docker/op-geth/Dockerfile + # platforms: linux/amd64 + # push: true + # tags: ${{ steps.meta.outputs.tags }} + # labels: ${{ steps.meta.outputs.labels }} + + # build-op-node: + # runs-on: ubuntu-latest + # permissions: + # contents: read + # packages: write + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + + # - name: Install just + # uses: extractions/setup-just@v2 + + # - name: Install Rust + # uses: actions-rs/toolchain@v1 + # with: + # toolchain: stable + # override: true + + # - name: Install Foundry + # uses: foundry-rs/foundry-toolchain@v1 + # with: + # version: nightly + + # - name: Install dasel + # run: | + # curl -sSL "https://github.com/TomWright/dasel/releases/latest/download/dasel_linux_amd64" -o /tmp/dasel + # sudo mv /tmp/dasel /usr/local/bin/dasel + # sudo chmod +x /usr/local/bin/dasel + + # - name: Check for package.json + # id: check-package + # run: | + # if [ -f "package.json" ]; then + # echo "has-package=true" >> $GITHUB_OUTPUT + # else + # echo "has-package=false" >> $GITHUB_OUTPUT + # fi + + # - name: Setup Node.js + # if: steps.check-package.outputs.has-package == 'true' + # uses: actions/setup-node@v4 + # with: + # node-version: '18' + # cache: 'npm' + + # - name: Install dependencies + # if: steps.check-package.outputs.has-package == 'true' + # run: npm ci + + # - name: Build op-deployer + # run: | + # cd op-deployer + # just + # echo "$(pwd)/bin" >> $GITHUB_PATH + + # - name: Compile contracts + # run: just compile-contracts + + # - name: Prepare allocations + # run: | + # cd espresso + # ./scripts/prepare-allocs.sh + + # - name: Create l2-config directory + # run: | + # mkdir -p espresso/deployment/l2-config + # echo "Created l2-config directory" + # ls -la espresso/deployment/ + + # - name: Login to GitHub Container Registry + # uses: docker/login-action@v3 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + + # - name: Extract metadata + # id: meta + # uses: docker/metadata-action@v5 + # with: + # images: ${{ env.IMAGE_PREFIX }}/op-node + # tags: | + # type=ref,event=branch + # type=ref,event=pr + # type=sha,prefix={{branch}}-,enable={{is_default_branch}} + # type=raw,value=latest,enable={{is_default_branch}} + # type=raw,value=pr-${{ github.event.number }},enable=${{ github.event_name == 'pull_request' }} + + # - name: Build and push OP Node + # uses: docker/build-push-action@v5 + # with: + # context: . + # file: espresso/docker/op-stack/Dockerfile + # target: op-node-target + # platforms: linux/amd64 + # push: true + # tags: ${{ steps.meta.outputs.tags }} + # labels: ${{ steps.meta.outputs.labels }} + # build-args: | + # TARGET_BASE_IMAGE=alpine:3.22 + # TARGETOS=linux + # TARGETARCH=amd64 + + # build-op-batcher: + # runs-on: ubuntu-latest + # permissions: + # contents: read + # packages: write + # steps: + # - name: Checkout + # uses: actions/checkout@v4 + + # - name: Install just + # uses: extractions/setup-just@v2 + + # - name: Install Rust + # uses: actions-rs/toolchain@v1 + # with: + # toolchain: stable + # override: true + + # - name: Install Foundry + # uses: foundry-rs/foundry-toolchain@v1 + # with: + # version: nightly + + # - name: Install dasel + # run: | + # curl -sSL "https://github.com/TomWright/dasel/releases/latest/download/dasel_linux_amd64" -o /tmp/dasel + # sudo mv /tmp/dasel /usr/local/bin/dasel + # sudo chmod +x /usr/local/bin/dasel + + # - name: Check for package.json + # id: check-package + # run: | + # if [ -f "package.json" ]; then + # echo "has-package=true" >> $GITHUB_OUTPUT + # else + # echo "has-package=false" >> $GITHUB_OUTPUT + # fi + + # - name: Setup Node.js + # if: steps.check-package.outputs.has-package == 'true' + # uses: actions/setup-node@v4 + # with: + # node-version: '18' + # cache: 'npm' + + # - name: Install dependencies + # if: steps.check-package.outputs.has-package == 'true' + # run: npm ci + + # - name: Build op-deployer + # run: | + # cd op-deployer + # just + # echo "$(pwd)/bin" >> $GITHUB_PATH + + # - name: Compile contracts + # run: just compile-contracts + + # - name: Prepare allocations + # run: | + # cd espresso + # ./scripts/prepare-allocs.sh + + # - name: Copy config for op-batcher + # run: | + # mkdir -p packages/contracts-bedrock/lib/superchain-registry/ops/testdata/monorepo + # # Copy any required config files here, or create placeholder + # echo "Config prepared for op-batcher" + + # - name: Login to GitHub Container Registry + # uses: docker/login-action@v3 + # with: + # registry: ${{ env.REGISTRY }} + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + + # - name: Extract metadata + # id: meta + # uses: docker/metadata-action@v5 + # with: + # images: ${{ env.IMAGE_PREFIX }}/op-batcher + # tags: | + # type=ref,event=branch + # type=ref,event=pr + # type=sha,prefix={{branch}}-,enable={{is_default_branch}} + # type=raw,value=latest,enable={{is_default_branch}} + # type=raw,value=pr-${{ github.event.number }},enable=${{ github.event_name == 'pull_request' }} + + # - name: Build and push OP Batcher + # uses: docker/build-push-action@v5 + # with: + # context: . + # file: espresso/docker/op-stack/Dockerfile + # target: op-batcher-target + # platforms: linux/amd64 + # push: true + # tags: ${{ steps.meta.outputs.tags }} + # labels: ${{ steps.meta.outputs.labels }} + # build-args: | + # TARGET_BASE_IMAGE=alpine:3.22 + # TARGETOS=linux + # TARGETARCH=amd64 - - name: Install just - uses: extractions/setup-just@v2 - - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Install dasel - run: | - curl -sSL "https://github.com/TomWright/dasel/releases/latest/download/dasel_linux_amd64" -o /tmp/dasel - sudo mv /tmp/dasel /usr/local/bin/dasel - sudo chmod +x /usr/local/bin/dasel - - - name: Check for package.json - id: check-package - run: | - if [ -f "package.json" ]; then - echo "has-package=true" >> $GITHUB_OUTPUT - else - echo "has-package=false" >> $GITHUB_OUTPUT - fi - - - name: Setup Node.js - if: steps.check-package.outputs.has-package == 'true' - uses: actions/setup-node@v4 - with: - node-version: '18' - cache: 'npm' - - - name: Install dependencies - if: steps.check-package.outputs.has-package == 'true' - run: npm ci - - - name: Build op-deployer - run: | - cd op-deployer - just - echo "$(pwd)/bin" >> $GITHUB_PATH - - - name: Compile contracts - run: just compile-contracts - - - name: Prepare allocations - run: | - cd espresso - ./scripts/prepare-allocs.sh - - - name: Create l2-config directory - run: | - mkdir -p espresso/deployment/l2-config - echo "Created l2-config directory" - ls -la espresso/deployment/ - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.IMAGE_PREFIX }}/op-node - tags: | - type=ref,event=branch - type=ref,event=pr - type=sha,prefix={{branch}}-,enable={{is_default_branch}} - type=raw,value=latest,enable={{is_default_branch}} - type=raw,value=pr-${{ github.event.number }},enable=${{ github.event_name == 'pull_request' }} - - - name: Build and push OP Node - uses: docker/build-push-action@v5 - with: - context: . - file: espresso/docker/op-stack/Dockerfile - target: op-node-target - platforms: linux/amd64 - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - build-args: | - TARGET_BASE_IMAGE=alpine:3.22 - TARGETOS=linux - TARGETARCH=amd64 - - build-op-batcher: + build-op-batcher-tee: runs-on: ubuntu-latest permissions: contents: read @@ -355,12 +458,6 @@ jobs: cd espresso ./scripts/prepare-allocs.sh - - name: Copy config for op-batcher - run: | - mkdir -p packages/contracts-bedrock/lib/superchain-registry/ops/testdata/monorepo - # Copy any required config files here, or create placeholder - echo "Config prepared for op-batcher" - - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: @@ -372,7 +469,7 @@ jobs: id: meta uses: docker/metadata-action@v5 with: - images: ${{ env.IMAGE_PREFIX }}/op-batcher + images: ${{ env.IMAGE_PREFIX }}/op-batcher-tee tags: | type=ref,event=branch type=ref,event=pr @@ -380,12 +477,12 @@ jobs: type=raw,value=latest,enable={{is_default_branch}} type=raw,value=pr-${{ github.event.number }},enable=${{ github.event_name == 'pull_request' }} - - name: Build and push OP Batcher + - name: Build and push OP Batcher TEE uses: docker/build-push-action@v5 with: context: . file: espresso/docker/op-stack/Dockerfile - target: op-batcher-target + target: op-batcher-enclave-target platforms: linux/amd64 push: true tags: ${{ steps.meta.outputs.tags }} @@ -394,100 +491,3 @@ jobs: TARGET_BASE_IMAGE=alpine:3.22 TARGETOS=linux TARGETARCH=amd64 - - build-op-batcher-tee: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - env: - ENCLAVE_APP_IMAGE: op-batcher-enclave:app - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install just - uses: extractions/setup-just@v2 - - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Install dasel - run: | - curl -sSL "https://github.com/TomWright/dasel/releases/latest/download/dasel_linux_amd64" -o /tmp/dasel - sudo mv /tmp/dasel /usr/local/bin/dasel - sudo chmod +x /usr/local/bin/dasel - dasel --version - - - name: Check for package.json - id: check-package - run: | - if [ -f "package.json" ]; then - echo "has-package=true" >> $GITHUB_OUTPUT - else - echo "has-package=false" >> $GITHUB_OUTPUT - fi - - - name: Setup Node.js - if: steps.check-package.outputs.has-package == 'true' - uses: actions/setup-node@v4 - with: - node-version: '18' - cache: 'npm' - - - name: Run Enclaver installation - run: | - echo "Downloading and installing Enclaver..." - ARCH=$(uname -m) - LATEST_RELEASE=$(curl -s https://api.github.com/repositories/516492075/releases/latest) - DOWNLOAD_URL=$(echo "$LATEST_RELEASE" | jq -r ".assets[] | select(.name | test(\"^enclaver-linux-$ARCH.*tar.gz$\")) | .browser_download_url") - if [ -z "$DOWNLOAD_URL" ]; then - echo "Could not find Enclaver download URL" - exit 1 - fi - curl -L "$DOWNLOAD_URL" -o enclaver.tar.gz - tar xzf enclaver.tar.gz - sudo install enclaver-*/enclaver /usr/local/bin/ - rm -rf enclaver.tar.gz enclaver-* - enclaver --version - - - name: Install dependencies - if: steps.check-package.outputs.has-package == 'true' - run: npm ci - - - name: Build op-batcher enclave image - run: | - cd espresso - ./scripts/batcher-enclave-image.sh - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.IMAGE_PREFIX }}/op-batcher-tee - tags: | - type=ref,event=branch - type=ref,event=pr - type=sha,prefix={{branch}}-,enable={{is_default_branch}} - type=raw,value=latest,enable={{is_default_branch}} - type=raw,value=pr-${{ github.event.number }},enable=${{ github.event_name == 'pull_request' }} - - - name: Tag and push op-batcher-tee image - run: | - docker tag "${{ env.ENCLAVE_APP_IMAGE }}" ${{ steps.meta.outputs.tags }} - docker push ${{ steps.meta.outputs.tags }} From 20cd1838f61b41d3810291ed36991beefa8285f7 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Sat, 23 Aug 2025 06:01:45 +0000 Subject: [PATCH 21/31] add my branch patter --- .github/workflows/docker-images.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-images.yml b/.github/workflows/docker-images.yml index 742d7b366d6..932c4a247ab 100644 --- a/.github/workflows/docker-images.yml +++ b/.github/workflows/docker-images.yml @@ -2,7 +2,7 @@ name: Build and Push Docker Images on: push: - branches: [main, celo*] + branches: [main, celo*, sishan/*] paths: - "espresso/docker/**" - "espresso/docker-compose.yml" From 69cdea0bb9c8c0446047a69d3bd9e9d115266223 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Sat, 23 Aug 2025 06:30:04 +0000 Subject: [PATCH 22/31] fix dockerfile --- espresso/docker/op-stack/Dockerfile | 56 ++++++++++++++--------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/espresso/docker/op-stack/Dockerfile b/espresso/docker/op-stack/Dockerfile index ef5eaed9fdc..e1a7d64836b 100644 --- a/espresso/docker/op-stack/Dockerfile +++ b/espresso/docker/op-stack/Dockerfile @@ -150,35 +150,33 @@ COPY --from=enclave-tools-builder /app/ops /app/ops COPY --from=enclave-tools-builder /app/espresso /app/espresso COPY --from=enclave-tools-builder /app/op-batcher /app/op-batcher # Create .env file with necessary variables (since it's excluded by .gitignore) -RUN cat > /app/espresso/.env << 'EOF' -# Environment variables for enclave -ESPRESSO_DEV_NODE_L1_DEPLOYMENT=skip -ESPRESSO_SEQUENCER_ESP_TOKEN_ADDRESS=0x00c042c4d5d913277ce16611a2ce6e9003554ad5 -ESPRESSO_SEQUENCER_PLONK_VERIFIER_V2_ADDRESS=0x422a3492e218383753d8006c7bfa97815b44373f -ESPRESSO_SEQUENCER_STAKE_TABLE_ADDRESS=0x63e6dde6763c3466c7b45be880f7ee5dc2ca3e25 -ESPRESSO_SEQUENCER_LIGHT_CLIENT_PROXY_ADDRESS=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797 -ESPRESSO_SEQUENCER_FEE_CONTRACT_PROXY_ADDRESS=0x72ae2643518179cf01bca3278a37cead408de8b2 -ESPRESSO_SEQUENCER_FEE_CONTRACT_ADDRESS=0x8f0342a7060e76dfc7f6e9debfad9b9ec919952c -ESPRESSO_SEQUENCER_STAKE_TABLE_PROXY_ADDRESS=0x9f5eac3d8e082f47631f1551f1343f23cd427162 -ESPRESSO_SEQUENCER_ESP_TOKEN_PROXY_ADDRESS=0x9fcf7d13d10dedf17d0f24c62f0cf4ed462f65b7 -ESPRESSO_SEQUENCER_PLONK_VERIFIER_ADDRESS=0xb4b46bdaa835f8e4b4d8e208b6559cd267851051 -ESPRESSO_SEQUENCER_API_PORT=24000 -ESPRESSO_DEV_NODE_PORT=24002 -ESPRESSO_BUILDER_PORT=31003 -L1_ENGINE_PORT=8551 -L1_HTTP_PORT=8545 -L1_BEACON_PORT=5052 -ROLLUP_PORT=9545 -VERIFIER_PORT=9546 -CAFF_PORT=9547 -OP_ENGINE_PORT=8552 -OP_HTTP_PORT=8546 -OPERATOR_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 -OPERATOR_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 -L1_CHAIN_ID=11155111 -L2_CHAIN_ID=22266222 -COMPOSE_PROFILES=default -EOF +RUN echo "# Environment variables for enclave" > /app/espresso/.env && \ + echo "ESPRESSO_DEV_NODE_L1_DEPLOYMENT=skip" >> /app/espresso/.env && \ + echo "ESPRESSO_SEQUENCER_ESP_TOKEN_ADDRESS=0x00c042c4d5d913277ce16611a2ce6e9003554ad5" >> /app/espresso/.env && \ + echo "ESPRESSO_SEQUENCER_PLONK_VERIFIER_V2_ADDRESS=0x422a3492e218383753d8006c7bfa97815b44373f" >> /app/espresso/.env && \ + echo "ESPRESSO_SEQUENCER_STAKE_TABLE_ADDRESS=0x63e6dde6763c3466c7b45be880f7ee5dc2ca3e25" >> /app/espresso/.env && \ + echo "ESPRESSO_SEQUENCER_LIGHT_CLIENT_PROXY_ADDRESS=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" >> /app/espresso/.env && \ + echo "ESPRESSO_SEQUENCER_FEE_CONTRACT_PROXY_ADDRESS=0x72ae2643518179cf01bca3278a37cead408de8b2" >> /app/espresso/.env && \ + echo "ESPRESSO_SEQUENCER_FEE_CONTRACT_ADDRESS=0x8f0342a7060e76dfc7f6e9debfad9b9ec919952c" >> /app/espresso/.env && \ + echo "ESPRESSO_SEQUENCER_STAKE_TABLE_PROXY_ADDRESS=0x9f5eac3d8e082f47631f1551f1343f23cd427162" >> /app/espresso/.env && \ + echo "ESPRESSO_SEQUENCER_ESP_TOKEN_PROXY_ADDRESS=0x9fcf7d13d10dedf17d0f24c62f0cf4ed462f65b7" >> /app/espresso/.env && \ + echo "ESPRESSO_SEQUENCER_PLONK_VERIFIER_ADDRESS=0xb4b46bdaa835f8e4b4d8e208b6559cd267851051" >> /app/espresso/.env && \ + echo "ESPRESSO_SEQUENCER_API_PORT=24000" >> /app/espresso/.env && \ + echo "ESPRESSO_DEV_NODE_PORT=24002" >> /app/espresso/.env && \ + echo "ESPRESSO_BUILDER_PORT=31003" >> /app/espresso/.env && \ + echo "L1_ENGINE_PORT=8551" >> /app/espresso/.env && \ + echo "L1_HTTP_PORT=8545" >> /app/espresso/.env && \ + echo "L1_BEACON_PORT=5052" >> /app/espresso/.env && \ + echo "ROLLUP_PORT=9545" >> /app/espresso/.env && \ + echo "VERIFIER_PORT=9546" >> /app/espresso/.env && \ + echo "CAFF_PORT=9547" >> /app/espresso/.env && \ + echo "OP_ENGINE_PORT=8552" >> /app/espresso/.env && \ + echo "OP_HTTP_PORT=8546" >> /app/espresso/.env && \ + echo "OPERATOR_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" >> /app/espresso/.env && \ + echo "OPERATOR_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" >> /app/espresso/.env && \ + echo "L1_CHAIN_ID=11155111" >> /app/espresso/.env && \ + echo "L2_CHAIN_ID=22266222" >> /app/espresso/.env && \ + echo "COMPOSE_PROFILES=default" >> /app/espresso/.env RUN chmod +x /app/espresso/scripts/batcher-enclave-tool-image.sh /app/espresso/scripts/prepare-allocs.sh WORKDIR /app CMD ["enclave-tools"] From f1a50964ab925bb360a2f513b06c74e3b8f13881 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Mon, 25 Aug 2025 22:19:13 +0000 Subject: [PATCH 23/31] a simplified version --- espresso/docker-compose.yml | 81 +++++++++++++++++++++++++++-- espresso/docker/op-stack/Dockerfile | 40 -------------- 2 files changed, 76 insertions(+), 45 deletions(-) diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index a1fe3c98f47..f500f6c3382 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -357,11 +357,82 @@ services: - /dev/nitro_enclaves:/dev/nitro_enclaves restart: "no" command: - - /app/espresso/scripts/batcher-enclave-tool-image.sh - - "http://127.0.0.1:${L1_HTTP_PORT}" - - "http://127.0.0.1:${OP_HTTP_PORT}" - - "http://127.0.0.1:${ROLLUP_PORT}" - - "http://127.0.0.1:${ESPRESSO_SEQUENCER_API_PORT}" + - sh + - -c + - | + # Configuration + TAG="${TAG:-op-batcher-enclavetool}" + L1_RPC_URL="http://127.0.0.1:${L1_HTTP_PORT}" + L2_RPC_URL="http://127.0.0.1:${OP_HTTP_PORT}" + ROLLUP_RPC_URL="http://127.0.0.1:${ROLLUP_PORT}" + ESPRESSO_URL="http://127.0.0.1:${ESPRESSO_SEQUENCER_API_PORT}" + + # Batcher arguments for run + BATCHER_ARGS="--l1-eth-rpc=$$L1_RPC_URL,--l2-eth-rpc=$$L2_RPC_URL,--rollup-rpc=$$ROLLUP_RPC_URL,--espresso-url=$$ESPRESSO_URL,--espresso-url=$$ESPRESSO_URL,--testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80,--mnemonic=test test test test test test test test test test test junk,--hd-path=m/44'/60'/0'/0/0,--throttle-threshold=0,--max-channel-duration=1,--target-num-frames=1,--espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" + + # Build the enclave image + echo "Building enclave image..." + cd /source + if ! enclave-tools build \ + --op-root /source \ + --tag "$$TAG" 2>&1 | tee /tmp/build_output.log; then + echo "Failed to build enclave image" + echo "Build output was:" + cat /tmp/build_output.log + exit 1 + fi + + echo "Build completed successfully" + + # # Extract PCR0 from build output + # PCR0=$$(grep "PCR0:" /tmp/build_output.log | sed 's/.*PCR0: //') + + # # Get batch authenticator address from deployment state + # BATCH_AUTHENTICATOR_ADDRESS=$$(jq -r '.opChainDeployments[0].batchAuthenticatorAddress' /source/espresso/deployment/deployer/state.json) + + # if [[ -n "$$PCR0" && -n "$$BATCH_AUTHENTICATOR_ADDRESS" && -n "$$OPERATOR_PRIVATE_KEY" ]]; then + # echo "Registering PCR0: $$PCR0 with authenticator: $$BATCH_AUTHENTICATOR_ADDRESS" + # /app/op-batcher/bin/enclave-tools register \ + # --authenticator "$$BATCH_AUTHENTICATOR_ADDRESS" \ + # --l1-url "$$L1_RPC_URL" \ + # --private-key "$$OPERATOR_PRIVATE_KEY" \ + # --pcr0 "$$PCR0" + + # if [ $$? -ne 0 ]; then + # echo "Failed to register PCR0, continuing anyway..." + # fi + # else + # echo "Skipping registration - missing PCR0 ($$PCR0), BATCH_AUTHENTICATOR_ADDRESS ($$BATCH_AUTHENTICATOR_ADDRESS), or OPERATOR_PRIVATE_KEY" + # fi + + # Run the enclave + echo "Running enclave..." + echo "Command: enclave-tools run --image \"$$TAG\" --args \"$$BATCHER_ARGS\"" + enclave-tools run \ + --image "$$TAG" \ + --args "$$BATCHER_ARGS" & + + # Get the enclave-tools PID + ENCLAVE_TOOLS_PID=$$! + echo "Enclave-tools started with PID: $$ENCLAVE_TOOLS_PID" + + # Keep the script running and monitor the enclave + echo "Monitoring enclave..." + while true; do + # Check if enclave-tools process is still running + if ! kill -0 $$ENCLAVE_TOOLS_PID 2>/dev/null; then + echo "Enclave-tools process has exited" + break + fi + + # Check if any enclave is running + RUNNING_ENCLAVES=$$(sudo nitro-cli describe-enclaves 2>/dev/null | jq length 2>/dev/null || echo "0") + echo "$$(date): Running enclaves: $$RUNNING_ENCLAVES" + + sleep 10 + done + + echo "Script exiting..." op-proposer: diff --git a/espresso/docker/op-stack/Dockerfile b/espresso/docker/op-stack/Dockerfile index e1a7d64836b..e5342a5a086 100644 --- a/espresso/docker/op-stack/Dockerfile +++ b/espresso/docker/op-stack/Dockerfile @@ -139,46 +139,6 @@ RUN curl -L https://github.com/enclaver-io/enclaver/releases/download/v0.5.0/enc ENV AZTEC_SRS_PATH /aztec/kzg10-aztec20-srs-1048584.bin ADD "https://github.com/EspressoSystems/ark-srs/releases/download/v0.2.0/kzg10-aztec20-srs-1048584.bin" /aztec/kzg10-aztec20-srs-1048584.bin COPY --from=enclave-tools-builder /app/op-batcher/bin/enclave-tools /usr/local/bin/ -# Copy go.mod to establish monorepo root for enclave-tools -COPY --from=enclave-tools-builder /app/go.mod /app/go.mod -# Copy entire packages and op-e2e directories to satisfy op-e2e config dependencies -COPY --from=enclave-tools-builder /app/packages /app/packages -COPY --from=enclave-tools-builder /app/op-e2e /app/op-e2e -# Copy ops directory required by enclave-tools -COPY --from=enclave-tools-builder /app/ops /app/ops -# Copy entire espresso directory and op-batcher to get all dependencies -COPY --from=enclave-tools-builder /app/espresso /app/espresso -COPY --from=enclave-tools-builder /app/op-batcher /app/op-batcher -# Create .env file with necessary variables (since it's excluded by .gitignore) -RUN echo "# Environment variables for enclave" > /app/espresso/.env && \ - echo "ESPRESSO_DEV_NODE_L1_DEPLOYMENT=skip" >> /app/espresso/.env && \ - echo "ESPRESSO_SEQUENCER_ESP_TOKEN_ADDRESS=0x00c042c4d5d913277ce16611a2ce6e9003554ad5" >> /app/espresso/.env && \ - echo "ESPRESSO_SEQUENCER_PLONK_VERIFIER_V2_ADDRESS=0x422a3492e218383753d8006c7bfa97815b44373f" >> /app/espresso/.env && \ - echo "ESPRESSO_SEQUENCER_STAKE_TABLE_ADDRESS=0x63e6dde6763c3466c7b45be880f7ee5dc2ca3e25" >> /app/espresso/.env && \ - echo "ESPRESSO_SEQUENCER_LIGHT_CLIENT_PROXY_ADDRESS=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" >> /app/espresso/.env && \ - echo "ESPRESSO_SEQUENCER_FEE_CONTRACT_PROXY_ADDRESS=0x72ae2643518179cf01bca3278a37cead408de8b2" >> /app/espresso/.env && \ - echo "ESPRESSO_SEQUENCER_FEE_CONTRACT_ADDRESS=0x8f0342a7060e76dfc7f6e9debfad9b9ec919952c" >> /app/espresso/.env && \ - echo "ESPRESSO_SEQUENCER_STAKE_TABLE_PROXY_ADDRESS=0x9f5eac3d8e082f47631f1551f1343f23cd427162" >> /app/espresso/.env && \ - echo "ESPRESSO_SEQUENCER_ESP_TOKEN_PROXY_ADDRESS=0x9fcf7d13d10dedf17d0f24c62f0cf4ed462f65b7" >> /app/espresso/.env && \ - echo "ESPRESSO_SEQUENCER_PLONK_VERIFIER_ADDRESS=0xb4b46bdaa835f8e4b4d8e208b6559cd267851051" >> /app/espresso/.env && \ - echo "ESPRESSO_SEQUENCER_API_PORT=24000" >> /app/espresso/.env && \ - echo "ESPRESSO_DEV_NODE_PORT=24002" >> /app/espresso/.env && \ - echo "ESPRESSO_BUILDER_PORT=31003" >> /app/espresso/.env && \ - echo "L1_ENGINE_PORT=8551" >> /app/espresso/.env && \ - echo "L1_HTTP_PORT=8545" >> /app/espresso/.env && \ - echo "L1_BEACON_PORT=5052" >> /app/espresso/.env && \ - echo "ROLLUP_PORT=9545" >> /app/espresso/.env && \ - echo "VERIFIER_PORT=9546" >> /app/espresso/.env && \ - echo "CAFF_PORT=9547" >> /app/espresso/.env && \ - echo "OP_ENGINE_PORT=8552" >> /app/espresso/.env && \ - echo "OP_HTTP_PORT=8546" >> /app/espresso/.env && \ - echo "OPERATOR_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" >> /app/espresso/.env && \ - echo "OPERATOR_ADDRESS=0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" >> /app/espresso/.env && \ - echo "L1_CHAIN_ID=11155111" >> /app/espresso/.env && \ - echo "L2_CHAIN_ID=22266222" >> /app/espresso/.env && \ - echo "COMPOSE_PROFILES=default" >> /app/espresso/.env -RUN chmod +x /app/espresso/scripts/batcher-enclave-tool-image.sh /app/espresso/scripts/prepare-allocs.sh -WORKDIR /app CMD ["enclave-tools"] FROM $TARGET_BASE_IMAGE AS op-proposer-target From dceab7e324095dd0d2434e4105f86ceb1c5f36c1 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Tue, 26 Aug 2025 03:36:42 +0000 Subject: [PATCH 24/31] adding packages/contracts-bedrock/forge-artifacts to op-batcher-enclave-target --- espresso/docker/op-stack/Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/espresso/docker/op-stack/Dockerfile b/espresso/docker/op-stack/Dockerfile index e5342a5a086..a0388adc6f2 100644 --- a/espresso/docker/op-stack/Dockerfile +++ b/espresso/docker/op-stack/Dockerfile @@ -136,6 +136,14 @@ FROM $TARGET_BASE_IMAGE AS op-batcher-enclave-target RUN apk add gcc docker bash jq curl wget # Install enclaver for EIF creation RUN curl -L https://github.com/enclaver-io/enclaver/releases/download/v0.5.0/enclaver-linux-x86_64-v0.5.0.tar.gz | tar xz --strip-components=1 -C /usr/local/bin enclaver-linux-x86_64-v0.5.0/enclaver + +# Copy source code +COPY --from=op-cgo-builder /app /source +WORKDIR /source + +# Copy pre-built forge-artifacts from host (faster for development) +COPY packages/contracts-bedrock/forge-artifacts /source/packages/contracts-bedrock/forge-artifacts + ENV AZTEC_SRS_PATH /aztec/kzg10-aztec20-srs-1048584.bin ADD "https://github.com/EspressoSystems/ark-srs/releases/download/v0.2.0/kzg10-aztec20-srs-1048584.bin" /aztec/kzg10-aztec20-srs-1048584.bin COPY --from=enclave-tools-builder /app/op-batcher/bin/enclave-tools /usr/local/bin/ From 0c0cfc192f1c37d1e3e7cf490c75cce5a0ebfaba Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Tue, 26 Aug 2025 20:49:44 +0000 Subject: [PATCH 25/31] PCR0 registered in op-batcher-tee docker compose and add monitor for enclave logs --- espresso/docker-compose-op-geth.yml | 4 +- espresso/docker-compose.yml | 242 +++++++++++++++--- .../scripts/batcher-enclave-tool-image.sh | 6 +- op-batcher/enclave-entrypoint.bash | 2 +- 4 files changed, 218 insertions(+), 36 deletions(-) diff --git a/espresso/docker-compose-op-geth.yml b/espresso/docker-compose-op-geth.yml index cdffe30c2bf..81564f5eec3 100644 --- a/espresso/docker-compose-op-geth.yml +++ b/espresso/docker-compose-op-geth.yml @@ -21,5 +21,5 @@ services: OP_HTTP_PORT: ${OP_HTTP_PORT:?err} OP_ENGINE_PORT: ${OP_ENGINE_PORT:?err} ports: - - "${OP_HTTP_PORT}" - - "${OP_ENGINE_PORT}" + - "${OP_HTTP_PORT}:${OP_HTTP_PORT}" + - "${OP_ENGINE_PORT}:${OP_ENGINE_PORT}" diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index f500f6c3382..4e1d0c74cb5 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -330,6 +330,12 @@ services: dockerfile: espresso/docker/op-stack/Dockerfile target: op-batcher-enclave-target image: op-batcher-tee:espresso + healthcheck: + test: ["CMD-SHELL", "test -f /tmp/enclave-tools.pid && kill -0 $(cat /tmp/enclave-tools.pid) 2>/dev/null || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s depends_on: l1-geth: condition: service_healthy @@ -347,6 +353,11 @@ services: environment: http_proxy: http://127.0.0.1:3128 HTTP_PROXY: http://127.0.0.1:3128 + OPERATOR_PRIVATE_KEY: ${OPERATOR_PRIVATE_KEY} + ENCLAVE_DEBUG: ${ENCLAVE_DEBUG:-false} + CONTAINER_MONITOR_INTERVAL: ${CONTAINER_MONITOR_INTERVAL:-1} + ENCLAVE_MEMORY_MB: ${ENCLAVE_MEMORY_MB:-4096} + ENCLAVE_CPU_COUNT: ${ENCLAVE_CPU_COUNT:-2} volumes: - /var/run/docker.sock:/var/run/docker.sock - ..:/source:ro @@ -367,9 +378,26 @@ services: ROLLUP_RPC_URL="http://127.0.0.1:${ROLLUP_PORT}" ESPRESSO_URL="http://127.0.0.1:${ESPRESSO_SEQUENCER_API_PORT}" + # Read environment variables with defaults + DEBUG_MODE="${ENCLAVE_DEBUG:-false}" + MONITOR_INTERVAL="${CONTAINER_MONITOR_INTERVAL:-1}" + MEMORY_MB="${ENCLAVE_MEMORY_MB:-4096}" + CPU_COUNT="${ENCLAVE_CPU_COUNT:-2}" + + echo "Enclave Configuration:" + echo " Debug Mode: $$DEBUG_MODE" + echo " Monitor Interval: $$MONITOR_INTERVAL seconds" + echo " Memory: $${MEMORY_MB}MB" + echo " CPU Count: $$CPU_COUNT" + # Batcher arguments for run BATCHER_ARGS="--l1-eth-rpc=$$L1_RPC_URL,--l2-eth-rpc=$$L2_RPC_URL,--rollup-rpc=$$ROLLUP_RPC_URL,--espresso-url=$$ESPRESSO_URL,--espresso-url=$$ESPRESSO_URL,--testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80,--mnemonic=test test test test test test test test test test test junk,--hd-path=m/44'/60'/0'/0/0,--throttle-threshold=0,--max-channel-duration=1,--target-num-frames=1,--espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" + # Add debug arguments if enabled + if [ "$$DEBUG_MODE" = "true" ]; then + BATCHER_ARGS="$$BATCHER_ARGS,--log.level=debug" + fi + # Build the enclave image echo "Building enclave image..." cd /source @@ -384,58 +412,212 @@ services: echo "Build completed successfully" - # # Extract PCR0 from build output - # PCR0=$$(grep "PCR0:" /tmp/build_output.log | sed 's/.*PCR0: //') + # Extract PCR0 from build output + PCR0=$$(grep "PCR0:" /tmp/build_output.log | sed 's/.*PCR0: //') + + # Get batch authenticator address from deployment state + BATCH_AUTHENTICATOR_ADDRESS=$$(jq -r '.opChainDeployments[0].batchAuthenticatorAddress' /source/espresso/deployment/deployer/state.json) + + if [[ -n "$$PCR0" && -n "$$BATCH_AUTHENTICATOR_ADDRESS" && -n "$$OPERATOR_PRIVATE_KEY" ]]; then + echo "Registering PCR0: $$PCR0 with authenticator: $$BATCH_AUTHENTICATOR_ADDRESS" + /usr/local/bin/enclave-tools register \ + --authenticator "$$BATCH_AUTHENTICATOR_ADDRESS" \ + --l1-url "$$L1_RPC_URL" \ + --private-key "$$OPERATOR_PRIVATE_KEY" \ + --pcr0 "$$PCR0" - # # Get batch authenticator address from deployment state - # BATCH_AUTHENTICATOR_ADDRESS=$$(jq -r '.opChainDeployments[0].batchAuthenticatorAddress' /source/espresso/deployment/deployer/state.json) + if [ $$? -ne 0 ]; then + echo "Failed to register PCR0, continuing anyway..." + fi + else + echo "Skipping registration - missing PCR0 ($$PCR0), BATCH_AUTHENTICATOR_ADDRESS ($$BATCH_AUTHENTICATOR_ADDRESS), or OPERATOR_PRIVATE_KEY" + fi - # if [[ -n "$$PCR0" && -n "$$BATCH_AUTHENTICATOR_ADDRESS" && -n "$$OPERATOR_PRIVATE_KEY" ]]; then - # echo "Registering PCR0: $$PCR0 with authenticator: $$BATCH_AUTHENTICATOR_ADDRESS" - # /app/op-batcher/bin/enclave-tools register \ - # --authenticator "$$BATCH_AUTHENTICATOR_ADDRESS" \ - # --l1-url "$$L1_RPC_URL" \ - # --private-key "$$OPERATOR_PRIVATE_KEY" \ - # --pcr0 "$$PCR0" + # Create tracking files + PID_FILE="/tmp/enclave-tools.pid" + CONTAINER_TRACKER_FILE="/tmp/enclave-containers.txt" + STATUS_FILE="/tmp/enclave-status.json" + + # Cleanup function + cleanup() { + echo "Cleaning up enclave resources..." + if [ -f "$$PID_FILE" ]; then + STORED_PID=$$(cat "$$PID_FILE") + if kill -0 "$$STORED_PID" 2>/dev/null; then + echo "Terminating enclave-tools process (PID: $$STORED_PID)" + kill -TERM "$$STORED_PID" 2>/dev/null || true + sleep 5 + kill -KILL "$$STORED_PID" 2>/dev/null || true + fi + rm -f "$$PID_FILE" + fi - # if [ $$? -ne 0 ]; then - # echo "Failed to register PCR0, continuing anyway..." - # fi - # else - # echo "Skipping registration - missing PCR0 ($$PCR0), BATCH_AUTHENTICATOR_ADDRESS ($$BATCH_AUTHENTICATOR_ADDRESS), or OPERATOR_PRIVATE_KEY" - # fi + # Clean up any remaining enclave containers + if [ -f "$$CONTAINER_TRACKER_FILE" ]; then + while IFS= read -r container_id; do + if [ -n "$$container_id" ] && docker ps -q --filter id="$$container_id" | grep -q "$$container_id"; then + echo "Stopping tracked enclave container: $$container_id" + docker stop "$$container_id" 2>/dev/null || true + docker rm "$$container_id" 2>/dev/null || true + fi + done < "$$CONTAINER_TRACKER_FILE" + rm -f "$$CONTAINER_TRACKER_FILE" + fi + exit 0 + } + + # Setup signal handlers + trap cleanup SIGTERM SIGINT EXIT + + # Get the current Docker network name for enclave container + DOCKER_NETWORK=$$(docker network ls --filter name=espresso --format "{{.Name}}" | head -1) + if [ -z "$$DOCKER_NETWORK" ]; then + DOCKER_NETWORK="espresso_default" + fi + echo "Using Docker network: $$DOCKER_NETWORK" # Run the enclave echo "Running enclave..." echo "Command: enclave-tools run --image \"$$TAG\" --args \"$$BATCHER_ARGS\"" - enclave-tools run \ - --image "$$TAG" \ - --args "$$BATCHER_ARGS" & + + # Set environment variables that might be used by enclave-tools + export DOCKER_DEFAULT_NETWORK="$$DOCKER_NETWORK" + export ENCLAVE_DOCKER_NETWORK="$$DOCKER_NETWORK" + + enclave-tools run --image "$$TAG" --args "$$BATCHER_ARGS" & # Get the enclave-tools PID ENCLAVE_TOOLS_PID=$$! - echo "Enclave-tools started with PID: $$ENCLAVE_TOOLS_PID" + echo "$$ENCLAVE_TOOLS_PID" > "$$PID_FILE" + echo "Enclave-tools started with PID: $$ENCLAVE_TOOLS_PID (stored in $$PID_FILE)" + + # Wait for enclave-tools to finish starting the enclave container + echo "Waiting for enclave-tools to complete startup..." + wait $$ENCLAVE_TOOLS_PID + ENCLAVE_TOOLS_EXIT_CODE=$$? + echo "Enclave-tools process completed with exit code: $$ENCLAVE_TOOLS_EXIT_CODE" + + # Clean up PID file since process has completed + rm -f "$$PID_FILE" + + # If enclave-tools failed, exit early + if [ $$ENCLAVE_TOOLS_EXIT_CODE -ne 0 ]; then + echo "ERROR: enclave-tools failed with exit code $$ENCLAVE_TOOLS_EXIT_CODE" + exit $$ENCLAVE_TOOLS_EXIT_CODE + fi + + # Wait a bit more for container to fully initialize + sleep 5 + + # Find the enclave container that was started + echo "Looking for running enclave container..." + CONTAINER_NAME=$$(docker ps --format "table {{.Names}}" | grep "batcher-enclaver-" | head -1) + + if [ -z "$$CONTAINER_NAME" ]; then + echo "ERROR: No enclave container found after waiting." + echo "Checking all Docker containers:" + docker ps -a + exit 1 + fi + + echo "Found enclave container: $$CONTAINER_NAME" + echo "$$CONTAINER_NAME" >> "$$CONTAINER_TRACKER_FILE" + + # Get container details and update status + CONTAINER_ID=$$(docker ps --filter "name=$$CONTAINER_NAME" --format "{{.ID}}" | head -1) + CONTAINER_IMAGE=$$(docker inspect "$$CONTAINER_NAME" --format '{{.Config.Image}}' 2>/dev/null) + STARTED_AT=$$(docker inspect "$$CONTAINER_NAME" --format '{{.State.StartedAt}}' 2>/dev/null) + + echo " Container ID: $$CONTAINER_ID" + echo " Container Image: $$CONTAINER_IMAGE" + echo " Container Started: $$STARTED_AT" + + # Update status file + echo "{" > "$$STATUS_FILE" + echo " \"container_id\": \"$$CONTAINER_ID\"," >> "$$STATUS_FILE" + echo " \"container_name\": \"$$CONTAINER_NAME\"," >> "$$STATUS_FILE" + echo " \"container_image\": \"$$CONTAINER_IMAGE\"," >> "$$STATUS_FILE" + echo " \"started_at\": \"$$STARTED_AT\"," >> "$$STATUS_FILE" + echo " \"last_updated\": \"$$(date -Iseconds)\"," >> "$$STATUS_FILE" + echo " \"status\": \"running\"," >> "$$STATUS_FILE" + echo " \"enclave_tools_exit_code\": $$ENCLAVE_TOOLS_EXIT_CODE" >> "$$STATUS_FILE" + echo "}" >> "$$STATUS_FILE" + + # Start capturing container logs in background + echo "Starting log capture for container $$CONTAINER_NAME" + ( + docker logs -f "$$CONTAINER_NAME" 2>&1 | while read line; do + echo "[ENCLAVE] $$line" + done + ) & + + LOG_PID=$$! + echo "Log capture started with PID: $$LOG_PID" + + # Keep the script running and monitor the container + echo "Monitoring enclave container $$CONTAINER_NAME..." + MONITOR_COUNT=0 - # Keep the script running and monitor the enclave - echo "Monitoring enclave..." while true; do - # Check if enclave-tools process is still running - if ! kill -0 $$ENCLAVE_TOOLS_PID 2>/dev/null; then - echo "Enclave-tools process has exited" + # Check if the container is still running + CONTAINER_STATUS=$$(docker inspect "$$CONTAINER_NAME" 2>/dev/null | jq -r '.[0].State.Status' 2>/dev/null || echo "") + + if [ -z "$$CONTAINER_STATUS" ] || [ "$$CONTAINER_STATUS" != "running" ]; then + echo "$$(date): Container $$CONTAINER_NAME is no longer running (status: $$CONTAINER_STATUS)" + # Get exit code if available + EXIT_CODE=$$(docker inspect "$$CONTAINER_NAME" 2>/dev/null | jq -r '.[0].State.ExitCode' 2>/dev/null || echo "unknown") + echo "Container exit code: $$EXIT_CODE" + + # Update status file + echo "{" > "$$STATUS_FILE" + echo " \"container_id\": \"$$CONTAINER_ID\"," >> "$$STATUS_FILE" + echo " \"container_name\": \"$$CONTAINER_NAME\"," >> "$$STATUS_FILE" + echo " \"container_image\": \"$$CONTAINER_IMAGE\"," >> "$$STATUS_FILE" + echo " \"started_at\": \"$$STARTED_AT\"," >> "$$STATUS_FILE" + echo " \"last_updated\": \"$$(date -Iseconds)\"," >> "$$STATUS_FILE" + echo " \"status\": \"exited\"," >> "$$STATUS_FILE" + echo " \"exit_code\": \"$$EXIT_CODE\"," >> "$$STATUS_FILE" + echo " \"enclave_tools_exit_code\": $$ENCLAVE_TOOLS_EXIT_CODE" >> "$$STATUS_FILE" + echo "}" >> "$$STATUS_FILE" break fi - # Check if any enclave is running - RUNNING_ENCLAVES=$$(sudo nitro-cli describe-enclaves 2>/dev/null | jq length 2>/dev/null || echo "0") - echo "$$(date): Running enclaves: $$RUNNING_ENCLAVES" + # Periodic status reporting + if [ $$((MONITOR_COUNT % 30)) -eq 0 ]; then # Every 30 monitor intervals + echo "$$(date): Container $$CONTAINER_NAME status: $$CONTAINER_STATUS" + + # Show container resource usage + docker stats --no-stream "$$CONTAINER_NAME" 2>/dev/null || echo "Could not get container stats" + + # Update status file with current info + echo "{" > "$$STATUS_FILE" + echo " \"container_id\": \"$$CONTAINER_ID\"," >> "$$STATUS_FILE" + echo " \"container_name\": \"$$CONTAINER_NAME\"," >> "$$STATUS_FILE" + echo " \"container_image\": \"$$CONTAINER_IMAGE\"," >> "$$STATUS_FILE" + echo " \"started_at\": \"$$STARTED_AT\"," >> "$$STATUS_FILE" + echo " \"last_updated\": \"$$(date -Iseconds)\"," >> "$$STATUS_FILE" + echo " \"status\": \"$$CONTAINER_STATUS\"," >> "$$STATUS_FILE" + echo " \"monitor_count\": $$MONITOR_COUNT," >> "$$STATUS_FILE" + echo " \"enclave_tools_exit_code\": $$ENCLAVE_TOOLS_EXIT_CODE" >> "$$STATUS_FILE" + echo "}" >> "$$STATUS_FILE" + fi - sleep 10 + MONITOR_COUNT=$$((MONITOR_COUNT + 1)) + sleep "$$MONITOR_INTERVAL" done + echo "Enclave monitoring ended" + # Clean up log capture if still running + if kill -0 $$LOG_PID 2>/dev/null; then + echo "Stopping log capture..." + kill $$LOG_PID 2>/dev/null || true + fi + echo "Script exiting..." op-proposer: + profiles: ["default"] build: context: ../ dockerfile: espresso/docker/op-stack/Dockerfile diff --git a/espresso/scripts/batcher-enclave-tool-image.sh b/espresso/scripts/batcher-enclave-tool-image.sh index 9a0daa2d09a..eb5826ab112 100755 --- a/espresso/scripts/batcher-enclave-tool-image.sh +++ b/espresso/scripts/batcher-enclave-tool-image.sh @@ -33,7 +33,7 @@ TAG="${TAG:-op-batcher-enclavetool}" echo "Service URLs:" echo " L1 RPC: $L1_RPC_URL" -echo " L2 RPC: $L2_RPC_URL" +echo " L2 RPC: $L2_RPC_URL" echo " Rollup RPC: $ROLLUP_RPC_URL" echo " Espresso API: $ESPRESSO_URL" echo " Host IP (for registration): $HOST_IP" @@ -120,11 +120,11 @@ while true; do echo "Enclave-tools process has exited" break fi - + # Check if any enclave is running RUNNING_ENCLAVES=$(sudo nitro-cli describe-enclaves 2>/dev/null | jq length 2>/dev/null || echo "0") echo "$(date): Running enclaves: $RUNNING_ENCLAVES" - + sleep 10 done diff --git a/op-batcher/enclave-entrypoint.bash b/op-batcher/enclave-entrypoint.bash index f09d11252cd..50523dfa3c2 100644 --- a/op-batcher/enclave-entrypoint.bash +++ b/op-batcher/enclave-entrypoint.bash @@ -134,7 +134,7 @@ while [ $# -gt 0 ]; do echo "Failed to launch socat for $flag=$part"; exit 1 fi echo "Rewritten: $new_url" - url_args+=("$flag" "$new_url") + url_args+=("${flag}=${new_url}") ((SOCAT_PORT++)) done else From ffb0016de06cc38dfc89522a40a3d9139af5bf20 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Wed, 27 Aug 2025 01:43:35 +0000 Subject: [PATCH 26/31] copy deployment/ to op-batcher-enclave-target --- .github/workflows/docker-images.yml | 2 +- espresso/docker/op-stack/Dockerfile | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-images.yml b/.github/workflows/docker-images.yml index c030b6e8af2..4cd458856a0 100644 --- a/.github/workflows/docker-images.yml +++ b/.github/workflows/docker-images.yml @@ -381,7 +381,7 @@ jobs: id: meta uses: docker/metadata-action@v5 with: - images: ${{ env.IMAGE_PREFIX }}/op-batcher-tee + images: ${{ env.IMAGE_PREFIX }}/op-batcher-tee.g tags: | type=ref,event=branch type=ref,event=pr diff --git a/espresso/docker/op-stack/Dockerfile b/espresso/docker/op-stack/Dockerfile index a0388adc6f2..db517092aea 100644 --- a/espresso/docker/op-stack/Dockerfile +++ b/espresso/docker/op-stack/Dockerfile @@ -144,6 +144,9 @@ WORKDIR /source # Copy pre-built forge-artifacts from host (faster for development) COPY packages/contracts-bedrock/forge-artifacts /source/packages/contracts-bedrock/forge-artifacts +# Include the deployment state for contract addresses +COPY espresso/deployment/ /source/espresso/deployment/ + ENV AZTEC_SRS_PATH /aztec/kzg10-aztec20-srs-1048584.bin ADD "https://github.com/EspressoSystems/ark-srs/releases/download/v0.2.0/kzg10-aztec20-srs-1048584.bin" /aztec/kzg10-aztec20-srs-1048584.bin COPY --from=enclave-tools-builder /app/op-batcher/bin/enclave-tools /usr/local/bin/ From cb22a6da596418c379e2f00128be8a8c9bd39e08 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Wed, 27 Aug 2025 01:46:07 +0000 Subject: [PATCH 27/31] fix docker-images --- .github/workflows/docker-images.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-images.yml b/.github/workflows/docker-images.yml index 4cd458856a0..c030b6e8af2 100644 --- a/.github/workflows/docker-images.yml +++ b/.github/workflows/docker-images.yml @@ -381,7 +381,7 @@ jobs: id: meta uses: docker/metadata-action@v5 with: - images: ${{ env.IMAGE_PREFIX }}/op-batcher-tee.g + images: ${{ env.IMAGE_PREFIX }}/op-batcher-tee tags: | type=ref,event=branch type=ref,event=pr From 141494e53d461b62010c072bfb8cf9e5cdb26cef Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Thu, 28 Aug 2025 17:02:34 +0000 Subject: [PATCH 28/31] Remove unneeded script --- espresso/scripts/batcher-enclave-image.sh | 87 ----------------------- 1 file changed, 87 deletions(-) delete mode 100755 espresso/scripts/batcher-enclave-image.sh diff --git a/espresso/scripts/batcher-enclave-image.sh b/espresso/scripts/batcher-enclave-image.sh deleted file mode 100755 index fd7f976548e..00000000000 --- a/espresso/scripts/batcher-enclave-image.sh +++ /dev/null @@ -1,87 +0,0 @@ -#!/bin/bash -set -euo pipefail - -# --- load .env --- -SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" -ENV_FILE="${SCRIPT_DIR}/../.env" -if [[ ! -f "$ENV_FILE" ]]; then - echo "Error: $ENV_FILE not found"; exit 1 -fi -# export everything we source -set -a -# shellcheck disable=SC1090 -source "$ENV_FILE" -set +a - -# Configuration -# NOTE: if loopback doesn't work from inside the enclave, set HOST_IP=host -HOST_IP="${HOST_IP:-127.0.0.1}" -export ENCLAVE_APP_IMAGE="op-batcher-enclave:app" -export ENCLAVE_TARGET_IMAGE="op-batcher-enclaver:tests" -export MANIFEST_FILE="batcher-enclave.yaml" - - -echo "Using HOST_IP: $HOST_IP" -echo "Ports -> L1:$L1_HTTP_PORT L2:$OP_HTTP_PORT Rollup:$ROLLUP_PORT EspressoAPI:$ESPRESSO_SEQUENCER_API_PORT" - -# Step 1: Build the Docker image using your existing Dockerfile -echo "Building Docker image..." -docker build -t "$ENCLAVE_APP_IMAGE" \ - -f ../ops/docker/op-stack-go/Dockerfile \ - --target op-batcher-enclave-target \ - --build-arg ENCLAVE_BATCHER_ARGS="--l1-eth-rpc=http://$HOST_IP:$L1_HTTP_PORT \ - --l2-eth-rpc=http://$HOST_IP:$OP_HTTP_PORT \ - --rollup-rpc=http://$HOST_IP:$ROLLUP_PORT \ - --espresso-url=http://$HOST_IP:$ESPRESSO_SEQUENCER_API_PORT,http://$HOST_IP:$ESPRESSO_SEQUENCER_API_PORT \ - --testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ - --mnemonic=test\ test\ test\ test\ test\ test\ test\ test\ test\ test\ test\ junk \ - --hd-path=m/44\'/60\'/0\'/0/0 \ - --throttle-threshold=0 --max-channel-duration=1 --target-num-frames=1 \ - --espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" \ - ../ - -if [ $? -ne 0 ]; then - echo "Failed to build Docker image" - exit 1 -fi - -# Step 2: Create enclaver manifest -echo "Creating enclaver manifest..." -cat > "$MANIFEST_FILE" << EOL -version: v1 -name: "op-batcher-enclave" -target: "$ENCLAVE_TARGET_IMAGE" -sources: - app: "$ENCLAVE_APP_IMAGE" -defaults: - memory_mb: 4096 - cpu_count: 2 -egress: - proxy_port: 10000 - allow: - - "host" - - "0.0.0.0/0" - - "**" - - "::/0" -EOL - -echo "Manifest created:" -cat "$MANIFEST_FILE" - -# Step 3: Build the enclave -echo "Building enclave..." -sudo enclaver build --file "$MANIFEST_FILE" - -if [ $? -ne 0 ]; then - echo "Failed to build enclave" - exit 1 -fi - -# Step 4: Run the enclave (commented out as in original) -# echo "Running enclave..." -# docker run --rm --privileged --net=host \ -# --name batcher-enclaver-$RANDOM \ -# --device=/dev/nitro_enclaves \ -# $ENCLAVE_TARGET_IMAGE - -# echo "Enclave execution completed" From 47ab40f23f8a8a8f9b3fe2060b2d0870fa2c0a7e Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Thu, 28 Aug 2025 17:05:56 +0000 Subject: [PATCH 29/31] remove unneeded script and cleanup readme --- .../scripts/batcher-enclave-tool-image.sh | 131 ------------------ 1 file changed, 131 deletions(-) delete mode 100755 espresso/scripts/batcher-enclave-tool-image.sh diff --git a/espresso/scripts/batcher-enclave-tool-image.sh b/espresso/scripts/batcher-enclave-tool-image.sh deleted file mode 100755 index eb5826ab112..00000000000 --- a/espresso/scripts/batcher-enclave-tool-image.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/bin/bash -set -euo pipefail - -# Parse command line arguments -if [[ $# -ne 4 ]]; then - echo "Usage: $0 " - echo "Example: $0 http://127.0.0.1:8545 http://127.0.0.1:8546 http://127.0.0.1:9545 http://127.0.0.1:24000" - exit 1 -fi - -L1_RPC_URL="$1" -L2_RPC_URL="$2" -ROLLUP_RPC_URL="$3" -ESPRESSO_URL="$4" - -# Extract HOST_IP from L1_RPC_URL for registration purposes -HOST_IP=$(echo "$L1_RPC_URL" | sed -n 's|^https\?://\([^:]*\).*|\1|p') - -# --- load .env --- -SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" -ENV_FILE="${SCRIPT_DIR}/../.env" -if [[ ! -f "$ENV_FILE" ]]; then - echo "Error: $ENV_FILE not found"; exit 1 -fi -# export everything we source -set -a -# shellcheck disable=SC1090 -source "$ENV_FILE" -set +a - -# Configuration -TAG="${TAG:-op-batcher-enclavetool}" - -echo "Service URLs:" -echo " L1 RPC: $L1_RPC_URL" -echo " L2 RPC: $L2_RPC_URL" -echo " Rollup RPC: $ROLLUP_RPC_URL" -echo " Espresso API: $ESPRESSO_URL" -echo " Host IP (for registration): $HOST_IP" - -# Build enclave-tools if not already built -if [[ ! -f "/app/op-batcher/bin/enclave-tools" ]]; then - echo "Building enclave-tools..." - cd /app/op-batcher - just enclave-tools - cd - -fi - -# Batcher arguments for both build and run -BATCHER_ARGS="--l1-eth-rpc=$L1_RPC_URL,--l2-eth-rpc=$L2_RPC_URL,--rollup-rpc=$ROLLUP_RPC_URL,--espresso-url=$ESPRESSO_URL,--espresso-url=$ESPRESSO_URL,--testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80,--mnemonic=test test test test test test test test test test test junk,--hd-path=m/44'/60'/0'/0/0,--throttle-threshold=0,--max-channel-duration=1,--target-num-frames=1,--espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" - -# Use enclave-tools to build the image -echo "Building enclave image using enclave-tools..." -echo "Command: /app/op-batcher/bin/enclave-tools build --op-root /source --tag \"$TAG\" --args \"$BATCHER_ARGS\"" -echo "Checking if enclaver is available..." -which enclaver || echo "enclaver not found in PATH" -echo "Checking Docker availability..." -docker version || echo "Docker not accessible" -echo "Starting enclave build..." - -# Change to source directory for build context -cd /source - -# Run the command and capture output while also showing it in real-time -/app/op-batcher/bin/enclave-tools build \ - --op-root /source \ - --tag "$TAG" \ - --args "$BATCHER_ARGS" 2>&1 | tee /tmp/build_output.log - -BUILD_EXIT_CODE=${PIPESTATUS[0]} -BUILD_OUTPUT=$(cat /tmp/build_output.log) - -if [ $BUILD_EXIT_CODE -ne 0 ]; then - echo "Failed to build enclave image (exit code: $BUILD_EXIT_CODE)" - echo "Build output was:" - echo "$BUILD_OUTPUT" - exit 1 -fi - -echo "Build completed successfully" - -# Extract PCR0 from build output -PCR0=$(echo "$BUILD_OUTPUT" | grep "PCR0:" | sed 's/.*PCR0: //') - -# Get batch authenticator address from deployment state -BATCH_AUTHENTICATOR_ADDRESS=$(jq -r '.opChainDeployments[0].batchAuthenticatorAddress' /source/espresso/deployment/deployer/state.json) - -if [[ -n "$PCR0" && -n "$BATCH_AUTHENTICATOR_ADDRESS" && -n "$OPERATOR_PRIVATE_KEY" ]]; then - echo "Registering PCR0: $PCR0 with authenticator: $BATCH_AUTHENTICATOR_ADDRESS" - # Use L1_RPC_URL for registration - /app/op-batcher/bin/enclave-tools register \ - --authenticator "$BATCH_AUTHENTICATOR_ADDRESS" \ - --l1-url "$L1_RPC_URL" \ - --private-key "$OPERATOR_PRIVATE_KEY" \ - --pcr0 "$PCR0" - - if [ $? -ne 0 ]; then - echo "Failed to register PCR0, continuing anyway..." - fi -else - echo "Skipping registration - missing PCR0 ($PCR0), BATCH_AUTHENTICATOR_ADDRESS ($BATCH_AUTHENTICATOR_ADDRESS), or OPERATOR_PRIVATE_KEY" -fi - -# Run the enclave -echo "Running enclave..." -echo "Command: /app/op-batcher/bin/enclave-tools run --image \"$TAG\" --args \"$BATCHER_ARGS\"" -/app/op-batcher/bin/enclave-tools run \ - --image "$TAG" \ - --args "$BATCHER_ARGS" & - -# Get the enclave-tools PID -ENCLAVE_TOOLS_PID=$! -echo "Enclave-tools started with PID: $ENCLAVE_TOOLS_PID" - -# Keep the script running and monitor the enclave -echo "Monitoring enclave..." -while true; do - # Check if enclave-tools process is still running - if ! kill -0 $ENCLAVE_TOOLS_PID 2>/dev/null; then - echo "Enclave-tools process has exited" - break - fi - - # Check if any enclave is running - RUNNING_ENCLAVES=$(sudo nitro-cli describe-enclaves 2>/dev/null | jq length 2>/dev/null || echo "0") - echo "$(date): Running enclaves: $RUNNING_ENCLAVES" - - sleep 10 -done - -echo "Script exiting..." From bb3d3a7b947a0f88712c9317777625066cbbef45 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Fri, 29 Aug 2025 00:07:55 +0000 Subject: [PATCH 30/31] fix overlapping ports and move long cmd of op-batcher-tee to script --- README_ESPRESSO.md | 5 - espresso/docker-compose-op-geth.yml | 3 - espresso/docker-compose.yml | 264 ++-------------- espresso/docker/op-batcher-tee/run-enclave.sh | 299 ++++++++++++++++++ espresso/docker/op-stack/Dockerfile | 7 +- 5 files changed, 320 insertions(+), 258 deletions(-) create mode 100755 espresso/docker/op-batcher-tee/run-enclave.sh diff --git a/README_ESPRESSO.md b/README_ESPRESSO.md index f070607a46d..9086efc0295 100644 --- a/README_ESPRESSO.md +++ b/README_ESPRESSO.md @@ -294,11 +294,6 @@ docker compose down -v --remove-orphans ./scripts/prepare-allocs.sh ``` -* Make sure you're on a machine with AWS Nitro Enclaves enabled. Build the enclave image. -```console -./scripts/batcher-enclave-tool-image.sh -``` - * Build and start all services in the background. ```console docker compose up --build -d diff --git a/espresso/docker-compose-op-geth.yml b/espresso/docker-compose-op-geth.yml index 81564f5eec3..af82c1b1009 100644 --- a/espresso/docker-compose-op-geth.yml +++ b/espresso/docker-compose-op-geth.yml @@ -20,6 +20,3 @@ services: L1_RPC: http://l1-geth:${L1_HTTP_PORT:?err} OP_HTTP_PORT: ${OP_HTTP_PORT:?err} OP_ENGINE_PORT: ${OP_ENGINE_PORT:?err} - ports: - - "${OP_HTTP_PORT}:${OP_HTTP_PORT}" - - "${OP_ENGINE_PORT}:${OP_ENGINE_PORT}" diff --git a/espresso/docker-compose.yml b/espresso/docker-compose.yml index 4e1d0c74cb5..e9f205422db 100644 --- a/espresso/docker-compose.yml +++ b/espresso/docker-compose.yml @@ -142,6 +142,9 @@ services: service: op-geth volumes: - op-data-seq:/data + ports: + - "${OP_HTTP_PORT}:${OP_HTTP_PORT}" + - "${OP_ENGINE_PORT}:${OP_ENGINE_PORT}" op-geth-verifier: extends: @@ -149,6 +152,9 @@ services: service: op-geth volumes: - op-data-verifier:/data + ports: + - "8547:${OP_HTTP_PORT}" + - "8553:${OP_ENGINE_PORT}" op-geth-caff-node: extends: @@ -156,6 +162,9 @@ services: service: op-geth volumes: - op-data-caff-node:/data + ports: + - "8548:${OP_HTTP_PORT}" + - "8554:${OP_ENGINE_PORT}" op-node-sequencer: build: @@ -368,252 +377,15 @@ services: - /dev/nitro_enclaves:/dev/nitro_enclaves restart: "no" command: - - sh - - -c - - | - # Configuration - TAG="${TAG:-op-batcher-enclavetool}" - L1_RPC_URL="http://127.0.0.1:${L1_HTTP_PORT}" - L2_RPC_URL="http://127.0.0.1:${OP_HTTP_PORT}" - ROLLUP_RPC_URL="http://127.0.0.1:${ROLLUP_PORT}" - ESPRESSO_URL="http://127.0.0.1:${ESPRESSO_SEQUENCER_API_PORT}" - - # Read environment variables with defaults - DEBUG_MODE="${ENCLAVE_DEBUG:-false}" - MONITOR_INTERVAL="${CONTAINER_MONITOR_INTERVAL:-1}" - MEMORY_MB="${ENCLAVE_MEMORY_MB:-4096}" - CPU_COUNT="${ENCLAVE_CPU_COUNT:-2}" - - echo "Enclave Configuration:" - echo " Debug Mode: $$DEBUG_MODE" - echo " Monitor Interval: $$MONITOR_INTERVAL seconds" - echo " Memory: $${MEMORY_MB}MB" - echo " CPU Count: $$CPU_COUNT" - - # Batcher arguments for run - BATCHER_ARGS="--l1-eth-rpc=$$L1_RPC_URL,--l2-eth-rpc=$$L2_RPC_URL,--rollup-rpc=$$ROLLUP_RPC_URL,--espresso-url=$$ESPRESSO_URL,--espresso-url=$$ESPRESSO_URL,--testing-espresso-batcher-private-key=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80,--mnemonic=test test test test test test test test test test test junk,--hd-path=m/44'/60'/0'/0/0,--throttle-threshold=0,--max-channel-duration=1,--target-num-frames=1,--espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" - - # Add debug arguments if enabled - if [ "$$DEBUG_MODE" = "true" ]; then - BATCHER_ARGS="$$BATCHER_ARGS,--log.level=debug" - fi - - # Build the enclave image - echo "Building enclave image..." - cd /source - if ! enclave-tools build \ - --op-root /source \ - --tag "$$TAG" 2>&1 | tee /tmp/build_output.log; then - echo "Failed to build enclave image" - echo "Build output was:" - cat /tmp/build_output.log - exit 1 - fi - - echo "Build completed successfully" - - # Extract PCR0 from build output - PCR0=$$(grep "PCR0:" /tmp/build_output.log | sed 's/.*PCR0: //') - - # Get batch authenticator address from deployment state - BATCH_AUTHENTICATOR_ADDRESS=$$(jq -r '.opChainDeployments[0].batchAuthenticatorAddress' /source/espresso/deployment/deployer/state.json) - - if [[ -n "$$PCR0" && -n "$$BATCH_AUTHENTICATOR_ADDRESS" && -n "$$OPERATOR_PRIVATE_KEY" ]]; then - echo "Registering PCR0: $$PCR0 with authenticator: $$BATCH_AUTHENTICATOR_ADDRESS" - /usr/local/bin/enclave-tools register \ - --authenticator "$$BATCH_AUTHENTICATOR_ADDRESS" \ - --l1-url "$$L1_RPC_URL" \ - --private-key "$$OPERATOR_PRIVATE_KEY" \ - --pcr0 "$$PCR0" - - if [ $$? -ne 0 ]; then - echo "Failed to register PCR0, continuing anyway..." - fi - else - echo "Skipping registration - missing PCR0 ($$PCR0), BATCH_AUTHENTICATOR_ADDRESS ($$BATCH_AUTHENTICATOR_ADDRESS), or OPERATOR_PRIVATE_KEY" - fi - - # Create tracking files - PID_FILE="/tmp/enclave-tools.pid" - CONTAINER_TRACKER_FILE="/tmp/enclave-containers.txt" - STATUS_FILE="/tmp/enclave-status.json" - - # Cleanup function - cleanup() { - echo "Cleaning up enclave resources..." - if [ -f "$$PID_FILE" ]; then - STORED_PID=$$(cat "$$PID_FILE") - if kill -0 "$$STORED_PID" 2>/dev/null; then - echo "Terminating enclave-tools process (PID: $$STORED_PID)" - kill -TERM "$$STORED_PID" 2>/dev/null || true - sleep 5 - kill -KILL "$$STORED_PID" 2>/dev/null || true - fi - rm -f "$$PID_FILE" - fi - - # Clean up any remaining enclave containers - if [ -f "$$CONTAINER_TRACKER_FILE" ]; then - while IFS= read -r container_id; do - if [ -n "$$container_id" ] && docker ps -q --filter id="$$container_id" | grep -q "$$container_id"; then - echo "Stopping tracked enclave container: $$container_id" - docker stop "$$container_id" 2>/dev/null || true - docker rm "$$container_id" 2>/dev/null || true - fi - done < "$$CONTAINER_TRACKER_FILE" - rm -f "$$CONTAINER_TRACKER_FILE" - fi - exit 0 - } - - # Setup signal handlers - trap cleanup SIGTERM SIGINT EXIT - - # Get the current Docker network name for enclave container - DOCKER_NETWORK=$$(docker network ls --filter name=espresso --format "{{.Name}}" | head -1) - if [ -z "$$DOCKER_NETWORK" ]; then - DOCKER_NETWORK="espresso_default" - fi - echo "Using Docker network: $$DOCKER_NETWORK" - - # Run the enclave - echo "Running enclave..." - echo "Command: enclave-tools run --image \"$$TAG\" --args \"$$BATCHER_ARGS\"" - - # Set environment variables that might be used by enclave-tools - export DOCKER_DEFAULT_NETWORK="$$DOCKER_NETWORK" - export ENCLAVE_DOCKER_NETWORK="$$DOCKER_NETWORK" - - enclave-tools run --image "$$TAG" --args "$$BATCHER_ARGS" & - - # Get the enclave-tools PID - ENCLAVE_TOOLS_PID=$$! - echo "$$ENCLAVE_TOOLS_PID" > "$$PID_FILE" - echo "Enclave-tools started with PID: $$ENCLAVE_TOOLS_PID (stored in $$PID_FILE)" - - # Wait for enclave-tools to finish starting the enclave container - echo "Waiting for enclave-tools to complete startup..." - wait $$ENCLAVE_TOOLS_PID - ENCLAVE_TOOLS_EXIT_CODE=$$? - echo "Enclave-tools process completed with exit code: $$ENCLAVE_TOOLS_EXIT_CODE" - - # Clean up PID file since process has completed - rm -f "$$PID_FILE" - - # If enclave-tools failed, exit early - if [ $$ENCLAVE_TOOLS_EXIT_CODE -ne 0 ]; then - echo "ERROR: enclave-tools failed with exit code $$ENCLAVE_TOOLS_EXIT_CODE" - exit $$ENCLAVE_TOOLS_EXIT_CODE - fi - - # Wait a bit more for container to fully initialize - sleep 5 - - # Find the enclave container that was started - echo "Looking for running enclave container..." - CONTAINER_NAME=$$(docker ps --format "table {{.Names}}" | grep "batcher-enclaver-" | head -1) - - if [ -z "$$CONTAINER_NAME" ]; then - echo "ERROR: No enclave container found after waiting." - echo "Checking all Docker containers:" - docker ps -a - exit 1 - fi - - echo "Found enclave container: $$CONTAINER_NAME" - echo "$$CONTAINER_NAME" >> "$$CONTAINER_TRACKER_FILE" - - # Get container details and update status - CONTAINER_ID=$$(docker ps --filter "name=$$CONTAINER_NAME" --format "{{.ID}}" | head -1) - CONTAINER_IMAGE=$$(docker inspect "$$CONTAINER_NAME" --format '{{.Config.Image}}' 2>/dev/null) - STARTED_AT=$$(docker inspect "$$CONTAINER_NAME" --format '{{.State.StartedAt}}' 2>/dev/null) - - echo " Container ID: $$CONTAINER_ID" - echo " Container Image: $$CONTAINER_IMAGE" - echo " Container Started: $$STARTED_AT" - - # Update status file - echo "{" > "$$STATUS_FILE" - echo " \"container_id\": \"$$CONTAINER_ID\"," >> "$$STATUS_FILE" - echo " \"container_name\": \"$$CONTAINER_NAME\"," >> "$$STATUS_FILE" - echo " \"container_image\": \"$$CONTAINER_IMAGE\"," >> "$$STATUS_FILE" - echo " \"started_at\": \"$$STARTED_AT\"," >> "$$STATUS_FILE" - echo " \"last_updated\": \"$$(date -Iseconds)\"," >> "$$STATUS_FILE" - echo " \"status\": \"running\"," >> "$$STATUS_FILE" - echo " \"enclave_tools_exit_code\": $$ENCLAVE_TOOLS_EXIT_CODE" >> "$$STATUS_FILE" - echo "}" >> "$$STATUS_FILE" - - # Start capturing container logs in background - echo "Starting log capture for container $$CONTAINER_NAME" - ( - docker logs -f "$$CONTAINER_NAME" 2>&1 | while read line; do - echo "[ENCLAVE] $$line" - done - ) & - - LOG_PID=$$! - echo "Log capture started with PID: $$LOG_PID" - - # Keep the script running and monitor the container - echo "Monitoring enclave container $$CONTAINER_NAME..." - MONITOR_COUNT=0 - - while true; do - # Check if the container is still running - CONTAINER_STATUS=$$(docker inspect "$$CONTAINER_NAME" 2>/dev/null | jq -r '.[0].State.Status' 2>/dev/null || echo "") - - if [ -z "$$CONTAINER_STATUS" ] || [ "$$CONTAINER_STATUS" != "running" ]; then - echo "$$(date): Container $$CONTAINER_NAME is no longer running (status: $$CONTAINER_STATUS)" - # Get exit code if available - EXIT_CODE=$$(docker inspect "$$CONTAINER_NAME" 2>/dev/null | jq -r '.[0].State.ExitCode' 2>/dev/null || echo "unknown") - echo "Container exit code: $$EXIT_CODE" - - # Update status file - echo "{" > "$$STATUS_FILE" - echo " \"container_id\": \"$$CONTAINER_ID\"," >> "$$STATUS_FILE" - echo " \"container_name\": \"$$CONTAINER_NAME\"," >> "$$STATUS_FILE" - echo " \"container_image\": \"$$CONTAINER_IMAGE\"," >> "$$STATUS_FILE" - echo " \"started_at\": \"$$STARTED_AT\"," >> "$$STATUS_FILE" - echo " \"last_updated\": \"$$(date -Iseconds)\"," >> "$$STATUS_FILE" - echo " \"status\": \"exited\"," >> "$$STATUS_FILE" - echo " \"exit_code\": \"$$EXIT_CODE\"," >> "$$STATUS_FILE" - echo " \"enclave_tools_exit_code\": $$ENCLAVE_TOOLS_EXIT_CODE" >> "$$STATUS_FILE" - echo "}" >> "$$STATUS_FILE" - break - fi - - # Periodic status reporting - if [ $$((MONITOR_COUNT % 30)) -eq 0 ]; then # Every 30 monitor intervals - echo "$$(date): Container $$CONTAINER_NAME status: $$CONTAINER_STATUS" - - # Show container resource usage - docker stats --no-stream "$$CONTAINER_NAME" 2>/dev/null || echo "Could not get container stats" - - # Update status file with current info - echo "{" > "$$STATUS_FILE" - echo " \"container_id\": \"$$CONTAINER_ID\"," >> "$$STATUS_FILE" - echo " \"container_name\": \"$$CONTAINER_NAME\"," >> "$$STATUS_FILE" - echo " \"container_image\": \"$$CONTAINER_IMAGE\"," >> "$$STATUS_FILE" - echo " \"started_at\": \"$$STARTED_AT\"," >> "$$STATUS_FILE" - echo " \"last_updated\": \"$$(date -Iseconds)\"," >> "$$STATUS_FILE" - echo " \"status\": \"$$CONTAINER_STATUS\"," >> "$$STATUS_FILE" - echo " \"monitor_count\": $$MONITOR_COUNT," >> "$$STATUS_FILE" - echo " \"enclave_tools_exit_code\": $$ENCLAVE_TOOLS_EXIT_CODE" >> "$$STATUS_FILE" - echo "}" >> "$$STATUS_FILE" - fi - - MONITOR_COUNT=$$((MONITOR_COUNT + 1)) - sleep "$$MONITOR_INTERVAL" - done - - echo "Enclave monitoring ended" - # Clean up log capture if still running - if kill -0 $$LOG_PID 2>/dev/null; then - echo "Stopping log capture..." - kill $$LOG_PID 2>/dev/null || true - fi - - echo "Script exiting..." + - sh + - -c + - | + export DEPLOYMENT_MODE=local + export L1_RPC_URL="http://127.0.0.1:${L1_HTTP_PORT}" + export L2_RPC_URL="http://127.0.0.1:${OP_HTTP_PORT}" + export ROLLUP_RPC_URL="http://127.0.0.1:${ROLLUP_PORT}" + export ESPRESSO_URL1="http://127.0.0.1:${ESPRESSO_SEQUENCER_API_PORT}" + /source/espresso/docker/op-batcher-tee/run-enclave.sh op-proposer: diff --git a/espresso/docker/op-batcher-tee/run-enclave.sh b/espresso/docker/op-batcher-tee/run-enclave.sh new file mode 100755 index 00000000000..9ba86cab307 --- /dev/null +++ b/espresso/docker/op-batcher-tee/run-enclave.sh @@ -0,0 +1,299 @@ +#!/bin/bash +# Enclave Batcher Runner Script +# Supports both local (docker-compose) and AWS ECS deployments + +set -e + +# Required environment variables - will fail if not set +: ${L1_RPC_URL:?Error: L1_RPC_URL is required} +: ${L2_RPC_URL:?Error: L2_RPC_URL is required} +: ${ROLLUP_RPC_URL:?Error: ROLLUP_RPC_URL is required} +: ${ESPRESSO_URL1:?Error: ESPRESSO_URL1 is required} +: ${OPERATOR_PRIVATE_KEY:?Error: OPERATOR_PRIVATE_KEY is required} + +# Optional configuration with defaults +TAG="${TAG:-op-batcher-enclavetool}" +ESPRESSO_URL2="${ESPRESSO_URL2:-$ESPRESSO_URL1}" # Default to same as URL1 if not set +ENCLAVE_DEBUG="${ENCLAVE_DEBUG:-false}" +MONITOR_INTERVAL="${MONITOR_INTERVAL:-30}" +MEMORY_MB="${ENCLAVE_MEMORY_MB:-4096}" +CPU_COUNT="${ENCLAVE_CPU_COUNT:-2}" + +# Deployment mode detection +DEPLOYMENT_MODE="${DEPLOYMENT_MODE:-aws}" # 'local' or 'aws' + +echo "=== Enclave Batcher Configuration ===" +echo "Deployment Mode: $DEPLOYMENT_MODE" +echo "L1 RPC URL: $L1_RPC_URL" +echo "L2 RPC URL: $L2_RPC_URL" +echo "Rollup RPC URL: $ROLLUP_RPC_URL" +echo "Espresso URLs: $ESPRESSO_URL1, $ESPRESSO_URL2" +echo "Debug Mode: $ENCLAVE_DEBUG" +echo "Monitor Interval: $MONITOR_INTERVAL seconds" +echo "Memory: ${MEMORY_MB}MB" +echo "CPU Count: $CPU_COUNT" +echo "=====================================" + +# Batcher arguments +BATCHER_ARGS="--l1-eth-rpc=$L1_RPC_URL" +BATCHER_ARGS="$BATCHER_ARGS,--l2-eth-rpc=$L2_RPC_URL" +BATCHER_ARGS="$BATCHER_ARGS,--rollup-rpc=$ROLLUP_RPC_URL" +BATCHER_ARGS="$BATCHER_ARGS,--espresso-url=$ESPRESSO_URL1" +BATCHER_ARGS="$BATCHER_ARGS,--espresso-url=$ESPRESSO_URL2" +BATCHER_ARGS="$BATCHER_ARGS,--testing-espresso-batcher-private-key=$OPERATOR_PRIVATE_KEY" +BATCHER_ARGS="$BATCHER_ARGS,--mnemonic=test test test test test test test test test test test junk" +BATCHER_ARGS="$BATCHER_ARGS,--hd-path=m/44'/60'/0'/0/0" +BATCHER_ARGS="$BATCHER_ARGS,--throttle-threshold=0" +BATCHER_ARGS="$BATCHER_ARGS,--max-channel-duration=1" +BATCHER_ARGS="$BATCHER_ARGS,--target-num-frames=1" +BATCHER_ARGS="$BATCHER_ARGS,--espresso-light-client-addr=0x703848f4c85f18e3acd8196c8ec91eb0b7bd0797" + +# Add debug arguments if enabled +if [ "$ENCLAVE_DEBUG" = "true" ]; then + BATCHER_ARGS="$BATCHER_ARGS,--log.level=debug" + echo "Debug logging enabled" +fi + +# Build the enclave image +echo "Building enclave image with tag: $TAG" +cd /source + +if ! enclave-tools build --op-root /source --tag "$TAG" 2>&1 | tee /tmp/build_output.log; then + echo "ERROR: Failed to build enclave image" + echo "Build output was:" + cat /tmp/build_output.log + exit 1 +fi + +echo "Build completed successfully" + +# Extract PCR0 from build output +PCR0=$(grep "PCR0:" /tmp/build_output.log | sed 's/.*PCR0: //') + +# Get batch authenticator address from deployment state +BATCH_AUTHENTICATOR_ADDRESS=$(jq -r '.opChainDeployments[0].batchAuthenticatorAddress' /source/espresso/deployment/deployer/state.json 2>/dev/null || echo "") + +# Register PCR0 if all required values are present +if [ -n "$PCR0" ] && [ -n "$BATCH_AUTHENTICATOR_ADDRESS" ] && [ -n "$OPERATOR_PRIVATE_KEY" ]; then + echo "Registering PCR0: $PCR0 with authenticator: $BATCH_AUTHENTICATOR_ADDRESS" + enclave-tools register \ + --authenticator "$BATCH_AUTHENTICATOR_ADDRESS" \ + --l1-url "$L1_RPC_URL" \ + --private-key "$OPERATOR_PRIVATE_KEY" \ + --pcr0 "$PCR0" + + if [ $? -ne 0 ]; then + echo "WARNING: Failed to register PCR0, continuing anyway..." + else + echo "PCR0 registration successful" + fi +else + echo "Skipping PCR0 registration - missing required values:" + echo " PCR0: ${PCR0:-[missing]}" + echo " BATCH_AUTHENTICATOR_ADDRESS: ${BATCH_AUTHENTICATOR_ADDRESS:-[missing]}" + echo " OPERATOR_PRIVATE_KEY: ${OPERATOR_PRIVATE_KEY:+[set]}" +fi + +# Setup tracking files for local deployment +if [ "$DEPLOYMENT_MODE" = "local" ]; then + PID_FILE="/tmp/enclave-tools.pid" + CONTAINER_TRACKER_FILE="/tmp/enclave-containers.txt" + STATUS_FILE="/tmp/enclave-status.json" + + # Cleanup function for local deployment + cleanup() { + echo "Cleaning up enclave resources..." + if [ -f "$PID_FILE" ]; then + STORED_PID=$(cat "$PID_FILE") + if kill -0 "$STORED_PID" 2>/dev/null; then + echo "Terminating enclave-tools process (PID: $STORED_PID)" + kill -TERM "$STORED_PID" 2>/dev/null || true + sleep 5 + kill -KILL "$STORED_PID" 2>/dev/null || true + fi + rm -f "$PID_FILE" + fi + + # Clean up any remaining enclave containers + if [ -f "$CONTAINER_TRACKER_FILE" ]; then + while IFS= read -r container_id; do + if [ -n "$container_id" ] && docker ps -q --filter id="$container_id" | grep -q "$container_id"; then + echo "Stopping tracked enclave container: $container_id" + docker stop "$container_id" 2>/dev/null || true + docker rm "$container_id" 2>/dev/null || true + fi + done < "$CONTAINER_TRACKER_FILE" + rm -f "$CONTAINER_TRACKER_FILE" + fi + + rm -f "$STATUS_FILE" + exit 0 + } + + # Setup signal handlers for local deployment + trap cleanup SIGTERM SIGINT EXIT + + # Get Docker network for local deployment + DOCKER_NETWORK=$(docker network ls --filter name=espresso --format "{{.Name}}" | head -1) + if [ -z "$DOCKER_NETWORK" ]; then + DOCKER_NETWORK="espresso_default" + fi + echo "Using Docker network: $DOCKER_NETWORK" + export DOCKER_DEFAULT_NETWORK="$DOCKER_NETWORK" + export ENCLAVE_DOCKER_NETWORK="$DOCKER_NETWORK" +fi + +# Run the enclave +echo "Starting enclave with command:" +echo " enclave-tools run --image \"$TAG\" --args \"$BATCHER_ARGS\"" + +enclave-tools run --image "$TAG" --args "$BATCHER_ARGS" & +ENCLAVE_TOOLS_PID=$! + +if [ "$DEPLOYMENT_MODE" = "local" ]; then + echo "$ENCLAVE_TOOLS_PID" > "$PID_FILE" + echo "Enclave-tools started with PID: $ENCLAVE_TOOLS_PID (stored in $PID_FILE)" +else + echo "Enclave-tools started with PID: $ENCLAVE_TOOLS_PID" +fi + +# Wait for enclave-tools to finish starting the enclave container +echo "Waiting for enclave-tools to complete startup..." +wait $ENCLAVE_TOOLS_PID +ENCLAVE_TOOLS_EXIT_CODE=$? +echo "Enclave-tools process completed with exit code: $ENCLAVE_TOOLS_EXIT_CODE" + +if [ "$DEPLOYMENT_MODE" = "local" ]; then + rm -f "$PID_FILE" +fi + +# Check if enclave-tools failed +if [ $ENCLAVE_TOOLS_EXIT_CODE -ne 0 ]; then + echo "ERROR: enclave-tools failed with exit code $ENCLAVE_TOOLS_EXIT_CODE" + exit $ENCLAVE_TOOLS_EXIT_CODE +fi + +# Wait for container to fully initialize +sleep 5 + +# Find the enclave container that was started +echo "Looking for running enclave container..." +CONTAINER_NAME=$(docker ps --format "table {{.Names}}" | grep "batcher-enclaver-" | head -1) + +if [ -z "$CONTAINER_NAME" ]; then + echo "ERROR: No enclave container found after waiting." + echo "Checking all Docker containers:" + docker ps -a + exit 1 +fi + +echo "Found enclave container: $CONTAINER_NAME" + +# Get container details +CONTAINER_ID=$(docker ps --filter "name=$CONTAINER_NAME" --format "{{.ID}}" | head -1) +CONTAINER_IMAGE=$(docker inspect "$CONTAINER_NAME" --format '{{.Config.Image}}' 2>/dev/null) +STARTED_AT=$(docker inspect "$CONTAINER_NAME" --format '{{.State.StartedAt}}' 2>/dev/null) + +echo "Container Details:" +echo " ID: $CONTAINER_ID" +echo " Image: $CONTAINER_IMAGE" +echo " Started: $STARTED_AT" + +# Setup status tracking for local deployment +if [ "$DEPLOYMENT_MODE" = "local" ]; then + echo "$CONTAINER_NAME" >> "$CONTAINER_TRACKER_FILE" + + # Create initial status file + cat > "$STATUS_FILE" <&1 | while read line; do + echo "[ENCLAVE] $line" + done +) & +LOG_PID=$! +echo "Log capture started with PID: $LOG_PID" + +# Monitor the container +echo "Monitoring enclave container $CONTAINER_NAME..." +MONITOR_COUNT=0 + +while true; do + # Check if the container is still running + CONTAINER_STATUS=$(docker inspect "$CONTAINER_NAME" 2>/dev/null | jq -r '.[0].State.Status' 2>/dev/null || echo "") + + if [ -z "$CONTAINER_STATUS" ] || [ "$CONTAINER_STATUS" != "running" ]; then + echo "$(date): Container $CONTAINER_NAME is no longer running (status: $CONTAINER_STATUS)" + + # Get exit code if available + EXIT_CODE=$(docker inspect "$CONTAINER_NAME" 2>/dev/null | jq -r '.[0].State.ExitCode' 2>/dev/null || echo "unknown") + echo "Container exit code: $EXIT_CODE" + + # Update status file for local deployment + if [ "$DEPLOYMENT_MODE" = "local" ] && [ -n "$STATUS_FILE" ]; then + cat > "$STATUS_FILE" </dev/null || echo "Could not get container stats" + + # Update status file for local deployment + if [ "$DEPLOYMENT_MODE" = "local" ] && [ -n "$STATUS_FILE" ]; then + cat > "$STATUS_FILE" </dev/null; then + echo "Stopping log capture..." + kill $LOG_PID 2>/dev/null || true +fi + +echo "Script exiting..." \ No newline at end of file diff --git a/espresso/docker/op-stack/Dockerfile b/espresso/docker/op-stack/Dockerfile index db517092aea..aa0b959394a 100644 --- a/espresso/docker/op-stack/Dockerfile +++ b/espresso/docker/op-stack/Dockerfile @@ -136,17 +136,16 @@ FROM $TARGET_BASE_IMAGE AS op-batcher-enclave-target RUN apk add gcc docker bash jq curl wget # Install enclaver for EIF creation RUN curl -L https://github.com/enclaver-io/enclaver/releases/download/v0.5.0/enclaver-linux-x86_64-v0.5.0.tar.gz | tar xz --strip-components=1 -C /usr/local/bin enclaver-linux-x86_64-v0.5.0/enclaver - # Copy source code COPY --from=op-cgo-builder /app /source WORKDIR /source - # Copy pre-built forge-artifacts from host (faster for development) COPY packages/contracts-bedrock/forge-artifacts /source/packages/contracts-bedrock/forge-artifacts - # Include the deployment state for contract addresses COPY espresso/deployment/ /source/espresso/deployment/ - +# Copy the run-enclave.sh script +COPY espresso/docker/op-batcher-tee/run-enclave.sh ./espresso/docker/op-batcher-tee/run-enclave.sh +RUN chmod +x ./espresso/docker/op-batcher-tee/run-enclave.sh ENV AZTEC_SRS_PATH /aztec/kzg10-aztec20-srs-1048584.bin ADD "https://github.com/EspressoSystems/ark-srs/releases/download/v0.2.0/kzg10-aztec20-srs-1048584.bin" /aztec/kzg10-aztec20-srs-1048584.bin COPY --from=enclave-tools-builder /app/op-batcher/bin/enclave-tools /usr/local/bin/ From 46a246bd3c80c3031394d4f2a55ac039ae1e50d8 Mon Sep 17 00:00:00 2001 From: dailinsubjam Date: Fri, 29 Aug 2025 01:43:13 +0000 Subject: [PATCH 31/31] update readme --- README_ESPRESSO.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_ESPRESSO.md b/README_ESPRESSO.md index 9086efc0295..681d2131ece 100644 --- a/README_ESPRESSO.md +++ b/README_ESPRESSO.md @@ -298,7 +298,7 @@ docker compose down -v --remove-orphans ```console docker compose up --build -d ``` -If you're on a machine with AWS Nitro Enclaves enabled, use the `tee` profile instead to start the enclave batcher. +If you're on a machine with [AWS Nitro Enclaves enabled](#guide-setting-up-an-enclave-enabled-nitro-ec2-instance), use the `tee` profile instead to start the enclave batcher. ```console COMPOSE_PROFILES=tee docker compose up --build -d ```