Skip to content

Commit 10d3bd2

Browse files
deniallugo-mlclaudeCopilot
authored
feat(airbender): adapt prover server to v31 verifier wire format (#4880)
Adapt the Airbender prover server to the v31 verifier wire format and add the plumbing needed to prove and verify a batch with it end-to-end: a zkstack knob to deploy the Airbender L1 verifier, and a GPU e2e CI lane that proves batch 1 and checks the proof on L1. ## What ❔ **Verifier bump (v31 wire format)** - Bump `eravm-airbender-verifier` to the released `v31.1.1` tag, which removes the `V0`/`V1` `AirbenderVerifierInput` envelope and adopts the v31 wire layout (`L2PubdataValidator`, `settlement_layer`, `interop_fee`). - client: deserialize the FRI job directly into the single `AirbenderVerifierInput` instead of polling `V1AirbenderVerifierInput` and wrapping it in `AirbenderVerifierInput::V1`; the integration test drops `.into_v1()` accordingly. - `build.rs` resolves guest/VK artifacts from the pinned tag as usual (with retry on transient download errors); the `AIRBENDER_*` env overrides remain available for local development. - SNARK wrapper: bind the guest program paths so the wrapper proves the pinned guest. - Note: the committed LFS bincode corpus used by the (ignored, GPU-gated) integration test predates the v31 layout and still needs regenerating. **zkstack: `--verifier-type` (`testnet` | `dual` | `airbender`)** - New `VerifierType` threaded through `ecosystem init` and `ctm` init into the CTM deploy scripts; `airbender` wires the Airbender PLONK verifier into the third slot of the Era dual verifier. Defaults preserve current behavior (`testnet` for `no-proofs`, `dual` otherwise). Named `--verifier-type` to avoid colliding with forge's `--verifier`. - genesis validation: the dual verifier's sub-verifier VK check now recognizes Airbender chains (index 2 on the Era dual verifier) and only treats index 2 as Airbender when index 0 (FFLONK) also resolves, since the ZKsyncOS dual verifier reuses index 2 for its own PLONK sub-verifier. There is no config field for the Airbender VK hash yet (TODO in code); a mismatch surfaces on L1 at prove time. - `setDAValidatorPair` call sites updated for the new signature (adds `access_control_restriction`). **CI: Airbender GPU e2e lane** - New `ci-airbender-prover-e2e.yml`: builds the prover server with CUDA 13 on a high-CPU runner, then on an RTX6000 GPU runner inits an ecosystem with `--verifier-type airbender`, sends precompile txs into batch 1, proves FRI then SNARK, and asserts on-chain that `getTotalBatchesVerified` advances (real `proveBatchesSharedBridge` through the Airbender verifier). - The lane only runs for same-repo PRs: it executes a PR-built binary on a persistent self-hosted GPU runner, so fork-controlled code never reaches it. - New checkers (`airbender_proof_status_checker`, `batch_verified_on_l1_checker`) and `bin/prepare_airbender_fixture` to collect proof artifacts for refreshing the era-contracts `AirbenderPlonkProofFixture.sol`. - `setup-env` gains an `sccache` toggle (the GPU hosts cannot authenticate the GCS backend). ## Why ❔ The v31 protocol upgrade changed the batch commitment inputs (pubdata validator, settlement layer, interop fee), and the Airbender verifier repo followed with a breaking wire-format change. This PR keeps the prover server compatible and adds the missing deployment/CI story so the Airbender proving path is exercised end-to-end on every relevant change. ## Is this a breaking change? - [ ] Yes - [x] No ## Operational changes - `zkstack ecosystem init` / `zkstack ctm init` accept `--verifier-type {testnet,dual,airbender}`; omitting it preserves current defaults. - The CTM deploy-script input gains an optional `airbender_verifier` flag (older input configs stay compatible). - The prover server accepts `PROVER_GUEST_DIST_DIR`, `FRI_VK`, `SNARK_VK`, `SNARK_TRUSTED_SETUP_FILE`, `PROVER_SERVER_URL` to point at artifacts explicitly. ## Checklist - [x] PR title corresponds to the body of PR (we generate changelog entries from PRs). - [x] Tests for the changes have been added / updated. - [x] Documentation comments have been added / updated. - [x] Code has been formatted via `zkstack dev fmt` and `zkstack dev lint`. --------- Signed-off-by: Danil Lugovskoi <dl@matterlabs.dev> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent fb5f82e commit 10d3bd2

35 files changed

Lines changed: 983 additions & 213 deletions

File tree

.github/actions/setup-env/action.yml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ inputs:
44
runner-compose-file:
55
description: 'Path to the runner compose file'
66
default: 'docker-compose.yml'
7+
sccache:
8+
description: >-
9+
Wire sccache to the shared GCS cache and start its servers. Disable on runners that can't
10+
reach the GCS backend (e.g. the Hetzner GPU hosts, which lack the GCP metadata service).
11+
default: 'true'
712

813
runs:
914
using: composite
@@ -20,9 +25,11 @@ runs:
2025
echo CI=1 >> $GITHUB_ENV
2126
echo IN_DOCKER=1 >> .env
2227
echo CI=1 >> .env
28+
echo DOCKER_PWD=$(pwd) >> .env
2329
echo RUNNER_COMPOSE_FILE=${{ inputs.runner-compose-file }} >> $GITHUB_ENV
2430
2531
- name: Setup sccache for building rust code outside Docker
32+
if: inputs.sccache == 'true'
2633
shell: bash
2734
run: |
2835
echo SCCACHE_CACHE_SIZE=50G >> $GITHUB_ENV
@@ -36,6 +43,7 @@ runs:
3643
echo SCCACHE_SERVER_PORT=4225 >> $GITHUB_ENV
3744
3845
- name: Setup sccache for building rust code inside Docker
46+
if: inputs.sccache == 'true'
3947
shell: bash
4048
run: |
4149
echo SCCACHE_CACHE_SIZE=50G >> .env
@@ -44,7 +52,13 @@ runs:
4452
echo SCCACHE_ERROR_LOG=/tmp/sccache_log.txt >> .env
4553
echo SCCACHE_GCS_RW_MODE=READ_WRITE >> .env
4654
echo RUSTC_WRAPPER=sccache >> .env
47-
echo DOCKER_PWD=$(pwd) >> .env
55+
56+
# The zk-environment image bakes in RUSTC_WRAPPER=sccache; empty means "no wrapper" to cargo.
57+
- name: Disable sccache inside Docker
58+
if: inputs.sccache != 'true'
59+
shell: bash
60+
run: |
61+
echo RUSTC_WRAPPER= >> .env
4862
4963
- name: Start localnet
5064
shell: bash
@@ -53,6 +67,7 @@ runs:
5367
ci_localnet_up
5468
5569
- name: Start sccache servers
70+
if: inputs.sccache == 'true'
5671
shell: bash
5772
run: |
5873
ci_run sccache --start-server

.github/workflows/ci-airbender-prover-e2e.yml

Lines changed: 368 additions & 0 deletions
Large diffs are not rendered by default.

.github/workflows/ci-prover-e2e.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ jobs:
1515
CUDA_ARCH: "75;80;89;90"
1616
CUDAARCHS: "75;80;89;90"
1717
PASSED_ENV_VARS: "CUDA_ARCH,CUDAARCHS"
18-
1918
steps:
2019
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
2120
with:

.github/workflows/ci.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
core: ${{ steps.changed-files.outputs.core_any_changed }}
1717
prover: ${{ steps.changed-files.outputs.prover_any_changed }}
1818
airbender_prover_server: ${{ steps.changed-files.outputs.airbender_prover_server_any_changed }}
19+
airbender_e2e: ${{ steps.changed-files.outputs.airbender_e2e_any_changed }}
1920
docs: ${{ steps.changed-files.outputs.docs_any_changed }}
2021
all: ${{ steps.changed-files.outputs.all_any_changed }}
2122
steps:
@@ -57,6 +58,23 @@ jobs:
5758
- '.github/workflows/actions/**'
5859
- '!**/*.md'
5960
- '!**/*.MD'
61+
# Airbender GPU e2e lane: the prover server and the core code it exercises.
62+
airbender_e2e:
63+
- 'airbender_prover_server/**'
64+
- 'docker/airbender-prover-server/**'
65+
- 'core/node/airbender_proof_data_handler/**'
66+
- 'core/lib/airbender_prover_interface/**'
67+
- 'core/lib/airbender_verifier/**'
68+
- 'core/lib/dal/src/airbender_proof_generation_dal.rs'
69+
- 'core/lib/dal/src/models/storage_airbender_proof.rs'
70+
- 'core/lib/dal/migrations/*airbender*'
71+
- '.github/workflows/ci-airbender-prover-e2e.yml'
72+
- '.github/workflows/build-airbender-prover-server-template.yml'
73+
# Only setup-env, not all actions — this lane occupies a scarce GPU runner for hours.
74+
- '.github/actions/setup-env/**'
75+
- 'bin/prover_checkers/**'
76+
- '!**/*.md'
77+
- '!**/*.MD'
6078
core:
6179
- 'core/**'
6280
- '!core/CHANGELOG.md'
@@ -124,6 +142,16 @@ jobs:
124142
if: ${{ (needs.changed_files.outputs.airbender_prover_server == 'true' || needs.changed_files.outputs.all == 'true') && !contains(github.head_ref, 'release-please--branches') }}
125143
uses: ./.github/workflows/ci-airbender-prover-server-reusable.yml
126144

145+
e2e-for-airbender-prover:
146+
name: E2E Test for Airbender Prover
147+
needs: changed_files
148+
permissions:
149+
contents: read
150+
# Same-repo PRs only: the e2e job executes a PR-built binary on a persistent self-hosted GPU
151+
# runner, so fork-controlled code must never reach it.
152+
if: ${{ (needs.changed_files.outputs.airbender_e2e == 'true' || needs.changed_files.outputs.all == 'true') && !contains(github.head_ref, 'release-please--branches') && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }}
153+
uses: ./.github/workflows/ci-airbender-prover-e2e.yml
154+
127155
ci-for-docs:
128156
needs: changed_files
129157
if: needs.changed_files.outputs.docs == 'true'
@@ -196,6 +224,7 @@ jobs:
196224
build-prover-images,
197225
build-airbender-prover-server-images,
198226
e2e-for-prover,
227+
e2e-for-airbender-prover,
199228
]
200229
steps:
201230
- name: Status

airbender_prover_server/Cargo.lock

Lines changed: 41 additions & 41 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

airbender_prover_server/Cargo.toml

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,8 @@ vise-exporter = "0.3.2"
102102
# workspace dep — a member's `default-features = false` is otherwise ignored.
103103
airbender-host = { git = "https://github.com/matter-labs/airbender-platform", tag = "v0.2.3", default-features = false }
104104

105-
# eravm-airbender-verifier crates, pinned to the released tag `v29.8.0`.
106-
# `build.rs` derives this tag from cargo metadata and downloads the matching
107-
# artifacts, so they track the verifier code we compile against.
108-
# `default-features = false` drops the host crate's default `gpu_fri`; the
109-
# server re-enables it via its own `gpu_fri` feature. Set on the workspace dep
110-
# so a member's `default-features = false` isn't ignored.
111-
eravm-prover-host = { git = "https://github.com/matter-labs/eravm-airbender-verifier", tag = "v29.8.0", default-features = false }
112-
# Same tag as eravm-prover-host so the two git copies unify into one crate
113-
# instance. Used by the client to deserialize jobs into the verifier input type.
114-
zksync_airbender_verifier = { git = "https://github.com/matter-labs/eravm-airbender-verifier", tag = "v29.8.0" }
105+
eravm-prover-host = { git = "https://github.com/matter-labs/eravm-airbender-verifier", tag = "v31.1.1", default-features = false }
106+
zksync_airbender_verifier = { git = "https://github.com/matter-labs/eravm-airbender-verifier", tag = "v31.1.1" }
115107

116108
# Local crates in this workspace.
117109
zksync_cli_utils = { path = "crates/lib/cli_utils" }

0 commit comments

Comments
 (0)