From 8bc53ecbde0944f59f2321f06f2f4171975c7288 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Wed, 15 Feb 2023 21:20:26 -0700 Subject: [PATCH] Update to development versions of incrementalmerkletree/bridgetree This modifies the tests where required to use bridgetree checkpoint identifiers. --- .gitignore | 1 + Cargo.toml | 9 ++++++++- src/builder.rs | 11 +++++------ src/tree.rs | 42 +++++++++++++++++++----------------------- tests/builder.rs | 11 ++++++----- 5 files changed, 39 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 173b9514..7b56a141 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ **/*.rs.bk Cargo.lock .vscode +action-circuit-layout.png diff --git a/Cargo.toml b/Cargo.toml index 2e51fb32..67ffefde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ rustdoc-args = ["--cfg", "docsrs", "--html-in-header", "katex-header.html"] aes = "0.8" bitvec = "1" blake2b_simd = "1" +bridgetree = { version = "0.2", optional = true } ff = "0.13" fpe = "0.6" group = { version = "0.13", features = ["wnaf-memuse"] } @@ -52,11 +53,13 @@ image = { version = ">= 0.24, < 0.24.5", optional = true } # 0.24.5 has MSRV 1.6 plotters = { version = "0.3.0", optional = true } [dev-dependencies] +bridgetree = "0.2" criterion = "0.3" halo2_gadgets = { version = "0.3", features = ["test-dependencies"] } hex = "0.4" proptest = "1.0.0" zcash_note_encryption = { version = "0.3", features = ["pre-zip-212"] } +incrementalmerkletree = { version = "0.3", features = ["test-dependencies"] } [target.'cfg(unix)'.dev-dependencies] inferno = ">= 0.11, < 0.11.15" @@ -69,7 +72,7 @@ bench = false default = ["multicore"] multicore = ["halo2_proofs/multicore"] dev-graph = ["halo2_proofs/dev-graph", "image", "plotters"] -test-dependencies = ["proptest"] +test-dependencies = ["bridgetree", "proptest"] [[bench]] name = "note_decryption" @@ -88,3 +91,7 @@ debug = true [profile.bench] debug = true + +[patch.crates-io] +bridgetree = { git = "https://github.com/zcash/incrementalmerkletree.git", rev = "ea1686e8f8f6c1e41aa97251a7eb4fadfd33df47" } +incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree.git", rev = "ea1686e8f8f6c1e41aa97251a7eb4fadfd33df47" } diff --git a/src/builder.rs b/src/builder.rs index f227e7a6..27628695 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -759,8 +759,8 @@ impl OutputView for RecipientInfo { #[cfg(any(test, feature = "test-dependencies"))] #[cfg_attr(docsrs, doc(cfg(feature = "test-dependencies")))] pub mod testing { + use bridgetree::BridgeTree; use core::fmt::Debug; - use incrementalmerkletree::{bridgetree::BridgeTree, Tree}; use rand::{rngs::StdRng, CryptoRng, SeedableRng}; use proptest::collection::vec; @@ -853,16 +853,15 @@ pub mod testing { rng_seed in prop::array::uniform32(prop::num::u8::ANY) ) -> ArbitraryBundleInputs { const MERKLE_DEPTH_ORCHARD: u8 = crate::constants::MERKLE_DEPTH_ORCHARD as u8; - let mut tree = BridgeTree::::new(100); + let mut tree = BridgeTree::::new(100, 0); let mut notes_and_auth_paths: Vec<(Note, MerklePath)> = Vec::new(); for note in notes.iter() { let leaf = MerkleHashOrchard::from_cmx(¬e.commitment().into()); - tree.append(&leaf); - let position = tree.witness().expect("tree is not empty"); + tree.append(leaf); + let position = tree.mark().expect("tree is not empty"); - let root = tree.root(0).unwrap(); - let path = MerklePath::from((position, tree.authentication_path(position, &root).expect("we just witnessed the path"))); + let path = MerklePath::from((position, tree.witness(position, 0).expect("we just witnessed the path"))); notes_and_auth_paths.push((*note, path)); } diff --git a/src/tree.rs b/src/tree.rs index c2854200..59adefdb 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -11,7 +11,7 @@ use crate::{ }; use halo2_gadgets::sinsemilla::primitives::HashDomain; -use incrementalmerkletree::{Altitude, Hashable}; +use incrementalmerkletree::{Hashable, Level}; use pasta_curves::pallas; use ff::{Field, PrimeField, PrimeFieldBits}; @@ -205,7 +205,7 @@ impl Hashable for MerkleHashOrchard { /// - when hashing two leaves, we produce a node on the layer above the leaves, i.e. /// layer = 31, l = 0 /// - when hashing to the final root, we produce the anchor with layer = 0, l = 31. - fn combine(altitude: Altitude, left: &Self, right: &Self) -> Self { + fn combine(level: Level, left: &Self, right: &Self) -> Self { // MerkleCRH Sinsemilla hash domain. let domain = HashDomain::new(MERKLE_CRH_PERSONALIZATION); @@ -213,7 +213,7 @@ impl Hashable for MerkleHashOrchard { domain .hash( iter::empty() - .chain(i2lebsp_k(altitude.into()).iter().copied()) + .chain(i2lebsp_k(level.into()).iter().copied()) .chain(left.0.to_le_bits().iter().by_vals().take(L_ORCHARD_MERKLE)) .chain(right.0.to_le_bits().iter().by_vals().take(L_ORCHARD_MERKLE)), ) @@ -221,8 +221,8 @@ impl Hashable for MerkleHashOrchard { ) } - fn empty_root(altitude: Altitude) -> Self { - EMPTY_ROOTS[::from(altitude)] + fn empty_root(level: Level) -> Self { + EMPTY_ROOTS[::from(level)] } } @@ -248,18 +248,14 @@ impl<'de> Deserialize<'de> for MerkleHashOrchard { #[cfg_attr(docsrs, doc(cfg(feature = "test-dependencies")))] pub mod testing { #[cfg(test)] - use incrementalmerkletree::{ + use { + crate::tree::{MerkleHashOrchard, EMPTY_ROOTS}, bridgetree::{BridgeTree, Frontier as BridgeFrontier}, - Altitude, Frontier, Tree, + group::ff::PrimeField, + incrementalmerkletree::Level, + pasta_curves::pallas, }; - #[cfg(test)] - use crate::tree::{MerkleHashOrchard, EMPTY_ROOTS}; - #[cfg(test)] - use group::ff::PrimeField; - #[cfg(test)] - use pasta_curves::pallas; - #[test] fn test_vectors() { let tv_empty_roots = crate::test_vectors::commitment_tree::test_vectors().empty_roots; @@ -268,14 +264,14 @@ pub mod testing { assert_eq!(tv_empty_roots[height], root.to_bytes()); } - let mut tree = BridgeTree::::new(100); + let mut tree = BridgeTree::::new(100, 0); for (i, tv) in crate::test_vectors::merkle_path::test_vectors() .into_iter() .enumerate() { let cmx = MerkleHashOrchard::from_bytes(&tv.leaves[i]).unwrap(); - tree.append(&cmx); - let position = tree.witness().expect("tree is not empty"); + tree.append(cmx); + let position = tree.mark().expect("tree is not empty"); assert_eq!(position, i.into()); let root = tree.root(0).unwrap(); @@ -286,7 +282,7 @@ pub mod testing { // but BridgeTree doesn't encode these. for j in 0..=i { assert_eq!( - tree.authentication_path(j.try_into().unwrap(), &root), + tree.witness(j.try_into().unwrap(), 0).ok(), Some( tv.paths[j] .iter() @@ -304,14 +300,14 @@ pub mod testing { let tv_empty_roots = crate::test_vectors::commitment_tree::test_vectors().empty_roots; - for (altitude, tv_root) in tv_empty_roots.iter().enumerate() { + for (level, tv_root) in tv_empty_roots.iter().enumerate() { assert_eq!( - MerkleHashOrchard::empty_root(Altitude::from(altitude as u8)) + MerkleHashOrchard::empty_root(Level::from(level as u8)) .0 .to_repr(), *tv_root, - "Empty root mismatch at altitude {}", - altitude + "Empty root mismatch at level {}", + level ); } } @@ -360,7 +356,7 @@ pub mod testing { let mut frontier = BridgeFrontier::::empty(); for commitment in commitments.iter() { let cmx = MerkleHashOrchard(pallas::Base::from_repr(*commitment).unwrap()); - frontier.append(&cmx); + frontier.append(cmx); } assert_eq!(frontier.root().0, pallas::Base::from_repr(anchor).unwrap()); } diff --git a/tests/builder.rs b/tests/builder.rs index 7590e108..eb181783 100644 --- a/tests/builder.rs +++ b/tests/builder.rs @@ -1,4 +1,5 @@ -use incrementalmerkletree::{bridgetree::BridgeTree, Hashable, Tree}; +use bridgetree::BridgeTree; +use incrementalmerkletree::Hashable; use orchard::{ builder::Builder, bundle::{Authorized, Flags}, @@ -70,11 +71,11 @@ fn bundle_chain() { // Use the tree with a single leaf. let cmx: ExtractedNoteCommitment = note.commitment().into(); let leaf = MerkleHashOrchard::from_cmx(&cmx); - let mut tree = BridgeTree::::new(0); - tree.append(&leaf); - let position = tree.witness().unwrap(); + let mut tree = BridgeTree::::new(100, 0); + tree.append(leaf); + let position = tree.mark().unwrap(); let root = tree.root(0).unwrap(); - let auth_path = tree.authentication_path(position, &root).unwrap(); + let auth_path = tree.witness(position, 0).unwrap(); let merkle_path = MerklePath::from_parts( u64::from(position).try_into().unwrap(), auth_path[..].try_into().unwrap(),