mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-06-29 18:39:30 +00:00
Add cycle benchmarks of PPE with private receiver
This commit is contained in:
parent
3e1343c6af
commit
7b099395d6
@ -15,7 +15,7 @@ use lee::program_methods::PRIVACY_PRESERVING_CIRCUIT_ID;
|
||||
use risc0_zkvm::{InnerReceipt, Receipt};
|
||||
|
||||
fn bench_verify(c: &mut Criterion) {
|
||||
let (output, proof) = prove_auth_transfer_in_ppe().expect("prove auth_transfer in PPE");
|
||||
let (output, proof, _) = prove_auth_transfer_in_ppe(false).expect("prove auth_transfer in PPE");
|
||||
let journal = output.to_bytes();
|
||||
let proof_bytes = proof.into_inner();
|
||||
let inner: InnerReceipt = borsh::from_slice(&proof_bytes)
|
||||
|
||||
@ -58,6 +58,11 @@ struct Cli {
|
||||
#[arg(long)]
|
||||
ppe: bool,
|
||||
|
||||
/// With --ppe, run the `auth_transfer` case with a private receiver. Requires
|
||||
/// --features ppe at build time. Extremely slow.
|
||||
#[arg(long)]
|
||||
ppe_private: bool,
|
||||
|
||||
/// Iterations for executor wall-time sampling per case. First iter is
|
||||
/// discarded as warmup, remaining N feed the stats.
|
||||
#[arg(long, default_value_t = 5)]
|
||||
@ -609,7 +614,11 @@ fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "ppe")]
|
||||
let ppe_results = if cli.ppe { ppe::run_all() } else { Vec::new() };
|
||||
let ppe_results = if cli.ppe {
|
||||
ppe::run_all(cli.ppe_private)
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
#[cfg(not(feature = "ppe"))]
|
||||
let ppe_results: Vec<ppe::PpeBenchResult> = {
|
||||
if cli.ppe {
|
||||
|
||||
@ -27,6 +27,8 @@ pub struct PpeBenchResult {
|
||||
pub label: String,
|
||||
pub chain_depth: usize,
|
||||
pub prove_wall_ms: Option<f64>,
|
||||
/// Executor `user_cycles` of the privacy circuit.
|
||||
pub user_cycles: Option<u64>,
|
||||
/// borsh-serialized `InnerReceipt` length (`S_agg` in the fee model).
|
||||
pub proof_bytes: Option<usize>,
|
||||
pub error: Option<String>,
|
||||
@ -34,17 +36,18 @@ pub struct PpeBenchResult {
|
||||
|
||||
#[cfg(not(feature = "ppe"))]
|
||||
#[must_use]
|
||||
pub const fn run_all() -> Vec<PpeBenchResult> {
|
||||
pub const fn run_all(_private: bool) -> Vec<PpeBenchResult> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
/// Runs the PPE cases.
|
||||
#[cfg(feature = "ppe")]
|
||||
#[must_use]
|
||||
pub fn run_all() -> Vec<PpeBenchResult> {
|
||||
pub fn run_all(private: bool) -> Vec<PpeBenchResult> {
|
||||
let mut results = Vec::new();
|
||||
|
||||
eprintln!("PPE: running composition cost (auth_transfer Transfer in PPE)");
|
||||
results.push(ppe_impl::run_auth_transfer_in_ppe());
|
||||
results.push(ppe_impl::run_auth_transfer_in_ppe(private));
|
||||
|
||||
for depth in [1_u32, 3, 5, 9] {
|
||||
eprintln!("PPE: running chain_caller depth={depth}");
|
||||
@ -63,29 +66,34 @@ pub fn print_table(results: &[PpeBenchResult]) {
|
||||
.max("label".len());
|
||||
|
||||
println!(
|
||||
"\n{:<lw$} {:>5} {:>20} {:>12} {}",
|
||||
"\n{:<lw$} {:>5} {:>20} {:>12} {:>12} {}",
|
||||
"label",
|
||||
"depth",
|
||||
"prove_ms (s)",
|
||||
"user_cycles",
|
||||
"proof_bytes",
|
||||
"error",
|
||||
lw = lw,
|
||||
);
|
||||
println!("{}", "-".repeat(lw + 60));
|
||||
println!("{}", "-".repeat(lw + 72));
|
||||
for r in results {
|
||||
let p = r.prove_wall_ms.map_or_else(
|
||||
|| "-".to_owned(),
|
||||
|v| format!("{v:.1} ({:.1}s)", v / 1_000.0),
|
||||
);
|
||||
let c = r
|
||||
.user_cycles
|
||||
.map_or_else(|| "-".to_owned(), |n| n.to_string());
|
||||
let b = r
|
||||
.proof_bytes
|
||||
.map_or_else(|| "-".to_owned(), |n| n.to_string());
|
||||
let e = r.error.as_deref().unwrap_or("");
|
||||
println!(
|
||||
"{:<lw$} {:>5} {:>20} {:>12} {}",
|
||||
"{:<lw$} {:>5} {:>20} {:>12} {:>12} {}",
|
||||
r.label,
|
||||
r.chain_depth,
|
||||
p,
|
||||
c,
|
||||
b,
|
||||
e,
|
||||
lw = lw,
|
||||
|
||||
@ -6,12 +6,14 @@
|
||||
use std::{collections::HashMap, time::Instant};
|
||||
|
||||
use lee::{
|
||||
execute_and_prove,
|
||||
privacy_preserving_transaction::circuit::{ProgramWithDependencies, Proof},
|
||||
privacy_preserving_transaction::circuit::{
|
||||
ProgramWithDependencies, Proof, execute_and_prove_with_cycles,
|
||||
},
|
||||
program::Program,
|
||||
};
|
||||
use lee_core::{
|
||||
InputAccountIdentity, PrivacyPreservingCircuitOutput,
|
||||
EphemeralPublicKey, InputAccountIdentity, NullifierPublicKey, PrivacyPreservingCircuitOutput,
|
||||
SharedSecretKey,
|
||||
account::{Account, AccountId, AccountWithMetadata},
|
||||
program::ProgramId,
|
||||
};
|
||||
@ -27,17 +29,22 @@ const AUTH_TRANSFER_ELF: &[u8] = lee::program_methods::AUTHENTICATED_TRANSFER_EL
|
||||
const CHAIN_CALLER_ELF: &[u8] =
|
||||
include_bytes!("../../../../artifacts/test_program_methods/chain_caller.bin");
|
||||
|
||||
pub fn run_auth_transfer_in_ppe() -> PpeBenchResult {
|
||||
let label = "auth_transfer Transfer in PPE".to_owned();
|
||||
pub fn run_auth_transfer_in_ppe(private: bool) -> PpeBenchResult {
|
||||
let label = if private {
|
||||
"auth_transfer Transfer in PPE (private output)".to_owned()
|
||||
} else {
|
||||
"auth_transfer Transfer in PPE (all public)".to_owned()
|
||||
};
|
||||
let started = Instant::now();
|
||||
match prove_auth_transfer_in_ppe() {
|
||||
Ok((_out, proof)) => {
|
||||
match prove_auth_transfer_in_ppe(private) {
|
||||
Ok((_out, proof, user_cycles)) => {
|
||||
let prove_ms = started.elapsed().as_secs_f64() * 1_000.0;
|
||||
PpeBenchResult {
|
||||
label,
|
||||
chain_depth: 0,
|
||||
prove_wall_ms: Some(prove_ms),
|
||||
proof_bytes: Some(proof.into_inner().len()),
|
||||
user_cycles: Some(user_cycles),
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
@ -46,18 +53,20 @@ pub fn run_auth_transfer_in_ppe() -> PpeBenchResult {
|
||||
chain_depth: 0,
|
||||
prove_wall_ms: None,
|
||||
proof_bytes: None,
|
||||
user_cycles: None,
|
||||
error: Some(err.to_string()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prove_auth_transfer_in_ppe() -> anyhow::Result<(PrivacyPreservingCircuitOutput, Proof)> {
|
||||
let program = Program::new(AUTH_TRANSFER_ELF.to_vec())?;
|
||||
let pwd = ProgramWithDependencies::from(program);
|
||||
/// Proves an `auth_transfer` Transfer wrapped in the privacy circuit.
|
||||
/// `private` flag signals whether the receiver is a private account.
|
||||
pub fn prove_auth_transfer_in_ppe(
|
||||
private: bool,
|
||||
) -> anyhow::Result<(PrivacyPreservingCircuitOutput, Proof, u64)> {
|
||||
let pwd = ProgramWithDependencies::from(Program::new(AUTH_TRANSFER_ELF.to_vec())?);
|
||||
|
||||
// For PPE to allow the sender's balance to be decremented by this
|
||||
// program, the sender must already be claimed by auth_transfer.
|
||||
// Recipient stays default-owned so the first call can claim it.
|
||||
// Sender must already be claimed by auth_transfer for its balance to be debited.
|
||||
let sender = AccountWithMetadata {
|
||||
account: Account {
|
||||
program_owner: AUTH_TRANSFER_ID,
|
||||
@ -67,22 +76,38 @@ pub fn prove_auth_transfer_in_ppe() -> anyhow::Result<(PrivacyPreservingCircuitO
|
||||
is_authorized: true,
|
||||
account_id: AccountId::new([1; 32]),
|
||||
};
|
||||
let recipient = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: true,
|
||||
account_id: AccountId::new([2; 32]),
|
||||
let instruction_data =
|
||||
to_vec(&authenticated_transfer_core::Instruction::Transfer { amount: 5_000 })?;
|
||||
|
||||
let (recipient, recipient_identity) = if private {
|
||||
let npk = NullifierPublicKey::from(&[2; 32]);
|
||||
let recipient = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: false,
|
||||
account_id: AccountId::for_regular_private_account(&npk, 0),
|
||||
};
|
||||
let identity = InputAccountIdentity::PrivateUnauthorized {
|
||||
epk: EphemeralPublicKey(Vec::new()),
|
||||
view_tag: 0,
|
||||
npk,
|
||||
ssk: SharedSecretKey([3; 32]),
|
||||
identifier: 0,
|
||||
};
|
||||
(recipient, identity)
|
||||
} else {
|
||||
// Recipient stays default-owned so the first call can claim it.
|
||||
let recipient = AccountWithMetadata {
|
||||
account: Account::default(),
|
||||
is_authorized: true,
|
||||
account_id: AccountId::new([4; 32]),
|
||||
};
|
||||
(recipient, InputAccountIdentity::Public)
|
||||
};
|
||||
let pre_states = vec![sender, recipient];
|
||||
|
||||
let instruction = authenticated_transfer_core::Instruction::Transfer { amount: 5_000 };
|
||||
let instruction_data = to_vec(&instruction)?;
|
||||
|
||||
let account_identities = vec![InputAccountIdentity::Public; pre_states.len()];
|
||||
|
||||
Ok(execute_and_prove(
|
||||
pre_states,
|
||||
Ok(execute_and_prove_with_cycles(
|
||||
vec![sender, recipient],
|
||||
instruction_data,
|
||||
account_identities,
|
||||
vec![InputAccountIdentity::Public, recipient_identity],
|
||||
&pwd,
|
||||
)?)
|
||||
}
|
||||
@ -91,13 +116,14 @@ pub fn run_chain_caller(depth: u32) -> PpeBenchResult {
|
||||
let label = format!("chain_caller depth={depth}");
|
||||
let started = Instant::now();
|
||||
match prove_chain_caller(depth) {
|
||||
Ok((_out, proof)) => {
|
||||
Ok((_out, proof, user_cycles)) => {
|
||||
let prove_ms = started.elapsed().as_secs_f64() * 1_000.0;
|
||||
PpeBenchResult {
|
||||
label,
|
||||
chain_depth: depth as usize,
|
||||
prove_wall_ms: Some(prove_ms),
|
||||
proof_bytes: Some(proof.into_inner().len()),
|
||||
user_cycles: Some(user_cycles),
|
||||
error: None,
|
||||
}
|
||||
}
|
||||
@ -106,6 +132,7 @@ pub fn run_chain_caller(depth: u32) -> PpeBenchResult {
|
||||
chain_depth: depth as usize,
|
||||
prove_wall_ms: None,
|
||||
proof_bytes: None,
|
||||
user_cycles: None,
|
||||
error: Some(err.to_string()),
|
||||
},
|
||||
}
|
||||
@ -113,7 +140,7 @@ pub fn run_chain_caller(depth: u32) -> PpeBenchResult {
|
||||
|
||||
fn prove_chain_caller(
|
||||
num_chain_calls: u32,
|
||||
) -> anyhow::Result<(PrivacyPreservingCircuitOutput, Proof)> {
|
||||
) -> anyhow::Result<(PrivacyPreservingCircuitOutput, Proof, u64)> {
|
||||
let chain_caller = Program::new(CHAIN_CALLER_ELF.to_vec())?;
|
||||
let auth_transfer = Program::new(AUTH_TRANSFER_ELF.to_vec())?;
|
||||
let mut deps = HashMap::new();
|
||||
@ -150,7 +177,7 @@ fn prove_chain_caller(
|
||||
|
||||
let account_identities = vec![InputAccountIdentity::Public; pre_states.len()];
|
||||
|
||||
Ok(execute_and_prove(
|
||||
Ok(execute_and_prove_with_cycles(
|
||||
pre_states,
|
||||
instruction_data,
|
||||
account_identities,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user