Skip to content

Commit c6291e4

Browse files
committed
Address review feedback: align OpenVM/ZisK with PR #6157 (todo! → unimplemented!),
make send_batches_proof_to_contract private, add natspec to based contract's verifyBatches noting it has no access control, update all L2 docs replacing verifyBatch references with verifyBatches, move distributed_proving.md from docs/prover/ to docs/l2/fundamentals/ since it describes the interaction between proof coordinator, proof sender, and provers rather than prover internals, and restructure the doc to be explanation-first with the testing guide at the end.
1 parent fb160e6 commit c6291e4

File tree

14 files changed

+89
-78
lines changed

14 files changed

+89
-78
lines changed

crates/l2/contracts/src/l1/based/OnChainProposer.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,8 @@ contract OnChainProposer is
431431
}
432432

433433
/// @inheritdoc IOnChainProposer
434+
/// @notice Callable by anyone (no access control) so that any party can
435+
/// advance verification once proofs are available.
434436
function verifyBatches(
435437
uint256 firstBatchNumber,
436438
bytes[] memory risc0BlockProofs,

crates/l2/prover/src/backend/openvm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ impl ProverBackend for OpenVmBackend {
6565
type SerializedInput = StdIn;
6666

6767
fn prover_type(&self) -> ProverType {
68-
todo!("No ProverType variant exists for OpenVM yet")
68+
unimplemented!("OpenVM is not yet enabled as a backend for the L2")
6969
}
7070

7171
fn serialize_input(&self, input: &ProgramInput) -> Result<Self::SerializedInput, BackendError> {

crates/l2/prover/src/backend/zisk.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl ProverBackend for ZiskBackend {
114114
type SerializedInput = ();
115115

116116
fn prover_type(&self) -> ProverType {
117-
todo!("No ProverType variant exists for ZisK yet")
117+
unimplemented!("ZisK is not yet enabled as a backend for the L2")
118118
}
119119

120120
fn serialize_input(&self, input: &ProgramInput) -> Result<Self::SerializedInput, BackendError> {

crates/l2/sequencer/l1_proof_sender.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ impl L1ProofSender {
580580
/// Sends one or more consecutive batch proofs in a single verifyBatches transaction.
581581
/// On revert with an invalid proof message, falls back to sending each batch
582582
/// individually to identify which batch has the bad proof.
583-
pub async fn send_batches_proof_to_contract(
583+
async fn send_batches_proof_to_contract(
584584
&self,
585585
first_batch: u64,
586586
batches: &[(u64, HashMap<ProverType, BatchProof>)],

docs/l2/deployment/aligned.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ INFO ethrex_l2::sequencer::l1_proof_verifier: Batches verified in OnChainPropose
355355
356356
### OnChainProposer
357357
358-
- Uses `verifyBatchesAligned()` instead of `verifyBatch()` (used in standard mode).
358+
- Uses `verifyBatchesAligned()` instead of `verifyBatches()` (used in standard mode).
359359
- Receives an array of proofs to verify.
360360
- Delegates proof verification to the `AlignedProofAggregatorService` contract.
361361

docs/l2/deployment/aligned_failure_recovery.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ ethrex l2 \
250250

251251
1. Restart the prover(s) - they will automatically generate Groth16 proofs (since `--aligned` is not set)
252252
2. ProofCoordinator will request proofs starting from `lastVerifiedBatch + 1`
253-
3. L1ProofSender will submit directly to OnChainProposer.verifyBatch()
253+
3. L1ProofSender will submit directly to OnChainProposer.verifyBatches()
254254

255255

256256
---
@@ -355,7 +355,7 @@ The response includes:
355355

356356
| Code | Meaning | Action |
357357
|------|---------|--------|
358-
| `00h` | Use verifyBatch instead | Contract not in Aligned mode |
358+
| `00h` | Use verifyBatches instead | Contract not in Aligned mode |
359359
| `00m` | Invalid Aligned proof | Proof will be deleted and regenerated |
360360
| `00y` | AlignedProofAggregator call failed | Check aggregator contract address |
361361
| `00z` | Aligned proof verification failed | Merkle proof invalid |

docs/l2/fundamentals/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ For general documentation, see:
3030
- [Fee token](./fee_token.md)
3131
- [Exit window](./exit_window.md) and [Timelock](./timelock.md) for upgrade safety mechanisms.
3232
- [Aligned Layer Integration](./ethrex_l2_aligned_integration.md) details how ethrex L2 integrates with Aligned Layer for proof aggregation and verification.
33+
- [Distributed proving](./distributed_proving.md) explains how the proof coordinator, proof sender, and provers interact to enable parallel proving and multi-batch L1 verification.

docs/l2/fundamentals/based.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ The `OnChainProposer` contract, which handles batch proposals and management on
7878
- **Event Modification:**
7979
The `BatchCommitted` event has been updated to include the batch number of the committed batch. This addition enhances traceability and allows external systems to monitor batch progression more effectively.
8080
- **Batch Verification:**
81-
The `verifyBatch` method has been made more flexible and decentralized:
82-
- The `onlySequencer` modifier has been removed, allowing anyone—not just the lead Sequencer—to verify batches.
83-
- The restriction preventing multiple verifications of the same batch has been lifted. While multiple verifications are now permitted, only one valid verification is required to advance the L2 state. This change improves resilience and reduces dependency on a single actor.
81+
The `verifyBatches` method has been made more flexible and decentralized:
82+
- The method has no access control modifier, allowing anyone—not just the lead Sequencer—to verify batches.
83+
- It supports verifying one or more consecutive batches in a single transaction. Only one valid verification is required to advance the L2 state. This change improves resilience and reduces dependency on a single actor.
8484

8585
### SequencerRegistry (New Contract)
8686

docs/l2/fundamentals/contracts.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ The `OnChainProposer` is an upgradeable smart contract that ensures the advancem
6161
- **`revertBatch()`**: Removes unverified batches (only callable when paused)
6262
6363
2. **Proof Verification**
64-
- **`verifyBatch()`**: Verifies a single batch using RISC0, SP1, or TDX proofs
64+
- **`verifyBatches()`**: Verifies one or more consecutive batches using RISC0, SP1, or TDX proofs
6565
- **`verifyBatchesAligned()`**: Verifies multiple batches in sequence using aligned proofs with Merkle verification
6666
6767
## L2 Contracts

docs/prover/distributed_proving.md renamed to docs/l2/fundamentals/distributed_proving.md

Lines changed: 59 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Distributed Proving
22

3-
Distributed proving allows running multiple prover instances in parallel, each working on different batches simultaneously. The proof coordinator assigns work to provers and collects their proofs, then the proof sender batches multiple consecutive proofs into a single L1 verification transaction.
3+
## Overview
4+
5+
Distributed proving enables running multiple prover instances in parallel, each working on different batches simultaneously. It has two key aspects:
6+
7+
1. **Parallel batch assignment**: the proof coordinator assigns different batches to different provers, so multiple provers work simultaneously.
8+
2. **Multi-batch verification**: the proof sender collects consecutive proven batches and submits them in a single `verifyBatches()` L1 transaction, saving gas.
49

510
## Architecture
611

@@ -28,9 +33,60 @@ Distributed proving allows running multiple prover instances in parallel, each w
2833
└────────────┘
2934
```
3035

31-
Multiple provers connect to the same proof coordinator. The coordinator tracks assignments per `(batch_number, prover_type)`, so:
36+
Multiple provers connect to the same proof coordinator over TCP. The coordinator tracks assignments per `(batch_number, prover_type)`, so:
37+
3238
- Two `sp1` provers get assigned **different** batches.
33-
- An `sp1` prover and an `risc0` prover can work on the **same** batch simultaneously (they produce different proof types).
39+
- An `sp1` prover and a `risc0` prover can work on the **same** batch simultaneously (they produce different proof types).
40+
41+
## Batch assignment
42+
43+
When a prover sends a `BatchRequest`, it includes its `prover_type`. The coordinator:
44+
45+
1. Scans batches starting from the oldest unverified one.
46+
2. Skips batches that already have a proof for this `prover_type`.
47+
3. Skips batches currently assigned to another prover of the same type (unless the assignment has timed out).
48+
4. Assigns the first available batch and records `(batch_number, prover_type) → Instant::now()`.
49+
50+
The assignment map is in-memory only — it is lost on restart. On restart, the coordinator simply reassigns batches from scratch, which is safe because storing a duplicate proof is a no-op.
51+
52+
## Prover timeout
53+
54+
If a prover doesn't submit a proof within `prover-timeout` (default 10 minutes), its assignment expires and the batch becomes available for reassignment to another prover. This handles prover crashes, network issues, or slow provers without manual intervention.
55+
56+
## Multi-batch verification
57+
58+
The proof sender runs on a periodic tick (every `send-interval` ms). On each tick it:
59+
60+
1. Queries the on-chain `lastVerifiedBatch` and `lastCommittedBatch`.
61+
2. Collects all **consecutive** proven batches starting from `lastVerifiedBatch + 1`, checking that every required proof type is present for each batch.
62+
3. Sends them in a single `verifyBatches()` call to L1.
63+
64+
For example, if batches 5, 6, 7 are fully proven but batch 8 is missing a proof, only batches 5–7 are sent. Batch 8 waits for its proof.
65+
66+
### Fallback to single-batch sending
67+
68+
On **any** multi-batch error (gas limit exceeded, calldata too large, invalid proof, etc.), the proof sender falls back to sending each batch individually. Since on-chain verification is sequential (`batchNumber == lastVerifiedBatch + 1`), the fallback stops at the first failing batch — remaining batches are retried on the next tick.
69+
70+
During single-batch fallback, if the error indicates an invalid proof (e.g. "Invalid SP1 proof"), that proof is deleted from the store so a prover can re-prove it.
71+
72+
## Configuration reference
73+
74+
### Proof coordinator (sequencer side)
75+
76+
| Flag | Env Variable | Default | Description |
77+
|------|-------------|---------|-------------|
78+
| `--proof-coordinator.addr` | `ETHREX_PROOF_COORDINATOR_LISTEN_ADDRESS` | `127.0.0.1` | Listen address |
79+
| `--proof-coordinator.port` | `ETHREX_PROOF_COORDINATOR_LISTEN_PORT` | `3900` | Listen port |
80+
| `--proof-coordinator.send-interval` | `ETHREX_PROOF_COORDINATOR_SEND_INTERVAL` | `5000` | How often (ms) the proof sender collects and sends proofs to L1 |
81+
| `--proof-coordinator.prover-timeout` | `ETHREX_PROOF_COORDINATOR_PROVER_TIMEOUT` | `600000` | Timeout (ms) before reassigning a batch to another prover (default: 10 min) |
82+
83+
### Prover client
84+
85+
| Flag | Env Variable | Default | Description |
86+
|------|-------------|---------|-------------|
87+
| `--proof-coordinators` | `PROVER_CLIENT_PROOF_COORDINATOR_URL` | `tcp://127.0.0.1:3900` | Space-separated coordinator URLs |
88+
| `--backend` | `PROVER_CLIENT_BACKEND` | `exec` | Backend: `exec`, `sp1`, `risc0`, `zisk`, `openvm` |
89+
| `--proving-time` | `PROVER_CLIENT_PROVING_TIME` | `5000` | Wait time (ms) between requesting new work |
3490

3591
## Testing locally
3692

@@ -74,47 +130,3 @@ make init-prover-exec
74130
```
75131

76132
Each prover will be assigned a different batch. When both finish, the proof sender will collect the consecutive proven batches and submit them in a single `verifyBatches` transaction on L1.
77-
78-
## Configuration reference
79-
80-
### Proof coordinator (L2 side)
81-
82-
| Flag | Env Variable | Default | Description |
83-
|------|-------------|---------|-------------|
84-
| `--proof-coordinator.addr` | `ETHREX_PROOF_COORDINATOR_LISTEN_ADDRESS` | `127.0.0.1` | Listen address |
85-
| `--proof-coordinator.port` | `ETHREX_PROOF_COORDINATOR_LISTEN_PORT` | `3900` | Listen port |
86-
| `--proof-coordinator.send-interval` | `ETHREX_PROOF_COORDINATOR_SEND_INTERVAL` | `5000` | How often (ms) the proof sender batches and sends proofs to L1 |
87-
| `--proof-coordinator.prover-timeout` | `ETHREX_PROOF_COORDINATOR_PROVER_TIMEOUT` | `600000` | Timeout (ms) before reassigning a batch to another prover (default: 10 min) |
88-
89-
### Prover client
90-
91-
| Flag | Env Variable | Default | Description |
92-
|------|-------------|---------|-------------|
93-
| `--proof-coordinators` | `PROVER_CLIENT_PROOF_COORDINATOR_URL` | `tcp://127.0.0.1:3900` | Space-separated coordinator URLs |
94-
| `--backend` | `PROVER_CLIENT_BACKEND` | `exec` | Backend: `exec`, `sp1`, `risc0`, `zisk`, `openvm` |
95-
| `--proving-time` | `PROVER_CLIENT_PROVING_TIME` | `5000` | Wait time (ms) between requesting new work |
96-
97-
## How it works
98-
99-
### Batch assignment
100-
101-
When a prover sends a `BatchRequest`, it includes its `prover_type`. The coordinator:
102-
103-
1. Scans batches starting from the oldest unverified one.
104-
2. Skips batches that already have a proof for this `prover_type`.
105-
3. Skips batches currently assigned to another prover of the same type (unless the assignment timed out).
106-
4. Assigns the first available batch and records `(batch_number, prover_type) → Instant::now()`.
107-
108-
### Prover timeout
109-
110-
If a prover doesn't submit a proof within `prover-timeout` (default 10 minutes), its assignment expires and the batch becomes available for reassignment to another prover.
111-
112-
### Multi-batch verification
113-
114-
The proof sender periodically (every `send-interval` ms):
115-
116-
1. Collects all **consecutive** proven batches starting from `last_verified_batch + 1`.
117-
2. Sends them in a single `verifyBatches()` call to L1.
118-
3. Falls back to per-batch verification if any batch has an invalid proof, to isolate the failure.
119-
120-
For example, if batches 1, 2, 3 are proven but 4 is not, only batches 1-3 are sent. Batch 4 waits for its proof.

0 commit comments

Comments
 (0)