diff --git a/Cargo.toml b/Cargo.toml index 30d058a2..efd57ebb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,9 @@ criterion = "0.3" hex = "0.4" proptest = "1.0.0" +[target.'cfg(unix)'.dev-dependencies] +pprof = { version = "0.4.2", features = ["criterion", "flamegraph"] } + [lib] bench = false @@ -61,6 +64,16 @@ test-dependencies = ["proptest"] name = "small" harness = false +[[bench]] +name = "circuit" +harness = false + +[profile.release] +debug = true + +[profile.bench] +debug = true + [patch.crates-io] halo2 = { git = "https://github.com/zcash/halo2.git", rev = "27c4187673a9c6ade13fbdbd4f20955530c22d7f" } zcash_note_encryption = { git = "https://github.com/zcash/librustzcash.git", rev = "cc533a9da4f6a7209a7be05f82b12a03969152c9" } diff --git a/benches/circuit.rs b/benches/circuit.rs new file mode 100644 index 00000000..8dbbe664 --- /dev/null +++ b/benches/circuit.rs @@ -0,0 +1,86 @@ +#[macro_use] +extern crate criterion; + +use criterion::{BenchmarkId, Criterion}; + +#[cfg(unix)] +use pprof::criterion::{Output, PProfProfiler}; + +use orchard::{ + builder::Builder, + bundle::Flags, + circuit::{ProvingKey, VerifyingKey}, + keys::{FullViewingKey, SpendingKey}, + value::NoteValue, + Anchor, Bundle, +}; +use rand::rngs::OsRng; + +fn criterion_benchmark(c: &mut Criterion) { + let rng = OsRng; + + let sk = SpendingKey::from_bytes([7; 32]).unwrap(); + let recipient = FullViewingKey::from(&sk).default_address(); + + let vk = VerifyingKey::build(); + let pk = ProvingKey::build(); + + for num_recipients in 1..4 { + let mut builder = Builder::new( + Flags::from_parts(true, true), + Anchor::from_bytes([0; 32]).unwrap(), + ); + for _ in 0..num_recipients { + builder + .add_recipient(None, recipient, NoteValue::from_raw(10), None) + .unwrap(); + } + let bundle: Bundle<_, i64> = builder.build(rng).unwrap(); + + let instances: Vec<_> = bundle + .actions() + .iter() + .map(|a| a.to_instance(*bundle.flags(), *bundle.anchor())) + .collect(); + + { + let mut group = c.benchmark_group("proving"); + group.sample_size(10); + group.bench_function(BenchmarkId::new("bundle", num_recipients), |b| { + b.iter(|| { + bundle + .authorization() + .create_proof(&pk, &instances) + .unwrap() + }); + }); + } + + { + let mut group = c.benchmark_group("verifying"); + let bundle = bundle + .create_proof(&pk) + .unwrap() + .apply_signatures(rng, [0; 32], &[]) + .unwrap(); + assert_eq!(bundle.verify_proof(&vk), Ok(())); + group.bench_function(BenchmarkId::new("bundle", num_recipients), |b| { + b.iter(|| bundle.authorization().proof().verify(&vk, &instances)); + }); + } + } +} + +#[cfg(unix)] +criterion_group! { + name = benches; + config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None))); + targets = criterion_benchmark +} +#[cfg(windows)] +criterion_group! { + name = benches; + config = Criterion::default(); + targets = criterion_benchmark +} +criterion_main!(benches); diff --git a/src/bundle.rs b/src/bundle.rs index 6c10fdf3..023dcb13 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -110,7 +110,9 @@ impl Action { }) } - pub(crate) fn to_instance(&self, flags: Flags, anchor: Anchor) -> Instance { + /// Prepares the public instance for this action, for creating and verifying the + /// bundle proof. + pub fn to_instance(&self, flags: Flags, anchor: Anchor) -> Instance { Instance { anchor, cv_net: self.cv_net.clone(),