2026-05-18 15:49:24 +02:00
|
|
|
//! Privacy-preserving execution (PPE) cases for `cycle_bench`.
|
2026-05-14 18:14:37 +02:00
|
|
|
//!
|
|
|
|
|
//! Composition cost is the delta between standalone `prover.prove(env, elf)` for
|
|
|
|
|
//! a single program (measured in the main bench) and a full `execute_and_prove`
|
|
|
|
|
//! that wraps the same program in the privacy circuit. Chained-call depth sweep
|
|
|
|
|
//! uses the `chain_caller` test program (loaded from artifacts/) with N=1, 3, 5, 9.
|
|
|
|
|
//!
|
2026-05-18 15:49:24 +02:00
|
|
|
//! `run_verify` produces `G_verify` for the fee model: it generates one PPE
|
|
|
|
|
//! receipt (`auth_transfer` Transfer in PPE) and times `Receipt::verify` over
|
2026-05-14 18:14:37 +02:00
|
|
|
//! `iters` iterations. The proof bytes captured here are also the on-wire
|
2026-05-18 15:49:24 +02:00
|
|
|
//! "outer proof" payload (`S_agg` in the fee model).
|
2026-05-14 18:14:37 +02:00
|
|
|
|
|
|
|
|
#![allow(
|
|
|
|
|
dead_code,
|
|
|
|
|
reason = "Stubs are used when the `ppe` feature is disabled."
|
|
|
|
|
)]
|
|
|
|
|
|
|
|
|
|
use anyhow::Result;
|
|
|
|
|
use serde::Serialize;
|
|
|
|
|
|
|
|
|
|
use crate::stats::Stats;
|
|
|
|
|
|
2026-05-18 15:49:24 +02:00
|
|
|
#[cfg(feature = "ppe")]
|
|
|
|
|
mod ppe_impl;
|
|
|
|
|
|
2026-05-14 18:14:37 +02:00
|
|
|
#[derive(Debug, Serialize, Clone)]
|
|
|
|
|
pub struct PpeBenchResult {
|
|
|
|
|
pub label: String,
|
|
|
|
|
pub chain_depth: usize,
|
|
|
|
|
pub prove_wall_ms: Option<f64>,
|
2026-05-18 15:49:24 +02:00
|
|
|
/// borsh-serialized `InnerReceipt` length (`S_agg` in the fee model).
|
2026-05-14 18:14:37 +02:00
|
|
|
pub proof_bytes: Option<usize>,
|
|
|
|
|
pub error: Option<String>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Serialize, Clone)]
|
|
|
|
|
pub struct VerifyBenchResult {
|
|
|
|
|
pub label: String,
|
|
|
|
|
pub stats: Stats,
|
|
|
|
|
pub proof_bytes: usize,
|
|
|
|
|
pub journal_bytes: usize,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(not(feature = "ppe"))]
|
2026-05-18 15:49:24 +02:00
|
|
|
pub fn run_all() -> Vec<PpeBenchResult> {
|
|
|
|
|
Vec::new()
|
2026-05-14 18:14:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "ppe")]
|
2026-05-18 15:49:24 +02:00
|
|
|
pub fn run_all() -> Vec<PpeBenchResult> {
|
2026-05-14 18:14:37 +02:00
|
|
|
let mut results = Vec::new();
|
|
|
|
|
|
|
|
|
|
eprintln!("PPE: running composition cost (auth_transfer Transfer in PPE)");
|
|
|
|
|
results.push(ppe_impl::run_auth_transfer_in_ppe());
|
|
|
|
|
|
|
|
|
|
for depth in [1_u32, 3, 5, 9] {
|
|
|
|
|
eprintln!("PPE: running chain_caller depth={depth}");
|
|
|
|
|
results.push(ppe_impl::run_chain_caller(depth));
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-18 15:49:24 +02:00
|
|
|
results
|
2026-05-14 18:14:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(not(feature = "ppe"))]
|
|
|
|
|
pub fn run_verify(_iters: usize) -> Result<VerifyBenchResult> {
|
|
|
|
|
anyhow::bail!("--verify requires --features ppe at build time")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "ppe")]
|
|
|
|
|
pub fn run_verify(iters: usize) -> Result<VerifyBenchResult> {
|
|
|
|
|
ppe_impl::run_verify(iters)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn print_table(results: &[PpeBenchResult]) {
|
|
|
|
|
let lw = results
|
|
|
|
|
.iter()
|
|
|
|
|
.map(|r| r.label.len())
|
|
|
|
|
.max()
|
|
|
|
|
.unwrap_or(0)
|
|
|
|
|
.max("label".len());
|
|
|
|
|
|
|
|
|
|
println!(
|
|
|
|
|
"\n{:<lw$} {:>5} {:>20} {:>12} {}",
|
2026-05-14 18:43:26 +02:00
|
|
|
"label",
|
|
|
|
|
"depth",
|
|
|
|
|
"prove_ms (s)",
|
|
|
|
|
"proof_bytes",
|
|
|
|
|
"error",
|
2026-05-14 18:14:37 +02:00
|
|
|
lw = lw,
|
|
|
|
|
);
|
|
|
|
|
println!("{}", "-".repeat(lw + 60));
|
|
|
|
|
for r in results {
|
2026-05-18 15:49:24 +02:00
|
|
|
let p = r.prove_wall_ms.map_or_else(
|
|
|
|
|
|| "-".to_owned(),
|
|
|
|
|
|v| format!("{v:.1} ({:.1}s)", v / 1_000.0),
|
|
|
|
|
);
|
2026-05-14 18:14:37 +02:00
|
|
|
let b = r
|
|
|
|
|
.proof_bytes
|
2026-05-18 15:49:24 +02:00
|
|
|
.map_or_else(|| "-".to_owned(), |n| n.to_string());
|
2026-05-14 18:14:37 +02:00
|
|
|
let e = r.error.as_deref().unwrap_or("");
|
|
|
|
|
println!(
|
|
|
|
|
"{:<lw$} {:>5} {:>20} {:>12} {}",
|
2026-05-14 18:43:26 +02:00
|
|
|
r.label,
|
|
|
|
|
r.chain_depth,
|
|
|
|
|
p,
|
|
|
|
|
b,
|
|
|
|
|
e,
|
2026-05-14 18:14:37 +02:00
|
|
|
lw = lw,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn print_verify(r: &VerifyBenchResult) {
|
|
|
|
|
println!("\nVerify (G_verify):");
|
|
|
|
|
println!(" case : {}", r.label);
|
2026-05-14 18:43:26 +02:00
|
|
|
println!(
|
|
|
|
|
" proof_bytes : {} (borsh InnerReceipt, S_agg)",
|
|
|
|
|
r.proof_bytes
|
|
|
|
|
);
|
2026-05-14 18:14:37 +02:00
|
|
|
println!(" journal_bytes : {}", r.journal_bytes);
|
2026-05-18 16:37:11 +02:00
|
|
|
println!(" verify_ms : {}", r.stats);
|
2026-05-14 18:14:37 +02:00
|
|
|
}
|