Skip to content

Commit

Permalink
Upgrade incrementalmerkletree to version 0.8.0
Browse files Browse the repository at this point in the history
This also requires us to replace the use of `bridgetree` in tests with
`shardtree`.
  • Loading branch information
nuttycom committed Dec 13, 2024
1 parent 5c451be commit 0a1c17d
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 58 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ and this project adheres to Rust's notion of
- `ValueCommitTrapdoor::to_bytes`
- `impl Clone for orchard::tree::MerklePath`

### Changed
- Migrated to `incrementalmerkletree 0.8`.

## [0.10.0] - 2024-10-02

### Changed
Expand Down
27 changes: 14 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ nonempty = "0.7"
serde = { version = "1.0", features = ["derive"] }
subtle = "2.3"
zcash_note_encryption = "0.4"
incrementalmerkletree = "0.7"
incrementalmerkletree = "0.8"
zcash_spec = "0.1"
zip32 = "0.1"
visibility = "0.1.1"
Expand All @@ -58,13 +58,13 @@ image = { version = "0.24", optional = true }
plotters = { version = "0.3.0", optional = true }

[dev-dependencies]
bridgetree = "0.6"
criterion = "0.4" # 0.5 depends on clap 4 which has MSRV 1.70
halo2_gadgets = { version = "0.3", features = ["test-dependencies"] }
hex = "0.4"
proptest = "1.0.0"
zcash_note_encryption = { version = "0.4", features = ["pre-zip-212"] }
incrementalmerkletree = { version = "0.7", features = ["test-dependencies"] }
incrementalmerkletree = { version = "0.8", features = ["test-dependencies"] }
shardtree = "0.5"

[target.'cfg(unix)'.dev-dependencies]
inferno = { version = "0.11", default-features = false, features = ["multithreaded", "nameattr"] }
Expand Down Expand Up @@ -97,3 +97,7 @@ debug = true

[profile.bench]
debug = true

[patch.crates-io]
incrementalmerkletree = { git = "https://github.com/zcash/incrementalmerkletree.git", rev = "353cf3e9ff9621f64e2b6fabb709f4afeca487c4" }
shardtree = { git = "https://github.com/zcash/incrementalmerkletree.git", rev = "353cf3e9ff9621f64e2b6fabb709f4afeca487c4" }
39 changes: 24 additions & 15 deletions src/pczt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,11 @@ pub struct Zip32Derivation {

#[cfg(test)]
mod tests {
use bridgetree::BridgeTree;
use ff::{Field, PrimeField};
use incrementalmerkletree::{Marking, Retention};
use pasta_curves::pallas;
use rand::rngs::OsRng;
use shardtree::{store::memory::MemoryShardStore, ShardTree};

use crate::{
builder::{Builder, BundleType},
Expand All @@ -300,7 +301,7 @@ mod tests {
keys::{FullViewingKey, Scope, SpendAuthorizingKey, SpendingKey},
note::{ExtractedNoteCommitment, RandomSeed, Rho},
pczt::Zip32Derivation,
tree::{MerkleHashOrchard, MerklePath, EMPTY_ROOTS},
tree::{MerkleHashOrchard, EMPTY_ROOTS},
value::NoteValue,
Note,
};
Expand Down Expand Up @@ -371,23 +372,31 @@ mod tests {
let (anchor, merkle_path) = {
let cmx: ExtractedNoteCommitment = note.commitment().into();
let leaf = MerkleHashOrchard::from_cmx(&cmx);
let mut tree = BridgeTree::<MerkleHashOrchard, u32, 32>::new(100);
tree.append(leaf);
let position = tree.mark().unwrap();
let root = tree.root(0).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(),
);
let anchor = root.into();
assert_eq!(anchor, merkle_path.root(cmx));
(anchor, merkle_path)
let mut tree: ShardTree<MemoryShardStore<MerkleHashOrchard, u32>, 32, 16> =
ShardTree::new(MemoryShardStore::empty(), 100);
tree.append(
leaf,
Retention::Checkpoint {
id: 0,
marking: Marking::Marked,
},
)
.unwrap();
let root = tree.root_at_checkpoint_id(&0).unwrap().unwrap();
let position = tree.max_leaf_position(None).unwrap().unwrap();
let merkle_path = tree
.witness_at_checkpoint_id(position, &0)
.unwrap()
.unwrap();
assert_eq!(root, merkle_path.root(MerkleHashOrchard::from_cmx(&cmx)));
(root.into(), merkle_path)
};

// Run the Creator and Constructor roles.
let mut builder = Builder::new(BundleType::DEFAULT, anchor);
builder.add_spend(fvk.clone(), note, merkle_path).unwrap();
builder
.add_spend(fvk.clone(), note, merkle_path.into())
.unwrap();
builder
.add_output(None, recipient, NoteValue::from_raw(10_000), None)
.unwrap();
Expand Down
33 changes: 22 additions & 11 deletions src/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,10 @@ pub mod testing {
mod tests {
use {
crate::tree::{MerkleHashOrchard, EMPTY_ROOTS},
bridgetree::{BridgeTree, Frontier as BridgeFrontier},
group::ff::PrimeField,
incrementalmerkletree::Level,
incrementalmerkletree::{frontier::Frontier, Level, Marking, MerklePath, Retention},
pasta_curves::pallas,
shardtree::{store::memory::MemoryShardStore, ShardTree},
};

#[test]
Expand All @@ -303,31 +303,42 @@ mod tests {
assert_eq!(tv_empty_roots[height], root.to_bytes());
}

let mut tree = BridgeTree::<MerkleHashOrchard, u32, 4>::new(100);
let mut tree: ShardTree<MemoryShardStore<MerkleHashOrchard, u32>, 4, 3> =
ShardTree::new(MemoryShardStore::empty(), 100);
for (i, tv) in crate::test_vectors::merkle_path::test_vectors()
.into_iter()
.enumerate()
{
let checkpoint_id = u32::try_from(i).unwrap();
let cmx = MerkleHashOrchard::from_bytes(&tv.leaves[i]).unwrap();
tree.append(cmx);
let position = tree.mark().expect("tree is not empty");
assert_eq!(position, (i as u64).into());
tree.append(
cmx,
Retention::Checkpoint {
id: checkpoint_id,
marking: Marking::Marked,
},
)
.unwrap();

let root = tree.root(0).unwrap();
let root = tree.root_at_checkpoint_id(&checkpoint_id).unwrap().unwrap();
assert_eq!(root.0, pallas::Base::from_repr(tv.root).unwrap());

// Check paths for all leaves up to this point. The test vectors include paths
// for not-yet-appended leaves (using UNCOMMITTED_ORCHARD as the leaf value),
// but BridgeTree doesn't encode these.
for j in 0..=i {
let position = j.try_into().unwrap();
assert_eq!(
tree.witness(j.try_into().unwrap(), 0).ok(),
Some(
tree.witness_at_checkpoint_id(position, &checkpoint_id)
.unwrap(),
MerklePath::from_parts(
tv.paths[j]
.iter()
.map(|v| MerkleHashOrchard::from_bytes(v).unwrap())
.collect()
.collect(),
position
)
.ok()
);
}
}
Expand Down Expand Up @@ -392,7 +403,7 @@ mod tests {
0x9c, 0x52, 0x7f, 0x0e,
];

let mut frontier = BridgeFrontier::<MerkleHashOrchard, 32>::empty();
let mut frontier: Frontier<MerkleHashOrchard, 32> = Frontier::empty();
for commitment in commitments.iter() {
let cmx = MerkleHashOrchard(pallas::Base::from_repr(*commitment).unwrap());
frontier.append(cmx);
Expand Down
38 changes: 22 additions & 16 deletions tests/builder.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use bridgetree::BridgeTree;
use incrementalmerkletree::Hashable;
use incrementalmerkletree::{Hashable, Marking, Retention};
use orchard::{
builder::{Builder, BundleType},
bundle::{Authorized, Flags},
circuit::{ProvingKey, VerifyingKey},
keys::{FullViewingKey, PreparedIncomingViewingKey, Scope, SpendAuthorizingKey, SpendingKey},
note::ExtractedNoteCommitment,
note_encryption::OrchardDomain,
tree::{MerkleHashOrchard, MerklePath},
tree::MerkleHashOrchard,
value::NoteValue,
Bundle,
};
use rand::rngs::OsRng;
use shardtree::{store::memory::MemoryShardStore, ShardTree};
use zcash_note_encryption::try_note_decryption;

fn verify_bundle(bundle: &Bundle<Authorized, i64>, vk: &VerifyingKey) {
Expand Down Expand Up @@ -91,20 +91,26 @@ 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::<MerkleHashOrchard, u32, 32>::new(100);
tree.append(leaf);
let position = tree.mark().unwrap();
let root = tree.root(0).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(),
);
let anchor = root.into();
assert_eq!(anchor, merkle_path.root(cmx));
let mut tree: ShardTree<MemoryShardStore<MerkleHashOrchard, u32>, 32, 16> =
ShardTree::new(MemoryShardStore::empty(), 100);
tree.append(
leaf,
Retention::Checkpoint {
id: 0,
marking: Marking::Marked,
},
)
.unwrap();
let root = tree.root_at_checkpoint_id(&0).unwrap().unwrap();
let position = tree.max_leaf_position(None).unwrap().unwrap();
let merkle_path = tree
.witness_at_checkpoint_id(position, &0)
.unwrap()
.unwrap();
assert_eq!(root, merkle_path.root(MerkleHashOrchard::from_cmx(&cmx)));

let mut builder = Builder::new(BundleType::DEFAULT, anchor);
assert_eq!(builder.add_spend(fvk, note, merkle_path), Ok(()));
let mut builder = Builder::new(BundleType::DEFAULT, root.into());
assert_eq!(builder.add_spend(fvk, note, merkle_path.into()), Ok(()));
assert_eq!(
builder.add_output(None, recipient, NoteValue::from_raw(5000), None),
Ok(())
Expand Down

0 comments on commit 0a1c17d

Please sign in to comment.