diff --git a/Cargo.toml b/Cargo.toml index bb8dc354..eff05d37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ fpe = "0.4" group = "0.10" halo2 = "0.0" lazy_static = "1" +memuse = { version = "0.1", features = ["nonempty"] } pasta_curves = "0.1.2" proptest = { version = "1.0.0", optional = true } rand = "0.8" diff --git a/src/bundle.rs b/src/bundle.rs index 302c0fc6..d022bbfd 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -3,9 +3,9 @@ pub mod commitments; use std::io; -use std::mem; use blake2b_simd::Hash as Blake2bHash; +use memuse::{DynamicUsage, NoDynamicUsage}; use nonempty::NonEmpty; use zcash_note_encryption::try_note_decryption; @@ -134,6 +134,8 @@ impl Action { } } +impl NoDynamicUsage for Action> {} + /// Orchard-specific flags. #[derive(Clone, Copy, Debug)] pub struct Flags { @@ -441,13 +443,6 @@ impl Authorized { } impl Bundle { - /// Returns the amount of heap-allocated memory used by this bundle. - pub fn dynamic_usage(&self) -> usize { - // NonEmpty stores its head element separately from its tail Vec. - (self.actions.capacity() - 1) * mem::size_of::>>() - + self.authorization.proof.dynamic_usage() - } - /// Computes a commitment to the authorizing data within for this bundle. /// /// This together with `Bundle::commitment` bind the entire bundle. @@ -463,6 +458,31 @@ impl Bundle { } } +impl DynamicUsage for Bundle { + fn dynamic_usage(&self) -> usize { + self.actions.dynamic_usage() + + self.value_balance.dynamic_usage() + + self.authorization.proof.dynamic_usage() + } + + fn dynamic_usage_bounds(&self) -> (usize, Option) { + let bounds = ( + self.actions.dynamic_usage_bounds(), + self.value_balance.dynamic_usage_bounds(), + self.authorization.proof.dynamic_usage_bounds(), + ); + ( + bounds.0 .0 + bounds.1 .0 + bounds.2 .0, + bounds + .0 + .1 + .zip(bounds.1 .1) + .zip(bounds.2 .1) + .map(|((a, b), c)| a + b + c), + ) + } +} + /// A commitment to a bundle of actions. /// /// This commitment is non-malleable, in the sense that a bundle's commitment will only diff --git a/src/circuit.rs b/src/circuit.rs index 4bc5da2c..8afa0187 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -1,7 +1,5 @@ //! The Orchard Action circuit implementation. -use std::mem; - use group::{Curve, GroupEncoding}; use halo2::{ circuit::{floor_planner, Layouter}, @@ -9,6 +7,7 @@ use halo2::{ poly::Rotation, transcript::{Blake2bRead, Blake2bWrite}, }; +use memuse::DynamicUsage; use pasta_curves::{ arithmetic::{CurveAffine, FieldExt}, pallas, vesta, @@ -849,12 +848,17 @@ impl AsRef<[u8]> for Proof { } } -impl Proof { - /// Returns the amount of heap-allocated memory used by this proof. - pub(crate) fn dynamic_usage(&self) -> usize { - self.0.capacity() * mem::size_of::() +impl DynamicUsage for Proof { + fn dynamic_usage(&self) -> usize { + self.0.dynamic_usage() } + fn dynamic_usage_bounds(&self) -> (usize, Option) { + self.0.dynamic_usage_bounds() + } +} + +impl Proof { /// Creates a proof for the given circuits and instances. pub fn create( pk: &ProvingKey,