Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade incrementalmerkletree to version 0.8.1 #442

Merged
merged 2 commits into from
Jan 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ and this project adheres to Rust's notion of

### Changed
- MSRV is now 1.70
- Migrated to `nonempty 0.11`.
- Migrated to `nonempty 0.11`, `incrementalmerkletree 0.8`, `shardtree 0.6`, `zip32 0.1.3`.

## [0.10.1] - 2024-12-16

Expand Down
36 changes: 20 additions & 16 deletions Cargo.lock

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

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ serde = { version = "1.0", default-features = false, features = ["derive"] }
sinsemilla = "0.1"
subtle = { version = "2.3", default-features = false }
zcash_note_encryption = "0.4"
incrementalmerkletree = { version = "0.7", default-features = false }
incrementalmerkletree = "0.8.1"
zcash_spec = "0.1"
zip32 = { version = "0.1", default-features = false }
zip32 = { version = "0.1.3", default-features = false }
visibility = "0.1.1"

# Circuit
Expand All @@ -65,13 +65,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.1", features = ["test-dependencies"] }
shardtree = "0.6"

[target.'cfg(unix)'.dev-dependencies]
inferno = { version = "0.11", default-features = false, features = ["multithreaded", "nameattr"] }
Expand Down
39 changes: 24 additions & 15 deletions src/pczt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,11 @@ impl 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 @@ -344,7 +345,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 @@ -415,23 +416,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 @@ -290,10 +290,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 @@ -304,31 +304,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 @@ -393,7 +404,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