Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
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
5 changes: 1 addition & 4 deletions crates/l2/prover/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,7 @@ openvm = [
profiling = ["sp1-sdk?/profiling"]

gpu = ["risc0-zkvm?/cuda", "sp1-sdk?/cuda", "openvm-sdk?/cuda"]
l2 = [
"guest_program/l2",
"ethrex-l2/l2",
]
l2 = ["guest_program/l2", "ethrex-l2/l2"]

# temporary feature until we fix cargo-zisk setup-rom from failing in the CI
ci = ["guest_program/ci"]
Expand Down
22 changes: 21 additions & 1 deletion crates/l2/prover/src/backend/exec.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::time::Instant;
use std::time::{Duration, Instant};
use tracing::{info, warn};

use ethrex_l2_common::{
Expand All @@ -16,6 +16,14 @@ pub fn execute(input: ProgramInput) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}

pub fn execute_timed(input: ProgramInput) -> Result<Duration, Box<dyn std::error::Error>> {
let now = Instant::now();
execution_program(input)?;
let duration = now.elapsed();

Ok(duration)
}

pub fn prove(
input: ProgramInput,
_format: ProofFormat,
Expand All @@ -25,6 +33,18 @@ pub fn prove(
Ok(output)
}

pub fn prove_timed(
input: ProgramInput,
_format: ProofFormat,
) -> Result<(ProgramOutput, Duration), Box<dyn std::error::Error>> {
warn!("\"exec\" prover backend generates no proof, only executes");
let now = Instant::now();
let output = execution_program(input)?;
let duration = now.elapsed();

Ok((output, duration))
}

pub fn verify(_proof: &ProgramOutput) -> Result<(), Box<dyn std::error::Error>> {
warn!("\"exec\" prover backend generates no proof, verification always succeeds");
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion crates/l2/prover/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub mod zisk;
#[cfg(feature = "openvm")]
pub mod openvm;

#[derive(Default, Debug, Deserialize, Serialize, Copy, Clone, ValueEnum)]
#[derive(Default, Debug, Deserialize, Serialize, Copy, Clone, ValueEnum, PartialEq)]
pub enum Backend {
#[default]
Exec,
Expand Down
42 changes: 42 additions & 0 deletions crates/l2/prover/src/backend/openvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ pub fn execute(input: ProgramInput) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}

pub fn execute_timed(
input: ProgramInput,
) -> Result<std::time::Duration, Box<dyn std::error::Error>> {
let sdk = Sdk::standard();

let mut stdin = StdIn::default();
let bytes = rkyv::to_bytes::<Error>(&input)?;
stdin.write_bytes(bytes.as_slice());

let start = std::time::Instant::now();
sdk.execute(PROGRAM_ELF, stdin.clone())?;
let duration = start.elapsed();

Ok(duration)
}

pub fn prove(
input: ProgramInput,
format: ProofFormat,
Expand All @@ -48,6 +64,32 @@ pub fn prove(
Ok(proof)
}

pub fn prove_timed(
input: ProgramInput,
format: ProofFormat,
) -> Result<(ProveOutput, std::time::Duration), Box<dyn std::error::Error>> {
let sdk = Sdk::standard();

let mut stdin = StdIn::default();
let bytes = rkyv::to_bytes::<Error>(&input)?;
stdin.write_bytes(bytes.as_slice());

let start = std::time::Instant::now();
let proof = match format {
ProofFormat::Compressed => {
let (proof, _) = sdk.prove(PROGRAM_ELF, stdin.clone())?;
ProveOutput::Compressed(proof)
}
ProofFormat::Groth16 => {
let proof = sdk.prove_evm(PROGRAM_ELF, stdin.clone())?;
ProveOutput::Groth16(proof)
}
};
let duration = start.elapsed();

Ok((proof, duration))
}

pub fn to_batch_proof(
_proof: ProveOutput,
_format: ProofFormat,
Expand Down
51 changes: 42 additions & 9 deletions crates/l2/prover/src/backend/risc0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use risc0_zkvm::{
serde::Error as Risc0SerdeError,
};
use rkyv::rancor::Error as RkyvError;
use std::time::Instant;
use std::time::{Duration, Instant};
use tracing::info;

#[derive(thiserror::Error, Debug)]
Expand All @@ -39,15 +39,26 @@ pub fn execute(input: ProgramInput) -> Result<(), Box<dyn std::error::Error>> {

let executor = default_executor();

let now = Instant::now();
let _session_info = executor.execute(env, ZKVM_RISC0_PROGRAM_ELF)?;
let elapsed = now.elapsed();

info!("Successfully executed RISC0 program in {elapsed:.2?}");

Ok(())
}

pub fn execute_timed(input: ProgramInput) -> Result<Duration, Box<dyn std::error::Error>> {
let bytes = rkyv::to_bytes::<RkyvError>(&input)?;
let env = ExecutorEnv::builder()
.write_slice(bytes.as_slice())
.build()?;

let executor = default_executor();

let start = Instant::now();
let _session_info = executor.execute(env, ZKVM_RISC0_PROGRAM_ELF)?;
let duration = start.elapsed();

Ok(duration)
}

pub fn prove(
input: ProgramInput,
format: ProofFormat,
Expand All @@ -67,15 +78,37 @@ pub fn prove(
ProofFormat::Groth16 => ProverOpts::groth16(),
};

let now = Instant::now();
let prove_info = prover.prove_with_opts(env, ZKVM_RISC0_PROGRAM_ELF, &prover_opts)?;
let elapsed = now.elapsed();

info!("Successfully proved RISC0 program in {elapsed:.2?}");

Ok(prove_info.receipt)
}

pub fn prove_timed(
input: ProgramInput,
format: ProofFormat,
) -> Result<(Receipt, Duration), Box<dyn std::error::Error>> {
let mut stdout = Vec::new();

let bytes = rkyv::to_bytes::<RkyvError>(&input)?;
let env = ExecutorEnv::builder()
.stdout(&mut stdout)
.write_slice(bytes.as_slice())
.build()?;

let prover = default_prover();

let prover_opts = match format {
ProofFormat::Compressed => ProverOpts::succinct(),
ProofFormat::Groth16 => ProverOpts::groth16(),
};

let start = Instant::now();
let prove_info = prover.prove_with_opts(env, ZKVM_RISC0_PROGRAM_ELF, &prover_opts)?;
let duration = start.elapsed();

Ok((prove_info.receipt, duration))
}

pub fn verify(receipt: &Receipt) -> Result<(), Error> {
receipt.verify(ZKVM_RISC0_PROGRAM_ID)?;
Ok(())
Expand Down
47 changes: 37 additions & 10 deletions crates/l2/prover/src/backend/sp1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use sp1_sdk::{
HashableKey, Prover, SP1ProofMode, SP1ProofWithPublicValues, SP1ProvingKey, SP1Stdin,
SP1VerifyingKey,
};
use std::{fmt::Debug, sync::OnceLock, time::Instant};
use std::{fmt::Debug, sync::OnceLock, time::{Duration, Instant}};
use tracing::info;
use url::Url;

Expand Down Expand Up @@ -84,15 +84,25 @@ pub fn execute(input: ProgramInput) -> Result<(), Box<dyn std::error::Error>> {

let setup = PROVER_SETUP.get_or_init(|| init_prover_setup(None));

let now = Instant::now();
setup.client.execute(ZKVM_SP1_PROGRAM_ELF, &stdin)?;
let elapsed = now.elapsed();

info!("Successfully executed SP1 program in {elapsed:.2?}");

Ok(())
}

pub fn execute_timed(input: ProgramInput) -> Result<Duration, Box<dyn std::error::Error>> {
let mut stdin = SP1Stdin::new();
let bytes = rkyv::to_bytes::<Error>(&input)?;
stdin.write_slice(bytes.as_slice());

let setup = PROVER_SETUP.get_or_init(|| init_prover_setup(None));

let start = Instant::now();
setup.client.execute(ZKVM_SP1_PROGRAM_ELF, &stdin)?;
let duration = start.elapsed();

Ok(duration)
}

pub fn prove(
input: ProgramInput,
format: ProofFormat,
Expand All @@ -103,21 +113,38 @@ pub fn prove(

let setup = PROVER_SETUP.get_or_init(|| init_prover_setup(None));

// contains the receipt along with statistics about execution of the guest
let format = match format {
ProofFormat::Compressed => SP1ProofMode::Compressed,
ProofFormat::Groth16 => SP1ProofMode::Groth16,
};

let now = Instant::now();
let proof = setup.client.prove(&setup.pk, &stdin, format)?;
let elapsed = now.elapsed();

info!("Successfully proved SP1 program in {elapsed:.2?}");

Ok(ProveOutput::new(proof, setup.vk.clone()))
}

pub fn prove_timed(
input: ProgramInput,
format: ProofFormat,
) -> Result<(ProveOutput, Duration), Box<dyn std::error::Error>> {
let mut stdin = SP1Stdin::new();
let bytes = rkyv::to_bytes::<Error>(&input)?;
stdin.write_slice(bytes.as_slice());

let setup = PROVER_SETUP.get_or_init(|| init_prover_setup(None));

let format = match format {
ProofFormat::Compressed => SP1ProofMode::Compressed,
ProofFormat::Groth16 => SP1ProofMode::Groth16,
};

let start = Instant::now();
let proof = setup.client.prove(&setup.pk, &stdin, format)?;
let duration = start.elapsed();

Ok((ProveOutput::new(proof, setup.vk.clone()), duration))
}

pub fn verify(output: &ProveOutput) -> Result<(), Box<dyn std::error::Error>> {
let setup = PROVER_SETUP.get_or_init(|| init_prover_setup(None));
setup.client.verify(&output.proof, &output.vk)?;
Expand Down
52 changes: 52 additions & 0 deletions crates/l2/prover/src/backend/zisk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,34 @@ pub fn execute(input: ProgramInput) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}

pub fn execute_timed(
input: ProgramInput,
) -> Result<std::time::Duration, Box<dyn std::error::Error>> {
write_elf_file()?;

let input_bytes = rkyv::to_bytes::<rkyv::rancor::Error>(&input)?;
std::fs::write(INPUT_PATH, input_bytes.as_slice())?;

let start = std::time::Instant::now();
let args = vec!["--elf", ELF_PATH, "--inputs", INPUT_PATH];
let output = Command::new("ziskemu")
.args(args)
.stdin(Stdio::inherit())
.stderr(Stdio::inherit())
.output()?;

if !output.status.success() {
return Err(format!(
"ZisK execution failed: {}",
String::from_utf8_lossy(&output.stderr)
)
.into());
}
let duration = start.elapsed();

Ok(duration)
}

pub fn prove(
input: ProgramInput,
format: ProofFormat,
Expand Down Expand Up @@ -84,6 +112,30 @@ pub fn prove(
Ok(output)
}

pub fn prove_timed(
input: ProgramInput,
format: ProofFormat,
) -> Result<(ProveOutput, std::time::Duration), Box<dyn std::error::Error>> {
let proof = prove(input, format)?;

#[derive(serde::Deserialize)]
struct ZisKResult {
#[serde(rename = "cycles")]
_cycles: u64,
#[serde(rename = "id")]
_id: String,
Comment on lines +123 to +126
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unknown fields are ignored by default. We can remove them if we are not going to use them. If we want them for completeness, it's ok then

time: f64,
}

let zisk_result_bytes = std::fs::read(format!("{OUTPUT_DIR_PATH}/result.json"))?;

let zisk_result: ZisKResult = serde_json::from_slice(&zisk_result_bytes)?;

let duration = std::time::Duration::from_secs_f64(zisk_result.time);

Ok((proof, duration))
}

pub fn verify(_output: &ProgramOutput) -> Result<(), Box<dyn std::error::Error>> {
unimplemented!("verify is not implemented for ZisK backend")
}
Expand Down
Loading
Loading