-
Notifications
You must be signed in to change notification settings - Fork 3
Add EigenDA V2 CI Infrastructure #144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
0415033
d7fbe37
47a835e
6f87992
e8c2d3e
642edd9
afda9fa
186a316
da8c9f2
0a3bd8b
cbfec59
4430bf8
516c4dc
f410169
fa69708
a37f34d
1551457
791de56
62111bc
badb723
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| name: EigenDA V2 CI | ||
|
|
||
| on: | ||
| workflow_call: | ||
| workflow_dispatch: | ||
| pull_request: | ||
| paths: | ||
| - 'eigenda/**' | ||
| - 'system_tests/eigenda_v2_test.go' | ||
| - 'system_tests/referenceda_test.go' | ||
| - 'daprovider/referenceda/**' | ||
| - 'scripts/start-eigenda-proxy.sh' | ||
| - '.github/workflows/eigenda-v2-ci.yml' | ||
|
|
||
| jobs: | ||
| eigenda-v2-tests: | ||
| runs-on: linux-2xl | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| submodules: recursive | ||
|
|
||
| - uses: ./.github/actions/ci-setup | ||
|
|
||
| - name: Start EigenDA V2 Proxy | ||
| run: | | ||
| # Start V2 proxy (will skip if image not available) | ||
| ./scripts/start-eigenda-proxy.sh v2 || echo "V2 proxy not available yet, skipping" | ||
| continue-on-error: true | ||
|
|
||
| - name: Build Nitro | ||
| run: make -j8 build test-go-deps | ||
| env: | ||
| CARGO_BUILD_JOBS: 2 | ||
|
|
||
| - name: Run V2 Integration Tests | ||
| run: | | ||
| # Run V2 tests with special build tag | ||
| # Tests are currently skipped but will run when V2 is ready | ||
| go test -timeout 600s \ | ||
| -tags eigendav2test \ | ||
| -v \ | ||
| ./system_tests \ | ||
| -run "TestEigenDAV2" || echo "V2 tests skipped (not yet implemented)" | ||
| env: | ||
| GOMEMLIMIT: 6GiB | ||
| GOGC: 80 | ||
| continue-on-error: true | ||
|
|
||
| - name: Run ReferenceDA Integration Tests | ||
| run: | | ||
| # Run ReferenceDA (CustomDA/ALT DA) tests | ||
| # These tests use the existing ReferenceDA implementation and should pass | ||
| # Tests include: | ||
| # - TestReferenceDAServerReachability: Basic server startup | ||
| # - TestReferenceDAStoreRetrieve: Store/retrieve operations | ||
| # - TestReferenceDAIntegration: Full L1/L2 integration with certificate verification | ||
| go test -timeout 600s \ | ||
| -v \ | ||
| ./system_tests \ | ||
| -run "TestReferenceDA" | ||
| env: | ||
| GOMEMLIMIT: 6GiB | ||
| GOGC: 80 | ||
|
|
||
| - name: Check for V2 TODOs | ||
| run: | | ||
| echo "=== V2 Implementation TODOs ===" | ||
| echo "" | ||
| echo "Proxy Script TODOs:" | ||
| grep -n "TODO" scripts/start-eigenda-proxy.sh || echo "None" | ||
| echo "" | ||
| echo "V2 Test TODOs:" | ||
| grep -n "TODO" system_tests/eigenda_v2_test.go | head -20 || echo "None" | ||
| echo "" | ||
| echo "=== Commands ===" | ||
| echo "V2 Proxy: ./scripts/start-eigenda-proxy.sh v2" | ||
| echo "V2 Tests: go test -tags eigendav2test ./system_tests -run TestEigenDAV2" | ||
| echo "ReferenceDA Tests: go test ./system_tests -run TestReferenceDA" | ||
|
|
||
| - name: Upload Test Logs | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: eigenda-v2-test-logs | ||
| path: | | ||
| system_tests/*.log | ||
| /tmp/eigenda-v2-*.log | ||
| if-no-files-found: ignore |
| +6 −0 | src/bridge/ISequencerInbox.sol | |
| +5 −1 | src/bridge/SequencerInbox.sol |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,10 +28,25 @@ func (c *EigenDAProxyClient) Put(ctx context.Context, data []byte) (*disperser.B | |
| return nil, fmt.Errorf("failed to set data: %w", err) | ||
| } | ||
|
|
||
| if len(cert) == 0 { | ||
| return nil, fmt.Errorf("received empty certificate from proxy") | ||
| } | ||
|
|
||
| // Check version byte to determine certificate format | ||
| version := cert[0] | ||
|
|
||
| // V2 certificate (version 0x02): Not supported through V1 code path | ||
| // V2 uses ALT-DA spec and should be accessed through DAProvider interface, not EigenDA.Enable | ||
| // Returning ErrServiceUnavailable will trigger failover to DAProvider if configured | ||
| if version == 0x02 { | ||
| return nil, standard_client.ErrServiceUnavailable | ||
| } | ||
|
Comment on lines
+36
to
+48
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this check being done?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This detects V2 certificates in the V1 code path and returns ErrServiceUnavailable to trigger failover to ReferenceDA. However, if we're removing V1 entirely, this check may no longer be needed.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| // V1 certificate (version 0x00): decode as disperser.BlobInfo | ||
| var blobInfo disperser.BlobInfo | ||
| err = rlp.DecodeBytes(cert[1:], &blobInfo) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to decode blob info: %w", err) | ||
| return nil, fmt.Errorf("failed to decode V1 blob info: %w", err) | ||
| } | ||
|
|
||
| return &blobInfo, nil | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,34 +1,139 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| echo "==== Pull eigenda-proxy container ====" | ||
| docker pull ghcr.io/layr-labs/eigenda-proxy:2.3.1 | ||
| set -euo pipefail | ||
|
|
||
| echo "==== Starting eigenda-proxy container ====" | ||
| # EigenDA Proxy Startup Script | ||
| # | ||
| # Usage: ./start-eigenda-proxy.sh [VERSION] [MODE] | ||
| # | ||
| # VERSION: v1 or v2 (default: v1) | ||
| # - v1: EigenDA V1 with Store() API | ||
| # - v2: EigenDA V2 with ALT-DA spec | ||
| # | ||
| # MODE: memstore or disperser (default: memstore) | ||
| # - memstore: In-memory storage, no real disperser (fast CI tests) | ||
| # * Uses dummy disperser (localhost:32003) | ||
| # * Good for system tests and CI validation | ||
| # * Tests: go test -tags eigendav2test ./system_tests | ||
| # | ||
| # - disperser: Real EigenDA network with blob dispersal (e2e tests) | ||
| # * Connects to real disperser (default: disperser-holesky.eigenda.xyz:443) | ||
| # * Enables arb API for Arbitrum-specific routes | ||
| # * Requires running EigenDA infrastructure or Holesky testnet | ||
| # * Tests: go test -tags eigendav2e2etest ./system_tests | ||
| # | ||
| # Examples: | ||
| # ./start-eigenda-proxy.sh v1 # V1 with memstore | ||
| # ./start-eigenda-proxy.sh v2 # V2 with memstore (fast CI) | ||
| # ./start-eigenda-proxy.sh v2 disperser # V2 with real disperser (e2e) | ||
|
|
||
| # proxy has a bug currently which forces the use of the service manager address | ||
| # Version parameter: v1 or v2 (default: v1) | ||
| VERSION="${1:-v1}" | ||
| # Mode parameter: memstore or disperser (default: memstore) | ||
| MODE="${2:-memstore}" | ||
|
||
|
|
||
| # Configuration based on version | ||
| case "$VERSION" in | ||
| v1) | ||
| PROXY_IMAGE="ghcr.io/layr-labs/eigenda-proxy:2.3.1" | ||
| CONTAINER_NAME="eigenda-proxy-nitro-test-instance" | ||
| STORAGE_BACKENDS="V1" | ||
| DISPERSAL_BACKEND="V1" | ||
| ;; | ||
| v2) | ||
| # V2 uses latest image (v2.5.0+) with V2 backend support | ||
| # V2 implements OP Alt-DA spec with Optimism routes | ||
| PROXY_IMAGE="ghcr.io/layr-labs/eigenda-proxy:latest" | ||
| CONTAINER_NAME="eigenda-proxy-v2-nitro-test-instance" | ||
| STORAGE_BACKENDS="V2" | ||
| DISPERSAL_BACKEND="V2" | ||
| # Enable admin API for runtime backend switching | ||
| ENABLE_ADMIN_API="true" | ||
|
|
||
| # Mode-specific configuration for V2 | ||
| case "$MODE" in | ||
| memstore) | ||
| ENABLE_MEMSTORE="true" | ||
| # For memstore mode, use dummy disperser (data stored in memory) | ||
| DISPERSER_RPC="localhost:32003" | ||
| ;; | ||
| disperser) | ||
| # For disperser mode, connect to real EigenDA network | ||
| ENABLE_MEMSTORE="false" | ||
| # Disperser RPC can be overridden via env var EIGENDA_DISPERSER_RPC | ||
| DISPERSER_RPC="${EIGENDA_DISPERSER_RPC:-disperser-holesky.eigenda.xyz:443}" | ||
| # Enable arb API for Arbitrum-specific routes | ||
| ENABLE_ARB_API="true" | ||
| echo "⚠️ DISPERSER MODE: Connecting to real EigenDA network" | ||
| echo " Disperser: $DISPERSER_RPC" | ||
| ;; | ||
| *) | ||
| echo "Error: Unknown mode '$MODE'. Use 'memstore' or 'disperser'" | ||
| exit 1 | ||
| ;; | ||
| esac | ||
| ;; | ||
| *) | ||
| echo "Error: Unknown version '$VERSION'. Use 'v1' or 'v2'" | ||
| exit 1 | ||
| ;; | ||
| esac | ||
|
|
||
| echo "==== Pull eigenda-proxy $VERSION container ====" | ||
| docker pull "$PROXY_IMAGE" | ||
|
|
||
| echo "==== Starting eigenda-proxy $VERSION container ====" | ||
|
|
||
| # proxy has a bug currently which forces the use of the service manager address | ||
| # & eth rpc despite cert verification being disabled. | ||
|
|
||
| docker run -d --name eigenda-proxy-nitro-test-instance \ | ||
| # Build docker run command | ||
| DOCKER_CMD="docker run -d --name $CONTAINER_NAME \ | ||
| -p 4242:6666 \ | ||
| -e EIGENDA_PROXY_ADDR=0.0.0.0 \ | ||
| -e EIGENDA_PROXY_PORT=6666 \ | ||
| -e EIGENDA_PROXY_STORAGE_BACKENDS_TO_ENABLE=V1 \ | ||
| -e EIGENDA_PROXY_STORAGE_DISPERSAL_BACKEND=V1 \ | ||
| -e EIGENDA_PROXY_APIS_TO_ENABLE=standard \ | ||
| -e EIGENDA_PROXY_MEMSTORE_ENABLED=true \ | ||
| -e EIGENDA_PROXY_STORAGE_BACKENDS_TO_ENABLE=$STORAGE_BACKENDS \ | ||
| -e EIGENDA_PROXY_STORAGE_DISPERSAL_BACKEND=$DISPERSAL_BACKEND \ | ||
| -e EIGENDA_PROXY_MEMSTORE_ENABLED=${ENABLE_MEMSTORE:-true} \ | ||
| -e EIGENDA_PROXY_MEMSTORE_EXPIRATION=120m \ | ||
| -e EIGENDA_PROXY_EIGENDA_ETH_RPC=http://localhost:6969 \ | ||
| -e EIGENDA_PROXY_EIGENDA_SERVICE_MANAGER_ADDR="0x0000000000000000000000000000000000000000" \ | ||
| -e EIGENDA_PROXY_EIGENDA_SERVICE_MANAGER_ADDR=0x0000000000000000000000000000000000000000 \ | ||
| -e EIGENDA_PROXY_EIGENDA_CERT_VERIFICATION_DISABLED=true \ | ||
| ghcr.io/layr-labs/eigenda-proxy:2.3.1 | ||
| -e EIGENDA_PROXY_EIGENDA_DISPERSER_RPC=${DISPERSER_RPC}" | ||
|
|
||
| # Add V2-specific configuration if V2 backend is enabled | ||
| if [[ "$STORAGE_BACKENDS" == *"V2"* ]]; then | ||
| # Use holesky_testnet network for default contract addresses | ||
| # This provides all necessary contract addresses automatically | ||
| DOCKER_CMD="$DOCKER_CMD \ | ||
| -e EIGENDA_PROXY_EIGENDA_V2_NETWORK=holesky_testnet \ | ||
| -e EIGENDA_PROXY_EIGENDA_V2_ETH_RPC=http://localhost:6969" | ||
| fi | ||
|
|
||
| # Add API configuration for V2 if enabled | ||
| if [ "${ENABLE_ADMIN_API:-false}" = "true" ]; then | ||
| if [ "${ENABLE_ARB_API:-false}" = "true" ]; then | ||
| DOCKER_CMD="$DOCKER_CMD -e EIGENDA_PROXY_API_ENABLED=admin,arb" | ||
| else | ||
| DOCKER_CMD="$DOCKER_CMD -e EIGENDA_PROXY_API_ENABLED=admin" | ||
| fi | ||
| elif [ "${ENABLE_ARB_API:-false}" = "true" ]; then | ||
| DOCKER_CMD="$DOCKER_CMD -e EIGENDA_PROXY_API_ENABLED=arb" | ||
| fi | ||
|
|
||
| # Run the container | ||
| eval "$DOCKER_CMD $PROXY_IMAGE" | ||
|
|
||
| # shellcheck disable=SC2181 | ||
| if [ $? -ne 0 ]; then | ||
| echo "==== Failed to start eigenda-proxy container ====" | ||
| echo "==== Failed to start eigenda-proxy $VERSION container ====" | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "==== eigenda-proxy container started ====" | ||
| echo "==== eigenda-proxy $VERSION container started ====" | ||
| echo "Container name: $CONTAINER_NAME" | ||
| echo "Version: $VERSION" | ||
| echo "Image: $PROXY_IMAGE" | ||
|
|
||
| ## TODO - support teardown or embed a docker client wrapper that spins up and tears down resource | ||
| ## TODO - support teardown or embed a docker client wrapper that spins up and tears down resource | ||
| # within system tests. Since this is only used by one system test, it's not a large priority atm. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is the submodule changed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it was updated to add
DAC_CERTIFICATE_MESSAGE_HEADER_FLAG(0x01) support in SequencerInbox.sol. This allows the contract to accept ReferenceDA certificates which use the ALT-DA spec. Without this, ReferenceDA batches are rejected as invalid.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still a bit fuzzy why contract submodules need to be updated here at all given the upstream repo has golang tests for their CustomDA feature which asserts to correctness of batch posting / derivation logics
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, upstream has CustomDA support and the golang daprovider/ code already supports 0x01 (we inherit that). However, the L1 contracts must also accept 0x01 headers for batch posting to work. Without this update, batch posting would fail with InvalidHeaderFlag(0x01).
The update adds one line to SequencerInbox.sol to validate the 0x01 header byte - same as upstream's CustomDA support, just using our fork's naming (
DAC_CERTIFICATE_MESSAGE_HEADER_FLAGvs upstream'sCUSTOM_DA_MESSAGE_HEADER_FLAG).