diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..782ce2f03 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +docker/* +**/.DS_Store +**/.idea +out +cache +**/build +**/target +**/aligned_verification_data +**/broadcast +volume +nonce_*.bin +docker-compose.yaml +.github/** +**.md diff --git a/.github/workflows/send-proofs-docker.yml b/.github/workflows/send-proofs-docker.yml new file mode 100644 index 000000000..070ca2576 --- /dev/null +++ b/.github/workflows/send-proofs-docker.yml @@ -0,0 +1,56 @@ +name: "[CI] Send proofs to network" + +on: + pull_request: + types: + - opened + - synchronize + paths-ignore: + - '**.md' + +concurrency: + group: pull_request-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + network-test-docker-compose: + name: "Test network with Docker Compose" + runs-on: aligned-runner-ci + permissions: + contents: read + packages: write + pull-requests: write + + steps: + - name: Log in to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Build containers + run: make docker_build + + - name: Start containers and initialize network + run: make docker_up && sleep 15 + + - name: Send proofs batches + run: make docker_batcher_send_all_proofs_burst + + - name: Verify all sent proofs + run: make docker_verify_proof_submission_success + + - name: Stop containers + continue-on-error: true + if: always() + run: make docker_down + + - name: Ensure admin permissions in _work + if: always() + run: sudo chown admin:admin -R /home/admin/actions-runner/_work/ diff --git a/Makefile b/Makefile index a249460b8..edf45df9e 100644 --- a/Makefile +++ b/Makefile @@ -698,6 +698,224 @@ tracker_dump_db: docker exec -t tracker-postgres-container pg_dumpall -c -U tracker_user > dump.$$(date +\%Y\%m\%d_\%H\%M\%S).sql @echo "Dumped database successfully to /operator_tracker" +DOCKER_RPC_URL=http://anvil:8545 +PROOF_GENERATOR_ADDRESS=0x66f9664f97F2b50F62D13eA064982f936dE76657 + +docker_build_base_image: + docker compose -f docker-compose.yaml --profile aligned_base build + +docker_build_aggregator: + docker compose -f docker-compose.yaml --profile aggregator build + +docker_build_operator: + docker compose -f docker-compose.yaml --profile operator build + +docker_build_batcher: + docker compose -f docker-compose.yaml --profile batcher build + +docker_restart_aggregator: + docker compose -f docker-compose.yaml --profile aggregator down + docker compose -f docker-compose.yaml --profile aggregator up -d --remove-orphans --force-recreate + +docker_restart_operator: + docker compose -f docker-compose.yaml --profile operator down + docker compose -f docker-compose.yaml --profile operator up -d --remove-orphans --force-recreate + +docker_restart_batcher: + docker compose -f docker-compose.yaml --profile batcher down + docker compose -f docker-compose.yaml --profile batcher up -d --remove-orphans --force-recreate + +docker_build: + docker compose -f docker-compose.yaml --profile aligned_base build + docker compose -f docker-compose.yaml --profile eigenlayer-cli build + docker compose -f docker-compose.yaml --profile foundry build + docker compose -f docker-compose.yaml --profile base build + docker compose -f docker-compose.yaml --profile operator build + docker compose -f docker-compose.yaml --profile batcher build + docker compose -f docker-compose.yaml --profile aggregator build + +docker_up: + docker compose -f docker-compose.yaml --profile base up -d --remove-orphans --force-recreate + @until [ "$$(docker inspect $$(docker ps | grep anvil | awk '{print $$1}') | jq -r '.[0].State.Health.Status')" = "healthy" ]; do sleep .5; done; sleep 2 + docker compose -f docker-compose.yaml --profile aggregator up -d --remove-orphans --force-recreate + docker compose -f docker-compose.yaml run --rm fund-operator + docker compose -f docker-compose.yaml run --rm register-operator-eigenlayer + docker compose -f docker-compose.yaml run --rm mint-mock-tokens + docker compose -f docker-compose.yaml run --rm operator-deposit-into-mock-strategy + docker compose -f docker-compose.yaml run --rm operator-whitelist-devnet + docker compose -f docker-compose.yaml run --rm operator-register-with-aligned-layer + docker compose -f docker-compose.yaml --profile operator up -d --remove-orphans --force-recreate + docker compose -f docker-compose.yaml run --rm user-fund-payment-service-devnet + docker compose -f docker-compose.yaml --profile batcher up -d --remove-orphans --force-recreate + @echo "Up and running" + +docker_down: + docker compose -f docker-compose.yaml --profile batcher down + docker compose -f docker-compose.yaml --profile operator down + docker compose -f docker-compose.yaml --profile base down + @echo "Everything down" + docker ps + +DOCKER_BURST_SIZE=2 +DOCKER_PROOFS_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + +docker_batcher_send_sp1_burst: + @echo "Sending SP1 fibonacci task to Batcher..." + docker exec $(shell docker ps | grep batcher | awk '{print $$1}') aligned submit \ + --private_key $(DOCKER_PROOFS_PRIVATE_KEY) \ + --proving_system SP1 \ + --proof ./scripts/test_files/sp1/sp1_fibonacci.proof \ + --vm_program ./scripts/test_files/sp1/sp1_fibonacci.elf \ + --repetitions $(DOCKER_BURST_SIZE) \ + --proof_generator_addr $(PROOF_GENERATOR_ADDRESS) \ + --rpc_url $(DOCKER_RPC_URL) + +docker_batcher_send_risc0_burst: + @echo "Sending Risc0 fibonacci task to Batcher..." + docker exec $(shell docker ps | grep batcher | awk '{print $$1}') aligned submit \ + --private_key $(DOCKER_PROOFS_PRIVATE_KEY) \ + --proving_system Risc0 \ + --proof ./scripts/test_files/risc_zero/fibonacci_proof_generator/risc_zero_fibonacci.proof \ + --vm_program ./scripts/test_files/risc_zero/fibonacci_proof_generator/fibonacci_id.bin \ + --public_input ./scripts/test_files/risc_zero/fibonacci_proof_generator/risc_zero_fibonacci.pub \ + --repetitions $(DOCKER_BURST_SIZE) \ + --proof_generator_addr $(PROOF_GENERATOR_ADDRESS) \ + --rpc_url $(DOCKER_RPC_URL) + +docker_batcher_send_plonk_bn254_burst: + @echo "Sending Groth16Bn254 1!=0 task to Batcher..." + docker exec $(shell docker ps | grep batcher | awk '{print $$1}') aligned submit \ + --private_key $(DOCKER_PROOFS_PRIVATE_KEY) \ + --proving_system GnarkPlonkBn254 \ + --proof ./scripts/test_files/gnark_plonk_bn254_script/plonk.proof \ + --public_input ./scripts/test_files/gnark_plonk_bn254_script/plonk_pub_input.pub \ + --vk ./scripts/test_files/gnark_plonk_bn254_script/plonk.vk \ + --proof_generator_addr $(PROOF_GENERATOR_ADDRESS) \ + --rpc_url $(DOCKER_RPC_URL) \ + --repetitions $(DOCKER_BURST_SIZE) + +docker_batcher_send_plonk_bls12_381_burst: + @echo "Sending Groth16 BLS12-381 1!=0 task to Batcher..." + docker exec $(shell docker ps | grep batcher | awk '{print $$1}') aligned submit \ + --private_key $(DOCKER_PROOFS_PRIVATE_KEY) \ + --proving_system GnarkPlonkBls12_381 \ + --proof ./scripts/test_files/gnark_plonk_bls12_381_script/plonk.proof \ + --public_input ./scripts/test_files/gnark_plonk_bls12_381_script/plonk_pub_input.pub \ + --vk ./scripts/test_files/gnark_plonk_bls12_381_script/plonk.vk \ + --proof_generator_addr $(PROOF_GENERATOR_ADDRESS) \ + --repetitions $(DOCKER_BURST_SIZE) \ + --rpc_url $(DOCKER_RPC_URL) + +docker_batcher_send_groth16_burst: + @echo "Sending Groth16 BLS12-381 1!=0 task to Batcher..." + docker exec $(shell docker ps | grep batcher | awk '{print $$1}') aligned submit \ + --private_key $(DOCKER_PROOFS_PRIVATE_KEY) \ + --proving_system Groth16Bn254 \ + --proof ./scripts/test_files/gnark_groth16_bn254_script/groth16.proof \ + --public_input ./scripts/test_files/gnark_groth16_bn254_script/plonk_pub_input.pub \ + --vk ./scripts/test_files/gnark_groth16_bn254_script/groth16.vk \ + --proof_generator_addr $(PROOF_GENERATOR_ADDRESS) \ + --repetitions $(DOCKER_BURST_SIZE) \ + --rpc_url $(DOCKER_RPC_URL) + +# Update target as new proofs are supported. +docker_batcher_send_all_proofs_burst: + @$(MAKE) docker_batcher_send_sp1_burst + @$(MAKE) docker_batcher_send_risc0_burst + @$(MAKE) docker_batcher_send_plonk_bn254_burst + @$(MAKE) docker_batcher_send_plonk_bls12_381_burst + @$(MAKE) docker_batcher_send_groth16_burst + +docker_batcher_send_infinite_groth16: + docker exec $(shell docker ps | grep batcher | awk '{print $$1}') \ + sh -c ' \ + mkdir -p scripts/test_files/gnark_groth16_bn254_infinite_script/infinite_proofs; \ + counter=1; \ + timer=3; \ + while true; do \ + echo "Generating proof $${counter} != 0"; \ + gnark_groth16_bn254_infinite_script $${counter}; \ + aligned submit \ + --rpc_url $(DOCKER_RPC_URL) \ + --repetitions $(DOCKER_BURST_SIZE) \ + --proving_system Groth16Bn254 \ + --proof scripts/test_files/gnark_groth16_bn254_infinite_script/infinite_proofs/ineq_$${counter}_groth16.proof \ + --public_input scripts/test_files/gnark_groth16_bn254_infinite_script/infinite_proofs/ineq_$${counter}_groth16.pub \ + --vk scripts/test_files/gnark_groth16_bn254_infinite_script/infinite_proofs/ineq_$${counter}_groth16.vk \ + --proof_generator_addr $(PROOF_GENERATOR_ADDRESS); \ + sleep $${timer}; \ + counter=$$((counter + 1)); \ + done \ + ' + +docker_verify_proofs_onchain: + @echo "Verifying proofs..." + docker exec $(shell docker ps | grep batcher | awk '{print $$1}') \ + sh -c ' \ + for proof in ./aligned_verification_data/*.cbor; do \ + echo "Verifying $${proof}"; \ + aligned verify-proof-onchain \ + --aligned-verification-data $${proof} \ + --rpc_url $(DOCKER_RPC_URL); \ + done \ + ' + +DOCKER_PROOFS_WAIT_TIME=30 + +docker_verify_proof_submission_success: + @echo "Verifying proofs were successfully submitted..." + docker exec $(shell docker ps | grep batcher | awk '{print $$1}') \ + sh -c ' \ + if [ -z "$$(ls -A ./aligned_verification_data)" ]; then echo "ERROR: There are no proofs on aligned_verification_data/ directory" && exit 1; fi; \ + echo "Waiting $(DOCKER_PROOFS_WAIT_TIME) seconds before starting proof verification. \n"; \ + sleep $(DOCKER_PROOFS_WAIT_TIME); \ + for proof in ./aligned_verification_data/*.cbor; do \ + echo "Verifying proof $${proof} \n"; \ + verification=$$(aligned verify-proof-onchain \ + --aligned-verification-data $${proof} \ + --rpc_url $$(echo $(DOCKER_RPC_URL)) 2>&1); \ + if echo "$$verification" | grep -q not; then \ + echo "ERROR: Proof verification failed for $${proof}"; \ + exit 1; \ + elif echo "$$verification" | grep -q verified; then \ + echo "Proof verification succeeded for $${proof}"; \ + fi; \ + echo "---------------------------------------------------------------------------------------------------"; \ + done; \ + if [ $$(ls -1 ./aligned_verification_data/*.cbor | wc -l) -ne 10 ]; then \ + echo "ERROR: Some proofs were verified successfully, but some proofs are missing in the aligned_verification_data/ directory"; \ + exit 1; \ + fi; \ + echo "All proofs verified successfully!"; \ + ' + +docker_attach_foundry: + docker exec -ti $(shell docker ps | grep anvil | awk '{print $$1}') /bin/bash + +docker_attach_anvil: + docker exec -ti $(shell docker ps | grep anvil | awk '{print $$1}') /bin/bash + +docker_attach_aggregator: + docker exec -ti $(shell docker ps | grep aggregator | awk '{print $$1}') /bin/bash + +docker_attach_operator: + docker exec -ti $(shell docker ps | grep operator | awk '{print $$1}') /bin/bash + +docker_attach_batcher: + docker exec -ti $(shell docker ps | grep batcher | awk '{print $$1}') /bin/bash + +docker_logs_anvil: + docker compose -f docker-compose.yaml logs anvil -f + +docker_logs_aggregator: + docker compose -f docker-compose.yaml logs aggregator -f + +docker_logs_operator: + docker compose -f docker-compose.yaml logs operator -f + +docker_logs_batcher: + docker compose -f docker-compose.yaml logs batcher -f + __TELEMETRY__: # Collector, Jaeger and Elixir API telemetry_full_start: open_telemetry_start telemetry_start diff --git a/anvil.Dockerfile b/anvil.Dockerfile deleted file mode 100644 index 41c823eca..000000000 --- a/anvil.Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -# Use the latest foundry image -FROM debian:bookworm-slim - -RUN apt-get update; apt-get -y install curl ; apt-get install make -# Copy our source code into the container -COPY Makefile Makefile - - -ENTRYPOINT ["tail", "-f", "/dev/null"] - -#RUN curl -L https://foundry.paradigm.xyz | bash -#RUN source /home/ubuntu/.bashrc -#ENTRYPOINT ["make", "anvil_start_with_block_time"] diff --git a/batcher/aligned-batcher/.env.docker b/batcher/aligned-batcher/.env.docker new file mode 100644 index 000000000..64ddff628 --- /dev/null +++ b/batcher/aligned-batcher/.env.docker @@ -0,0 +1,8 @@ +AWS_SECRET_ACCESS_KEY=test +AWS_REGION=us-east-2 +AWS_ACCESS_KEY_ID=test +AWS_BUCKET_NAME=aligned.storage +UPLOAD_ENDPOINT=http://localstack:4566 +DOWNLOAD_ENDPOINT=http://localstack:4566/aligned.storage +RUST_LOG=info +RUST_BACKTRACE=1 diff --git a/compose.yaml b/compose.yaml deleted file mode 100644 index 2a1fcf22f..000000000 --- a/compose.yaml +++ /dev/null @@ -1,8 +0,0 @@ -services: - anvil_blockchain: - image: anvil_blockchain - build: - context: . - dockerfile: anvil.Dockerfile - ports: - - "8000:5000" diff --git a/config-files/config-aggregator-docker.yaml b/config-files/config-aggregator-docker.yaml new file mode 100644 index 000000000..81c7aba1d --- /dev/null +++ b/config-files/config-aggregator-docker.yaml @@ -0,0 +1,32 @@ +# Common variables for all the services +# 'production' only prints info and above. 'development' also prints debug +environment: "production" +aligned_layer_deployment_config_file_path: "./contracts/script/output/devnet/alignedlayer_deployment_output.json" +eigen_layer_deployment_config_file_path: "./contracts/script/output/devnet/eigenlayer_deployment_output.json" +eth_rpc_url: "http://anvil:8545" +eth_rpc_url_fallback: "http://anvil:8545" +eth_ws_url: "ws://anvil:8545" +eth_ws_url_fallback: "ws://anvil:8545" +eigen_metrics_ip_port_address: "localhost:9090" + +## ECDSA Configurations +ecdsa: + private_key_store_path: "config-files/anvil.aggregator.ecdsa.key.json" + private_key_store_password: "" + +## BLS Configurations +bls: + private_key_store_path: "config-files/anvil.aggregator.bls.key.json" + private_key_store_password: "" + +## Aggregator Configurations +aggregator: + server_ip_port_address: 0.0.0.0:8090 + bls_public_key_compendium_address: 0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44 + avs_service_manager_address: 0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690 + enable_metrics: true + metrics_ip_port_address: 0.0.0.0:9091 + telemetry_ip_port_address: localhost:4001 + garbage_collector_period: 2m #The period of the GC process. Suggested value for Prod: '168h' (7 days) + garbage_collector_tasks_age: 20 #The age of tasks that will be removed by the GC, in blocks. Suggested value for prod: '216000' (30 days) + garbage_collector_tasks_interval: 10 #The interval of queried blocks to get an old batch. Suggested value for prod: '900' (3 hours) diff --git a/config-files/config-batcher-docker.yaml b/config-files/config-batcher-docker.yaml new file mode 100644 index 000000000..216cb8eee --- /dev/null +++ b/config-files/config-batcher-docker.yaml @@ -0,0 +1,28 @@ +# Common variables for all the services +# 'production' only prints info and above. 'development' also prints debug +environment: "production" +aligned_layer_deployment_config_file_path: "./contracts/script/output/devnet/alignedlayer_deployment_output.json" +eigen_layer_deployment_config_file_path: "./contracts/script/output/devnet/eigenlayer_deployment_output.json" +eth_rpc_url: "http://anvil:8545" +eth_rpc_url_fallback: "http://anvil:8545" +eth_ws_url: "ws://anvil:8545" +eth_ws_url_fallback: "ws://anvil:8545" +eigen_metrics_ip_port_address: "localhost:9090" + +## ECDSA Configurations +ecdsa: + private_key_store_path: "config-files/anvil.batcher.ecdsa.key.json" + private_key_store_password: "" + +## Batcher configurations +batcher: + block_interval: 3 + batch_size_interval: 10 + max_proof_size: 67108864 # 64 MiB + max_batch_size: 268435456 # 256 MiB + eth_ws_reconnects: 99999999999999 + pre_verification_is_enabled: true + metrics_port: 9093 + non_paying: + address: 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 # Anvil address 9 + replacement_private_key: ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 # Anvil address 1 diff --git a/config-files/config-docker.yaml b/config-files/config-docker.yaml new file mode 100644 index 000000000..712edf11c --- /dev/null +++ b/config-files/config-docker.yaml @@ -0,0 +1,57 @@ +# Common variables for all the services +# 'production' only prints info and above. 'development' also prints debug +environment: "production" +aligned_layer_deployment_config_file_path: "./contracts/script/output/devnet/alignedlayer_deployment_output.json" +eigen_layer_deployment_config_file_path: "./contracts/script/output/devnet/eigenlayer_deployment_output.json" +eth_rpc_url: "http://anvil:8545" +eth_rpc_url_fallback: "http://anvil:8545" +eth_ws_url: "ws://anvil:8545" +eth_ws_url_fallback: "ws://anvil:8545" +eigen_metrics_ip_port_address: "localhost:9090" + +## ECDSA Configurations +ecdsa: + private_key_store_path: "config-files/anvil.ecdsa.key.json" + private_key_store_password: "" + +## BLS Configurations +bls: + private_key_store_path: "config-files/anvil.bls.key.json" + private_key_store_password: "" + +## Batcher configurations +batcher: + block_interval: 3 + batch_size_interval: 10 + max_proof_size: 67108864 # 64 MiB + max_batch_size: 268435456 # 256 MiB + eth_ws_reconnects: 99999999999999 + pre_verification_is_enabled: true + +## Aggregator Configurations +aggregator: + server_ip_port_address: localhost:8090 + bls_public_key_compendium_address: 0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44 + avs_service_manager_address: 0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690 + enable_metrics: true + metrics_ip_port_address: localhost:9091 + +## Operator Configurations +operator: + aggregator_rpc_server_ip_port_address: aggregator:8090 + operator_tracker_ip_port_address: http://localhost:3030 + address: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + earnings_receiver_address: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + delegation_approver_address: "0x0000000000000000000000000000000000000000" + staker_opt_out_window_blocks: 0 + metadata_url: "https://yetanotherco.github.io/operator_metadata/metadata.json" + enable_metrics: true + metrics_ip_port_address: localhost:9092 + max_batch_size: 268435456 # 256 MiB + last_processed_batch_filepath: config-files/operator.last_processed_batch.json +# Operators variables needed for register it in EigenLayer +el_delegation_manager_address: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9" +private_key_store_path: config-files/anvil.ecdsa.key.json +bls_private_key_store_path: config-files/anvil.bls.key.json +signer_type: local_keystore +chain_id: 31337 diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 000000000..fb43a5178 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,143 @@ +services: + + localstack: + extends: + file: storage-docker-compose.yaml + service: localstack + profiles: + - base + + anvil: + image: ghcr.io/yetanotherco/aligned_layer/anvil:latest + build: + context: . + dockerfile: docker/anvil.Dockerfile + healthcheck: + test: cast block-number + interval: 1s + timeout: 45s + retries: 20 + start_period: 1s + profiles: + - base + + aggregator: + image: ghcr.io/yetanotherco/aligned_layer/aggregator:latest + build: + context: . + dockerfile: docker/aggregator.Dockerfile + profiles: + - aggregator + + fund-operator: + image: ghcr.io/yetanotherco/aligned_layer/foundry:latest + command: ["sh", "-c", "cast send --from 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 --value 1ether --private-key 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d --rpc-url http://anvil:8545 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --gas-price $(cast gas-price --rpc-url http://anvil:8545)"] + build: + context: . + dockerfile: docker/foundry.Dockerfile + profiles: + - excluded + + register-operator-eigenlayer: + image: ghcr.io/yetanotherco/aligned_layer/eigenlayer-cli:latest + command: ["sh", "-c", "echo '' | eigenlayer operator register config-files/config-docker.yaml"] + build: + context: . + dockerfile: docker/eigenlayer-cli.Dockerfile + profiles: + - excluded + + mint-mock-tokens: + image: ghcr.io/yetanotherco/aligned_layer/foundry:latest + command: ["sh", "-c", "cast send 09635f643e140090a9a8dcd712ed6285858cebef 'mint(address, uint256)' 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 100000000000000000 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://anvil:8545 --gas-price $(cast gas-price --rpc-url http://anvil:8545)"] + build: + context: . + dockerfile: docker/foundry.Dockerfile + profiles: + - excluded + + operator-deposit-into-mock-strategy: + image: ghcr.io/yetanotherco/aligned_layer/operator:latest + command: ["aligned-layer-operator", "deposit-into-strategy", "--config", "./config-files/config-docker.yaml", "--strategy-address", "0xc5a5C42992dECbae36851359345FE25997F5C42d", "--amount", "100000000000000000"] + build: + context: . + dockerfile: docker/operator.Dockerfile + profiles: + - excluded + + operator-whitelist-devnet: + image: ghcr.io/yetanotherco/aligned_layer/foundry:latest + command: ["sh", "-c", "cast send --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 0x851356ae760d987E095750cCeb3bC6014560891C 'add(address)' 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --rpc-url http://anvil:8545 --gas-price $(cast gas-price --rpc-url http://anvil:8545)"] + build: + context: . + dockerfile: docker/foundry.Dockerfile + profiles: + - excluded + + operator-register-with-aligned-layer: + image: ghcr.io/yetanotherco/aligned_layer/operator:latest + command: ["aligned-layer-operator", "register", "--config", "./config-files/config-docker.yaml"] + build: + context: . + dockerfile: docker/operator.Dockerfile + profiles: + - excluded + + operator: + image: ghcr.io/yetanotherco/aligned_layer/operator:latest + command: ["aligned-layer-operator", "start", "--config", "./config-files/config-docker.yaml"] + build: + context: . + dockerfile: docker/operator.Dockerfile + profiles: + - operator + + user-fund-payment-service-devnet: + image: ghcr.io/yetanotherco/aligned_layer/foundry:latest + command: ["sh", "-c", "cast send --from 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 --value 100ether --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 --rpc-url http://anvil:8545 0x7969c5eD335650692Bc04293B07F5BF2e7A673C0 --gas-price $(cast gas-price --rpc-url http://anvil:8545)"] + build: + context: . + dockerfile: docker/foundry.Dockerfile + profiles: + - excluded + + batcher: + image: ghcr.io/yetanotherco/aligned_layer/batcher:latest + environment: + AWS_SECRET_ACCESS_KEY: test + AWS_REGION: us-east-2 + AWS_ACCESS_KEY_ID: test + AWS_BUCKET_NAME: aligned.storage + UPLOAD_ENDPOINT: http://localstack:4566 + DOWNLOAD_ENDPOINT: http://localstack:4566/aligned.storage + RUST_LOG: info + RUST_BACKTRACE: 1 + build: + context: . + dockerfile: docker/batcher.Dockerfile + profiles: + - batcher + + aligned_base: + image: ghcr.io/yetanotherco/aligned_layer/aligned_base:latest + build: + context: . + dockerfile: docker/aligned_base.Dockerfile + profiles: + - aligned_base + + foundry: + image: ghcr.io/yetanotherco/aligned_layer/foundry:latest + build: + context: . + dockerfile: docker/foundry.Dockerfile + profiles: + - foundry + + eigenlayer-cli: + image: ghcr.io/yetanotherco/aligned_layer/eigenlayer-cli:latest + build: + context: . + dockerfile: docker/eigenlayer-cli.Dockerfile + profiles: + - eigenlayer-cli diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 000000000..4e7f3c393 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,113 @@ +# Docker for all components + +To build the necessary images, first run: + +```shell +make docker_build +``` + +Beware that this takes quite a bit of storage, so if you're using Docker for Mac, you're advised to increase to at least 100GB the "Virtual disk limit" size. + +To run the whole stack, including initialization, run: + +```shell +make docker_up +``` + +This will bring app the resources and run the common initialization steps. + +If you want to bring it down, run: + +```shell +make docker_down +``` + +If you want to rebuild any of the components, you can run either of these: + +```shell +make docker_build_aggregator +``` + +```shell +make docker_build_operator +``` + +```shell +make docker_build_batcher +``` + +If you want to rebuild and then restart any of these components without bringing down the docker environment, just run either of these, after rebuilding: + +```shell +make docker_restart_aggregator +``` + +```shell +make docker_restart_operator +``` + +```shell +make docker_restart_batcher +``` + +Alternatively, you can run `make docker_down`, then rebuild, and then `make docker_up` to start over with a fresh environment. + +Additionally, you can run any of these to send proofs (burst of 2 each): + +```shell +make docker_batcher_send_sp1_burst +``` + +```shell +make docker_batcher_send_risc0_burst +``` + +```shell +make docker_batcher_send_plonk_bn254_burst +``` + +```shell +make docker_batcher_send_plonk_bls12_381_burst +``` + +```shell +make docker_batcher_send_infinite_groth16 +``` + +Or you can send all of them together with: + +```shell +make docker_batcher_send_all_proofs_burst +``` + +To verify all sent proofs: + +```shell +make docker_verify_proofs_onchain +``` + +And you can run this to attach to the anvil/foundry container and run `cast` with custom flags: + +```shell +make docker_attach_foundry +``` + +## Logs + +You can watch logs for the components with the following commands: + +```shell +make docker_logs_anvil +``` + +```shell +make docker_logs_aggregator +``` + +```shell +make docker_logs_operator +``` + +```shell +make docker_logs_batcher +``` diff --git a/docker/aggregator.Dockerfile b/docker/aggregator.Dockerfile new file mode 100644 index 000000000..288c705bb --- /dev/null +++ b/docker/aggregator.Dockerfile @@ -0,0 +1,25 @@ +FROM ghcr.io/yetanotherco/aligned_layer/aligned_base:latest AS builder + +WORKDIR /aligned_layer + +COPY go.mod . +COPY go.sum . +COPY aggregator ./aggregator +COPY core ./core +COPY metrics ./metrics +COPY contracts/bindings/ ./contracts/bindings + +RUN go build -o ./aligned-layer-aggregator aggregator/cmd/main.go + +FROM debian:bookworm-slim + +WORKDIR /aggregator + +COPY --from=builder /aligned_layer/aligned-layer-aggregator /usr/local/bin/aligned-layer-aggregator +COPY config-files/config-aggregator-docker.yaml ./config-files/config-aggregator-docker.yaml +COPY contracts/script/output/devnet/alignedlayer_deployment_output.json ./contracts/script/output/devnet/alignedlayer_deployment_output.json +COPY contracts/script/output/devnet/eigenlayer_deployment_output.json ./contracts/script/output/devnet/eigenlayer_deployment_output.json +COPY config-files/anvil.aggregator.ecdsa.key.json ./config-files/anvil.aggregator.ecdsa.key.json +COPY config-files/anvil.aggregator.bls.key.json ./config-files/anvil.aggregator.bls.key.json + +CMD ["aligned-layer-aggregator", "--config", "config-files/config-aggregator-docker.yaml"] diff --git a/docker/aligned_base.Dockerfile b/docker/aligned_base.Dockerfile new file mode 100644 index 000000000..86e88de54 --- /dev/null +++ b/docker/aligned_base.Dockerfile @@ -0,0 +1,42 @@ +FROM rust:slim-bookworm + +# Install rust nightly-2024-04-17 +RUN rustup toolchain install nightly-2024-04-17 + +ARG BUILDARCH +ENV GO_VERSION=1.22.2 + +RUN apt update -y && apt upgrade -y +RUN apt install -y wget \ + tar \ + curl \ + git \ + make \ + clang \ + pkg-config \ + openssl \ + libssl-dev \ + yq \ + jq + +RUN wget https://golang.org/dl/go$GO_VERSION.linux-${BUILDARCH}.tar.gz +RUN tar -C /usr/local -xzf go$GO_VERSION.linux-${BUILDARCH}.tar.gz +RUN rm go$GO_VERSION.linux-${BUILDARCH}.tar.gz +RUN apt clean -y +RUN rm -rf /var/lib/apt/lists/* +ENV PATH="/usr/local/go/bin:${PATH}" + +# Install go deps +RUN go install github.com/maoueh/zap-pretty@latest +RUN go install github.com/ethereum/go-ethereum/cmd/abigen@latest +RUN go install github.com/Layr-Labs/eigenlayer-cli/cmd/eigenlayer@latest + +WORKDIR /aligned_layer + +COPY Makefile . +COPY operator ./operator +COPY batcher/aligned-sdk ./batcher/aligned-sdk + +ENV CARGO_NET_GIT_FETCH_WITH_CLI=true + +RUN make build_all_ffi_linux diff --git a/docker/anvil.Dockerfile b/docker/anvil.Dockerfile new file mode 100644 index 000000000..e56111fa9 --- /dev/null +++ b/docker/anvil.Dockerfile @@ -0,0 +1,5 @@ +FROM ghcr.io/yetanotherco/aligned_layer/foundry:latest + +COPY contracts/scripts/anvil/state/* . + +CMD ["anvil", "--load-state", "alignedlayer-deployed-anvil-state.json", "--block-time", "7", "--host", "0.0.0.0"] diff --git a/docker/batcher.Dockerfile b/docker/batcher.Dockerfile new file mode 100644 index 000000000..d90fe76b3 --- /dev/null +++ b/docker/batcher.Dockerfile @@ -0,0 +1,44 @@ +FROM ghcr.io/yetanotherco/aligned_layer/aligned_base:latest AS builder + +RUN apt update -y +RUN apt install -y gcc + +COPY go.mod . +COPY go.sum . +COPY batcher ./batcher + +WORKDIR /aligned_layer/batcher/aligned-batcher + +RUN go build -buildmode=c-archive -o libverifier.a ./gnark/verifier.go + +WORKDIR /aligned_layer + +COPY batcher/aligned-batcher/Cargo.toml batcher/aligned-batcher/Cargo.toml +COPY batcher/aligned/Cargo.toml batcher/aligned/Cargo.toml + +RUN cargo build --manifest-path ./batcher/aligned-batcher/Cargo.toml --release +RUN cargo build --manifest-path ./batcher/aligned/Cargo.toml --release + +COPY scripts/test_files/gnark_groth16_bn254_infinite_script scripts/test_files/gnark_groth16_bn254_infinite_script + +RUN go build -o ./gnark_groth16_bn254_infinite_script scripts/test_files/gnark_groth16_bn254_infinite_script/cmd/main.go + +RUN rm -rf operator/ + +FROM debian:bookworm-slim + +WORKDIR /aligned_layer + +COPY --from=builder /aligned_layer /aligned_layer +COPY --from=builder /aligned_layer/batcher/target/release/aligned-batcher /usr/local/bin/ +COPY --from=builder /aligned_layer/batcher/target/release/aligned /usr/local/bin/ +COPY --from=builder /aligned_layer/gnark_groth16_bn254_infinite_script /usr/local/bin +COPY ./contracts/script ./contracts/script +COPY ../scripts/test_files/ ./scripts/test_files +COPY ./config-files/config-batcher-docker.yaml ./config-files/ +COPY ./config-files/anvil.batcher.ecdsa.key.json ./config-files/ + +RUN apt update -y +RUN apt install -y libssl-dev ca-certificates + +CMD ["aligned-batcher", "--config", "./config-files/config-batcher-docker.yaml"] diff --git a/docker/eigenlayer-cli.Dockerfile b/docker/eigenlayer-cli.Dockerfile new file mode 100644 index 000000000..3ad0f1033 --- /dev/null +++ b/docker/eigenlayer-cli.Dockerfile @@ -0,0 +1,5 @@ +FROM golang:1.22.2-bookworm + +COPY config-files/ ./config-files + +RUN go install github.com/Layr-Labs/eigenlayer-cli/cmd/eigenlayer@latest diff --git a/docker/foundry.Dockerfile b/docker/foundry.Dockerfile new file mode 100644 index 000000000..e1f331ba9 --- /dev/null +++ b/docker/foundry.Dockerfile @@ -0,0 +1,10 @@ +FROM debian:bookworm-slim + +RUN apt update -y +RUN apt upgrade -y +RUN apt install -y curl git + +# Install foundry +RUN curl -L https://foundry.paradigm.xyz | bash +ENV PATH="/root/.foundry/bin:${PATH}" +RUN foundryup diff --git a/docker/operator.Dockerfile b/docker/operator.Dockerfile new file mode 100644 index 000000000..b264b7127 --- /dev/null +++ b/docker/operator.Dockerfile @@ -0,0 +1,30 @@ +FROM ghcr.io/yetanotherco/aligned_layer/aligned_base:latest AS builder + +RUN apt update -y +RUN apt install -y gcc + +COPY go.mod . +COPY go.sum . + +COPY core ./core +COPY metrics ./metrics +COPY common ./common +COPY contracts/bindings/ ./contracts/bindings + +RUN go build -o /aligned_layer/aligned-layer-operator operator/cmd/main.go + +FROM debian:bookworm-slim + +WORKDIR /aligned_layer + +RUN apt update -y +RUN apt install -y libssl-dev + +COPY --from=builder /aligned_layer/aligned-layer-operator /usr/local/bin/aligned-layer-operator +COPY --from=builder /aligned_layer/operator/ ./operator/ +COPY config-files/ ./config-files/ +COPY contracts ./contracts + +ENV LD_LIBRARY_PATH=/aligned_layer/operator/risc_zero/lib/ + +CMD ["aligned-layer-operator", "start", "--config", "./config-files/config-docker.yaml"]