Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9d4b9b0
Add proving time instrumentation and log-parsing benchmark script
avilagaston9 Feb 6, 2026
f16d3d0
Fix stale VK file paths in deployer after guest program was moved out…
avilagaston9 Feb 6, 2026
5bccf59
Use pending nonce in load test to support consecutive runs without no…
avilagaston9 Feb 6, 2026
0ff9f59
Enrich benchmark script with batch metadata from Prometheus metrics e…
avilagaston9 Feb 6, 2026
a236c08
Make benchmark script read the log file once and exit instead of tail…
avilagaston9 Feb 6, 2026
a56a257
Fix off-by-one in batch_size metric: a batch spanning blocks [first, …
avilagaston9 Feb 6, 2026
9fbeaef
Add --timed/--no-timed flag to prover to control proving time measure…
avilagaston9 Feb 9, 2026
05c0785
Add env var support to load test CLI for RPC URL, tx amount, and endl…
avilagaston9 Feb 9, 2026
ab55110
Add prover benchmarking guide and agent workflow documentation.
avilagaston9 Feb 9, 2026
a786cd1
Extract load test round logic into run_round function and use it once
avilagaston9 Feb 9, 2026
48ec1c1
Change load_test and wait_until_all_included to take references for c…
avilagaston9 Feb 9, 2026
9fd1d07
Change --timed flag default to false so it must be explicitly opted in.
avilagaston9 Feb 9, 2026
131c650
Clarify GPU acceleration option in prover benchmarking guide by showing
avilagaston9 Feb 9, 2026
8375cb2
Add PROVER_ARGS variable to Makefile prover targets so extra flags like
avilagaston9 Feb 9, 2026
d0fbcaa
Use PROVER_CLIENT_TIMED env var in Makefile prover targets instead of
avilagaston9 Feb 9, 2026
baae118
Use PROVER_CLIENT_TIMED env var directly instead of a TIMED Makefile …
avilagaston9 Feb 9, 2026
e60ed34
Rewrite benchmark script to output a markdown file with a table and s…
avilagaston9 Feb 9, 2026
ff9e680
Remove load-test target from crates/l2/Makefile and use the existing
avilagaston9 Feb 9, 2026
f87ed2a
Add automatic server specs detection (CPU, RAM, GPU) to the benchmark
avilagaston9 Feb 9, 2026
db185aa
Add batches-to-prove prompt to agent setup instructions and include
avilagaston9 Feb 9, 2026
7e49164
Clarify that LOAD_TEST_RPC_URL must point to the L2 node RPC (port 1729
avilagaston9 Feb 9, 2026
517e535
Add prover_type to BatchRequest so the proof coordinator can filter
avilagaston9 Feb 9, 2026
8bd6f49
Remove redundant prover_type field from Prover struct — the backend
avilagaston9 Feb 9, 2026
49cedbf
Add missing prover_type field to TDX quote-gen BatchRequest and fix l…
avilagaston9 Feb 10, 2026
88151ee
Clarify in prover benchmarking workflow that the load test must be st…
avilagaston9 Feb 10, 2026
b4fe39c
Pre-compile the load test binary before starting the L2 to avoid
avilagaston9 Feb 10, 2026
90f8b4b
Use pre-built binaries in benchmarking workflow to eliminate redundan…
avilagaston9 Feb 10, 2026
1d3ad05
Replace todo!() with unimplemented!() in OpenVM and ZisK backends, re…
avilagaston9 Feb 10, 2026
01db920
Skip batch assignment when the requesting prover's proof already exists,
avilagaston9 Feb 11, 2026
2cb2ffe
Return ProverTypeNotNeeded immediately when a prover connects with a
avilagaston9 Feb 11, 2026
00c7bf6
Remove the all_proofs_exist loop from handle_request since it is redu…
avilagaston9 Feb 11, 2026
a059a43
Flatten handle_request into sequential early returns instead of a nested
avilagaston9 Feb 11, 2026
368cda9
Remove the redundant contains_batch check in handle_request since
avilagaston9 Feb 11, 2026
5d34ed6
Move the prover type check before the store query in handle_request so
avilagaston9 Feb 11, 2026
0740241
Fix --sp1 flag in Makefile to pass explicit 'true' value (the arg uses
avilagaston9 Feb 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cmd/ethrex/l2/deployer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1015,17 +1015,17 @@ fn get_vk(prover_type: ProverType, opts: &DeployerOptions) -> Result<Bytes, Depl
let vk_path = {
let path = match &prover_type {
ProverType::RISC0 => format!(
"{}/../../crates/l2/prover/src/ethrex_guest_program/src/risc0/out/riscv32im-risc0-vk",
"{}/../../crates/guest-program/bin/risc0/out/riscv32im-risc0-vk",
env!("CARGO_MANIFEST_DIR")
),
// Aligned requires the vk's 32 bytes hash, while the L1 verifier requires
// the hash as a bn254 F_r element.
ProverType::SP1 if opts.aligned => format!(
"{}/../../crates/l2/prover/src/ethrex_guest_program/src/sp1/out/riscv32im-succinct-zkvm-vk-u32",
"{}/../../crates/guest-program/bin/sp1/out/riscv32im-succinct-zkvm-vk-u32",
env!("CARGO_MANIFEST_DIR")
),
ProverType::SP1 if !opts.aligned => format!(
"{}/../../crates/l2/prover/src/ethrex_guest_program/src/sp1/out/riscv32im-succinct-zkvm-vk-bn254",
"{}/../../crates/guest-program/bin/sp1/out/riscv32im-succinct-zkvm-vk-bn254",
env!("CARGO_MANIFEST_DIR")
),
// other types don't have a verification key
Expand Down
10 changes: 10 additions & 0 deletions cmd/ethrex/l2/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,14 @@ pub struct ProverClientOptions {
help_heading = "Prover client options"
)]
pub log_level: Level,
#[arg(
long,
default_value_t = false,
env = "PROVER_CLIENT_TIMED",
help = "Measure and log proving time for each batch",
help_heading = "Prover client options"
)]
pub timed: bool,
#[cfg(all(feature = "sp1", feature = "gpu"))]
#[arg(
long,
Expand All @@ -1098,6 +1106,7 @@ impl From<ProverClientOptions> for ProverConfig {
backend: config.backend,
proof_coordinators: config.proof_coordinator_endpoints,
proving_time_ms: config.proving_time_ms,
timed: config.timed,
#[cfg(all(feature = "sp1", feature = "gpu"))]
sp1_server: config.sp1_server,
}
Expand All @@ -1113,6 +1122,7 @@ impl Default for ProverClientOptions {
proving_time_ms: 5000,
log_level: Level::INFO,
backend: BackendType::Exec,
timed: false,
#[cfg(all(feature = "sp1", feature = "gpu"))]
sp1_server: None,
}
Expand Down
7 changes: 2 additions & 5 deletions crates/l2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,12 @@ deploy-l1: ## 📜 Deploys the L1 contracts
--genesis-l2-path ${L2_GENESIS_FILE_PATH}

## Same as deploy-l1 but deploys the SP1 verifier
deploy-l1-sp1: ## 📜 Deploys the L1 contracts
deploy-l1-sp1: ## 📜 Deploys the L1 contracts with SP1 verifier
COMPILE_CONTRACTS=true \
cargo run --release --features l2,l2-sql --manifest-path ../../Cargo.toml -- l2 deploy \
--eth-rpc-url ${L1_RPC_URL} \
--private-key ${L1_PRIVATE_KEY} \
--risc0.verifier-address 0x00000000000000000000000000000000000000aa \
--sp1.deploy-verifier \
--tdx.verifier-address 0x00000000000000000000000000000000000000aa \
--aligned.aggregator-address 0x00000000000000000000000000000000000000aa \
--sp1 true \
--on-chain-proposer-owner ${L2_OWNER_ADDRESS} \
--bridge-owner ${L2_OWNER_ADDRESS} \
--bridge-owner-pk ${BRIDGE_OWNER_PRIVATE_KEY} \
Expand Down
19 changes: 16 additions & 3 deletions crates/l2/common/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,24 @@ pub enum ProofData {
/// The Client initiates the connection with a BatchRequest.
/// Asking for the ProverInputData the prover_server considers/needs.
/// The commit hash is used to ensure the client and server are compatible.
BatchRequest { commit_hash: String },
/// The prover_type tells the coordinator which backend the client runs,
/// so it can skip batches that already have a proof for that type.
BatchRequest {
commit_hash: String,
prover_type: ProverType,
},

/// 4.
/// The Server responds with a NoBatchForVersion if the code version is not the same as the one
/// generated in the batch.
/// The Client can only prove batches of its own version.
NoBatchForVersion { commit_hash: String },

/// 4b.
/// The Server responds with ProverTypeNotNeeded when the connecting prover's
/// backend type is not in the set of required proof types for this deployment.
ProverTypeNotNeeded { prover_type: ProverType },

/// 5.
/// The Server responds with a BatchResponse containing the ProverInputData.
/// If the BatchResponse is ProofData::BatchResponse{None, None},
Expand Down Expand Up @@ -224,8 +234,11 @@ impl ProofData {
}

/// Builder function for creating a BatchRequest
pub fn batch_request(commit_hash: String) -> Self {
ProofData::BatchRequest { commit_hash }
pub fn batch_request(commit_hash: String, prover_type: ProverType) -> Self {
ProofData::BatchRequest {
commit_hash,
prover_type,
}
}

/// Builder function for creating a NoBatchForVersion
Expand Down
4 changes: 4 additions & 0 deletions crates/l2/prover/src/backend/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ impl ProverBackend for ExecBackend {
type ProofOutput = ProgramOutput;
type SerializedInput = ();

fn prover_type(&self) -> ProverType {
ProverType::Exec
}

fn serialize_input(
&self,
_input: &ProgramInput,
Expand Down
5 changes: 4 additions & 1 deletion crates/l2/prover/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::time::{Duration, Instant};

use clap::ValueEnum;
use ethrex_guest_program::input::ProgramInput;
use ethrex_l2_common::prover::{BatchProof, ProofFormat};
use ethrex_l2_common::prover::{BatchProof, ProofFormat, ProverType};
use serde::{Deserialize, Serialize};

pub mod error;
Expand Down Expand Up @@ -85,6 +85,9 @@ pub trait ProverBackend {
/// The serialized input type specific to this backend.
type SerializedInput;

/// Returns the ProverType for this backend.
fn prover_type(&self) -> ProverType;

/// Serialize the program input into the backend-specific format.
fn serialize_input(&self, input: &ProgramInput) -> Result<Self::SerializedInput, BackendError>;

Expand Down
6 changes: 5 additions & 1 deletion crates/l2/prover/src/backend/openvm.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::time::{Duration, Instant};

use ethrex_guest_program::input::ProgramInput;
use ethrex_l2_common::prover::{BatchProof, ProofFormat};
use ethrex_l2_common::prover::{BatchProof, ProofFormat, ProverType};
use openvm_continuations::verifier::internal::types::VmStarkProof;
use openvm_sdk::{Sdk, StdIn, types::EvmProof};
use openvm_stark_sdk::config::baby_bear_poseidon2::BabyBearPoseidon2Config;
Expand Down Expand Up @@ -64,6 +64,10 @@ impl ProverBackend for OpenVmBackend {
type ProofOutput = OpenVmProveOutput;
type SerializedInput = StdIn;

fn prover_type(&self) -> ProverType {
unimplemented!("OpenVM is not yet enabled as a backend for the L2")
}

fn serialize_input(&self, input: &ProgramInput) -> Result<Self::SerializedInput, BackendError> {
let mut stdin = StdIn::default();
let bytes = rkyv::to_bytes::<Error>(input).map_err(BackendError::serialization)?;
Expand Down
4 changes: 4 additions & 0 deletions crates/l2/prover/src/backend/risc0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ impl ProverBackend for Risc0Backend {
type ProofOutput = Receipt;
type SerializedInput = ExecutorEnv<'static>;

fn prover_type(&self) -> ProverType {
ProverType::RISC0
}

fn serialize_input(&self, input: &ProgramInput) -> Result<Self::SerializedInput, BackendError> {
let bytes = rkyv::to_bytes::<RkyvError>(input).map_err(BackendError::serialization)?;
ExecutorEnv::builder()
Expand Down
4 changes: 4 additions & 0 deletions crates/l2/prover/src/backend/sp1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ impl ProverBackend for Sp1Backend {
type ProofOutput = Sp1ProveOutput;
type SerializedInput = SP1Stdin;

fn prover_type(&self) -> ProverType {
ProverType::SP1
}

fn serialize_input(&self, input: &ProgramInput) -> Result<Self::SerializedInput, BackendError> {
let mut stdin = SP1Stdin::new();
let bytes = rkyv::to_bytes::<Error>(input).map_err(BackendError::serialization)?;
Expand Down
6 changes: 5 additions & 1 deletion crates/l2/prover/src/backend/zisk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
};

use ethrex_guest_program::{ZKVM_ZISK_PROGRAM_ELF, input::ProgramInput};
use ethrex_l2_common::prover::{BatchProof, ProofFormat};
use ethrex_l2_common::prover::{BatchProof, ProofFormat, ProverType};

use crate::backend::{BackendError, ProverBackend};

Expand Down Expand Up @@ -113,6 +113,10 @@ impl ProverBackend for ZiskBackend {
type ProofOutput = ZiskProveOutput;
type SerializedInput = ();

fn prover_type(&self) -> ProverType {
unimplemented!("ZisK is not yet enabled as a backend for the L2")
}

fn serialize_input(&self, input: &ProgramInput) -> Result<Self::SerializedInput, BackendError> {
let input_bytes =
rkyv::to_bytes::<rkyv::rancor::Error>(input).map_err(BackendError::serialization)?;
Expand Down
1 change: 1 addition & 0 deletions crates/l2/prover/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub struct ProverConfig {
pub backend: BackendType,
pub proof_coordinators: Vec<Url>,
pub proving_time_ms: u64,
pub timed: bool,
#[cfg(all(feature = "sp1", feature = "gpu"))]
pub sp1_server: Option<Url>,
}
46 changes: 39 additions & 7 deletions crates/l2/prover/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ struct Prover<B: ProverBackend> {
backend: B,
proof_coordinator_endpoints: Vec<Url>,
proving_time_ms: u64,
timed: bool,
commit_hash: String,
}

Expand All @@ -70,6 +71,7 @@ impl<B: ProverBackend> Prover<B> {
backend,
proof_coordinator_endpoints: cfg.proof_coordinators.clone(),
proving_time_ms: cfg.proving_time_ms,
timed: cfg.timed,
commit_hash: get_git_commit_hash(),
}
}
Expand Down Expand Up @@ -97,12 +99,33 @@ impl<B: ProverBackend> Prover<B> {

// If we get the input
// Generate the Proof
let Ok(batch_proof) = self
.backend
.prove(prover_data.input, prover_data.format)
.and_then(|output| self.backend.to_batch_proof(output, prover_data.format))
.inspect_err(|e| error!("{e}"))
else {
let batch_proof = if self.timed {
self.backend
.prove_timed(prover_data.input, prover_data.format)
.and_then(|(output, elapsed)| {
info!(
batch = prover_data.batch_number,
proving_time_s = elapsed.as_secs(),
proving_time_ms =
u64::try_from(elapsed.as_millis()).unwrap_or(u64::MAX),
"Proved batch {} in {:.2?}",
prover_data.batch_number,
elapsed
);
self.backend.to_batch_proof(output, prover_data.format)
})
} else {
self.backend
.prove(prover_data.input, prover_data.format)
.and_then(|output| {
info!(
batch = prover_data.batch_number,
"Proved batch {}", prover_data.batch_number
);
self.backend.to_batch_proof(output, prover_data.format)
})
};
let Ok(batch_proof) = batch_proof.inspect_err(|e| error!("{e}")) else {
continue;
};

Expand All @@ -118,7 +141,8 @@ impl<B: ProverBackend> Prover<B> {

async fn request_new_input(&self, endpoint: &Url) -> Result<Option<ProverData>, String> {
// Request the input with the correct batch_number
let request = ProofData::batch_request(self.commit_hash.clone());
let request =
ProofData::batch_request(self.commit_hash.clone(), self.backend.prover_type());
let response = connect_to_prover_server_wr(endpoint, &request)
.await
.map_err(|e| format!("Failed to get Response: {e}"))?;
Expand All @@ -136,6 +160,14 @@ impl<B: ProverBackend> Prover<B> {
);
return Ok(None);
}
ProofData::ProverTypeNotNeeded { prover_type } => {
error!(
"Proof coordinator does not need {prover_type} proofs. \
This prover's backend is not in the required proof types for this deployment. \
Shutting down."
);
std::process::exit(1);
}
_ => return Err("Expecting ProofData::Response".to_owned()),
};

Expand Down
2 changes: 1 addition & 1 deletion crates/l2/sequencer/l1_committer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,7 @@ impl L1Committer {
#[allow(clippy::as_conversions)]
let blob_usage_percentage = blob_size as f64 * 100_f64 / ethrex_common::types::BYTES_PER_BLOB_F64;
let batch_gas_used = batch_gas_used.try_into()?;
let batch_size = (last_added_block_number - first_block_of_batch).try_into()?;
let batch_size = (last_added_block_number - first_block_of_batch + 1).try_into()?;
let tx_count = tx_count.try_into()?;
METRICS.set_blob_usage_percentage(blob_usage_percentage);
METRICS.set_batch_gas_used(batch_number, batch_gas_used)?;
Expand Down
Loading