diff --git a/Cargo.lock b/Cargo.lock index 9311ae6f3d5..c436cf59147 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1460,7 +1460,7 @@ dependencies = [ [[package]] name = "redjubjub" version = "0.1.1" -source = "git+https://github.com/ZcashFoundation/redjubjub.git?branch=batch#469e853ac9cf184eeeb11b7aa564f45c49374b76" +source = "git+https://github.com/ZcashFoundation/redjubjub.git?branch=main#ba256655ddf84dac7ea6281a1b398495e46d232a" dependencies = [ "blake2b_simd", "byteorder", @@ -2409,7 +2409,7 @@ dependencies = [ "futures", "futures-util", "rand 0.7.3", - "redjubjub 0.1.1 (git+https://github.com/ZcashFoundation/redjubjub.git?branch=batch)", + "redjubjub 0.1.1 (git+https://github.com/ZcashFoundation/redjubjub.git?branch=main)", "spandoc", "tokio", "tower", diff --git a/zebra-consensus/Cargo.toml b/zebra-consensus/Cargo.toml index ac66ee6b63a..6bccc096d76 100644 --- a/zebra-consensus/Cargo.toml +++ b/zebra-consensus/Cargo.toml @@ -10,7 +10,7 @@ chrono = "0.4.13" futures = "0.3.5" futures-util = "0.3.5" rand = "0.7" -redjubjub = { git = "https://github.com/ZcashFoundation/redjubjub.git", branch = "main" } +redjubjub = { git = "https://github.com/ZcashFoundation/redjubjub.git", branch = "main"} tokio = { version = "0.2", features = ["time", "sync", "stream"] } tower = "0.3" tracing = "0.1.15" diff --git a/zebra-consensus/src/verify/redjubjub.rs b/zebra-consensus/src/verify/redjubjub.rs index 0ae87e38504..09eaa03dd06 100644 --- a/zebra-consensus/src/verify/redjubjub.rs +++ b/zebra-consensus/src/verify/redjubjub.rs @@ -12,8 +12,8 @@ use tower::Service; use tower_batch::BatchControl; /// RedJubjub signature verifier service -pub struct RedJubjubVerifier { - batch: batch::Verifier, +pub struct RedJubjubVerifier { + batch: batch::Verifier, // This uses a "broadcast" channel, which is an mpmc channel. Tokio also // provides a spmc channel, "watch", but it only keeps the latest value, so // using it would require thinking through whether it was possible for @@ -22,10 +22,10 @@ pub struct RedJubjubVerifier { } #[allow(clippy::new_without_default)] -impl RedJubjubVerifier { +impl RedJubjubVerifier { /// Create a new RedJubjubVerifier instance pub fn new() -> Self { - let batch = batch::Verifier::::default(); + let batch = batch::Verifier::default(); // XXX(hdevalence) what's a reasonable choice here? let (tx, _) = channel(10); Self { tx, batch } @@ -33,9 +33,9 @@ impl RedJubjubVerifier { } /// Type alias to clarify that this batch::Item is a RedJubjubItem -pub type RedJubjubItem = batch::Item; +pub type RedJubjubItem = batch::Item; -impl Service>> for RedJubjubVerifier { +impl<'msg> Service> for RedJubjubVerifier { type Response = (); type Error = Error; type Future = Pin> + Send + 'static>>; @@ -44,7 +44,7 @@ impl Service>> for RedJubjubVerifier>) -> Self::Future { + fn call(&mut self, req: BatchControl) -> Self::Future { match req { BatchControl::Item(item) => { tracing::trace!("got item"); @@ -73,7 +73,7 @@ impl Service>> for RedJubjubVerifier Drop for RedJubjubVerifier { +impl Drop for RedJubjubVerifier { fn drop(&mut self) { // We need to flush the current batch in case there are still any pending futures. let batch = mem::take(&mut self.batch); @@ -92,22 +92,33 @@ mod tests { use tower::ServiceExt; use tower_batch::Batch; - async fn sign_and_verify(mut verifier: V, n: usize) -> Result<(), V::Error> + async fn sign_and_verify(mut verifier: V, n: usize) -> Result<(), V::Error> where - T: SigType, - V: Service, Response = ()>, + V: Service, { let rng = thread_rng(); let mut results = FuturesUnordered::new(); for i in 0..n { let span = tracing::trace_span!("sig", i); - let sk = SigningKey::::new(rng); - let vk = VerificationKey::from(&sk); let msg = b"BatchVerifyTest"; - let sig = sk.sign(rng, &msg[..]); - verifier.ready_and().await?; - results.push(span.in_scope(|| verifier.call((vk.into(), sig, msg).into()))) + match i % 2 { + 0 => { + let sk = SigningKey::::new(rng); + let vk = VerificationKey::from(&sk); + let sig = sk.sign(rng, &msg[..]); + verifier.ready_and().await?; + results.push(span.in_scope(|| verifier.call((vk.into(), sig, msg).into()))) + } + 1 => { + let sk = SigningKey::::new(rng); + let vk = VerificationKey::from(&sk); + let sig = sk.sign(rng, &msg[..]); + verifier.ready_and().await?; + results.push(span.in_scope(|| verifier.call((vk.into(), sig, msg).into()))) + } + _ => panic!(), + } } while let Some(result) = results.next().await { @@ -124,11 +135,7 @@ mod tests { // Use a very long max_latency and a short timeout to check that // flushing is happening based on hitting max_items. - let verifier = Batch::new( - RedJubjubVerifier::::new(), - 10, - Duration::from_secs(1000), - ); + let verifier = Batch::new(RedJubjubVerifier::new(), 10, Duration::from_secs(1000)); timeout(Duration::from_secs(1), sign_and_verify(verifier, 100)).await? } @@ -139,11 +146,7 @@ mod tests { // Use a very high max_items and a short timeout to check that // flushing is happening based on hitting max_latency. - let verifier = Batch::new( - RedJubjubVerifier::::new(), - 100, - Duration::from_millis(500), - ); + let verifier = Batch::new(RedJubjubVerifier::new(), 100, Duration::from_millis(500)); timeout(Duration::from_secs(1), sign_and_verify(verifier, 10)).await? } }