The Scroll proving stack consists of two primary runtime components written in Rust and Go, plus a shared Rust library used for proof verification.
┌─────────────────────────────────────────────────────────────────────┐
│ Coordinator (Go) │
│ Task scheduler & proof verifier │
│ • Reads pending chunk / batch / bundle tasks from PostgreSQL │
│ • Distributes tasks to connected provers │
│ • Validates proofs submitted by provers via libzkp (FFI) │
│ • Serves gRPC/HTTP APIs for provers and rollup services │
└──────────────────────────────┬──────────────────────────────────────┘
│ assign / submit
┌──────────────────────────────▼──────────────────────────────────────┐
│ Prover (Rust, prover-bin) │
│ ZK proof generator │
│ • Polls coordinator for proving tasks │
│ • Executes zkvm-prover (OpenVM) to generate STARK/SNARK proofs │
│ • Submits proof results back to coordinator │
│ • Supports three task types: Chunk, Batch, Bundle │
└─────────────────────────────────────────────────────────────────────┘
- Rollup services (in
rollup/) ingest L2 blocks, group them into chunks, batches, and bundles, and write task records into PostgreSQL. - Coordinator (
coordinator/) discovers these records and advertises them to connected provers. - Prover (
crates/prover-bin/) fetches a task, downloads the required verification key (VK) asset, runs the zkVM circuit, and produces a proof. - Coordinator receives the proof and calls
libzkp(via CGO) to verify it before marking the task complete.
Shared Rust library containing:
- Witness serialization / deserialization for chunk, batch, and bundle tasks
- Proof verification logic
- FFI bindings (
libzkp_c) so the Go coordinator can link againstlibzkp.so
Important: Any breaking change to witness formats or proof structures requires rebuilding libzkp.so and relinking the coordinator.
The prover binary. Key concepts:
- UniversalHandler: Dynamically loads circuit assets (VKs, params) based on the task's fork name (e.g.,
galileo,galileoV2). - AssetsLocationData: Configures where to download circuit assets from.
debug_modeskips remote size verification when a local file already exists. - Task types:
Chunk: Prove a group of L2 blocksBatch: Prove a group of chunksBundle: Prove a group of batches
- Commands:
handle <json>: Prove a specific set of task IDsdump <type> <id>: Export task input data to local files (JSON or bincode) without proving- (no subcommand): Run as a persistent service polling coordinator
Go service with three entry points:
coordinator_api: Main API servercoordinator_cron: Background jobscoordinator_tool: CLI utilities
The coordinator links against libzkp.so at build time. The localsetup Makefile target builds the .so, builds the binary, and copies config templates.
End-to-end test harness for the proving pipeline.
-
Each subdirectory (
sepolia-galileoV2,mainnet-galileo,cloak-galileoV2, etc.) contains:.make.env: Block range and fork nameconfig.json: Database / RPC config for the test toolconfig.template.json: Coordinator config templategenesis.json: Chain genesis for the local import.sqlfiles (optional): Pre-seeded block data
-
Workflow:
make all→ starts PostgreSQL container, buildse2e_tool, imports blocks from RPC into DBmake coordinator_setup→ builds coordinator API binary and copies config- Run
coordinator_apilocally - Configure and run
prover→ connects to local coordinator and proves injected tasks
- Workspace version: defined in root
Cargo.toml(workspace.package.version) - ZK version: derived from
zkvm-provergit commit +Plonky3git commit, embedded into coordinator/prover binaries at build time - Fork names: hard-fork identifiers (
galileo,galileoV2, ...) that select which circuit assets and witness formats to use
Prover and coordinator must agree on:
- ZK version (assets compatibility)
- Fork name support (coordinator's verifier config must list the fork, prover must have the asset)
- Task type enum values
cd zkvm-prover
make prover_cpu
# Binary appears at ../target/release/provercd zkvm-prover
make provercd coordinator
make coordinator_api
# Requires libzkp.so to be built firstcd tests/prover-e2e
ln -s sepolia-galileoV2 conf
make all
make coordinator_setup
cd ../../coordinator/build/bin
# edit conf/config.json if needed
./coordinator_api
# In another terminal:
cd zkvm-prover
# copy config.template.json → config.json, set coordinator base_url
make test_e2e_runFor a production-like setup using Docker containers and the Coordinator Proxy, see docs/testing/docker-compose-e2e-guide.md.
- The prover downloads large circuit assets (VKs, params) on first use. Ensure sufficient disk space and network bandwidth.
debug_modeinAssetsLocationDatais intended for local development only; do not enable in production.- A prover panic now triggers
resume_unwind, killing the worker thread (and potentially the process). Monitor prover restarts in production.