Browse Source

Merge pull request #134 from 0xPolygonMiden/add-rustfmt-config

config: add rustfmt config
al-gkr-basic-workflow
Augusto Hack 2 years ago
committed by GitHub
parent
commit
45412b5cec
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 126 additions and 341 deletions
  1. +1
    -7
      benches/hash.rs
  2. +1
    -6
      benches/smt.rs
  3. +20
    -30
      benches/store.rs
  4. +20
    -0
      rustfmt.toml
  5. +1
    -4
      src/hash/blake/mod.rs
  6. +5
    -6
      src/hash/rpo/digest.rs
  7. +1
    -4
      src/merkle/index.rs
  8. +6
    -26
      src/merkle/merkle_tree.rs
  9. +1
    -3
      src/merkle/mmr/accumulator.rs
  10. +1
    -4
      src/merkle/mmr/full.rs
  11. +18
    -78
      src/merkle/mmr/tests.rs
  12. +6
    -13
      src/merkle/path_set.rs
  13. +2
    -11
      src/merkle/simple_smt/mod.rs
  14. +7
    -26
      src/merkle/simple_smt/tests.rs
  15. +7
    -19
      src/merkle/store/mod.rs
  16. +29
    -104
      src/merkle/store/tests.rs

+ 1
- 7
benches/hash.rs

@ -106,11 +106,5 @@ fn blake3_sequential(c: &mut Criterion) {
}); });
} }
criterion_group!(
hash_group,
rpo256_2to1,
rpo256_sequential,
blake3_2to1,
blake3_sequential
);
criterion_group!(hash_group, rpo256_2to1, rpo256_sequential, blake3_2to1, blake3_sequential);
criterion_main!(hash_group); criterion_main!(hash_group);

+ 1
- 6
benches/smt.rs

@ -75,10 +75,5 @@ criterion_main!(smt_group);
fn generate_word(seed: &mut [u8; 32]) -> Word { fn generate_word(seed: &mut [u8; 32]) -> Word {
swap(seed, &mut prng_array(*seed)); swap(seed, &mut prng_array(*seed));
let nums: [u64; 4] = prng_array(*seed); let nums: [u64; 4] = prng_array(*seed);
[
Felt::new(nums[0]),
Felt::new(nums[1]),
Felt::new(nums[2]),
Felt::new(nums[3]),
]
[Felt::new(nums[0]), Felt::new(nums[1]), Felt::new(nums[2]), Felt::new(nums[3])]
} }

+ 20
- 30
benches/store.rs

@ -347,16 +347,13 @@ fn new(c: &mut Criterion) {
// This could be done with `bench_with_input`, however to remove variables while comparing // This could be done with `bench_with_input`, however to remove variables while comparing
// with MerkleTree it is using `iter_batched` // with MerkleTree it is using `iter_batched`
group.bench_function(
BenchmarkId::new("MerkleStore::with_merkle_tree", size),
|b| {
b.iter_batched(
|| leaves.iter().map(|v| v.into()).collect::<Vec<Word>>(),
|l| black_box(MerkleStore::new().with_merkle_tree(l)),
BatchSize::SmallInput,
)
},
);
group.bench_function(BenchmarkId::new("MerkleStore::with_merkle_tree", size), |b| {
b.iter_batched(
|| leaves.iter().map(|v| v.into()).collect::<Vec<Word>>(),
|l| black_box(MerkleStore::new().with_merkle_tree(l)),
BatchSize::SmallInput,
)
});
group.bench_function(BenchmarkId::new("SimpleSmt::new", size), |b| { group.bench_function(BenchmarkId::new("SimpleSmt::new", size), |b| {
b.iter_batched( b.iter_batched(
@ -372,26 +369,19 @@ fn new(c: &mut Criterion) {
) )
}); });
group.bench_function(
BenchmarkId::new("MerkleStore::with_sparse_merkle_tree", size),
|b| {
b.iter_batched(
|| {
leaves
.iter()
.enumerate()
.map(|(c, v)| (c.try_into().unwrap(), v.into()))
.collect::<Vec<(u64, Word)>>()
},
|l| {
black_box(
MerkleStore::new().with_sparse_merkle_tree(SimpleSmt::MAX_DEPTH, l),
)
},
BatchSize::SmallInput,
)
},
);
group.bench_function(BenchmarkId::new("MerkleStore::with_sparse_merkle_tree", size), |b| {
b.iter_batched(
|| {
leaves
.iter()
.enumerate()
.map(|(c, v)| (c.try_into().unwrap(), v.into()))
.collect::<Vec<(u64, Word)>>()
},
|l| black_box(MerkleStore::new().with_sparse_merkle_tree(SimpleSmt::MAX_DEPTH, l)),
BatchSize::SmallInput,
)
});
} }
} }

+ 20
- 0
rustfmt.toml

@ -0,0 +1,20 @@
edition = "2021"
array_width = 80
attr_fn_like_width = 80
chain_width = 80
#condense_wildcard_suffixes = true
#enum_discrim_align_threshold = 40
fn_call_width = 80
#fn_single_line = true
#format_code_in_doc_comments = true
#format_macro_matchers = true
#format_strings = true
#group_imports = "StdExternalCrate"
#hex_literal_case = "Lower"
#imports_granularity = "Crate"
newline_style = "Unix"
#normalize_doc_attributes = true
#reorder_impl_items = true
single_line_if_else_max_width = 60
use_field_init_shorthand = true
use_try_shorthand = true

+ 1
- 4
src/hash/blake/mod.rs

@ -270,10 +270,7 @@ impl Blake3_160 {
/// Zero-copy ref shrink to array. /// Zero-copy ref shrink to array.
fn shrink_bytes<const M: usize, const N: usize>(bytes: &[u8; M]) -> &[u8; N] { fn shrink_bytes<const M: usize, const N: usize>(bytes: &[u8; M]) -> &[u8; N] {
// compile-time assertion // compile-time assertion
assert!(
M >= N,
"N should fit in M so it can be safely transmuted into a smaller slice!"
);
assert!(M >= N, "N should fit in M so it can be safely transmuted into a smaller slice!");
// safety: bytes len is asserted // safety: bytes len is asserted
unsafe { transmute(bytes) } unsafe { transmute(bytes) }
} }

+ 5
- 6
src/hash/rpo/digest.rs

@ -118,14 +118,13 @@ impl Ord for RpoDigest {
// finally, we use `Felt::inner` instead of `Felt::as_int` so we avoid performing a // finally, we use `Felt::inner` instead of `Felt::as_int` so we avoid performing a
// montgomery reduction for every limb. that is safe because every inner element of the // montgomery reduction for every limb. that is safe because every inner element of the
// digest is guaranteed to be in its canonical form (that is, `x in [0,p)`). // digest is guaranteed to be in its canonical form (that is, `x in [0,p)`).
self.0
.iter()
.map(Felt::inner)
.zip(other.0.iter().map(Felt::inner))
.fold(Ordering::Equal, |ord, (a, b)| match ord {
self.0.iter().map(Felt::inner).zip(other.0.iter().map(Felt::inner)).fold(
Ordering::Equal,
|ord, (a, b)| match ord {
Ordering::Equal => a.cmp(&b), Ordering::Equal => a.cmp(&b),
_ => ord, _ => ord,
})
},
)
} }
} }

+ 1
- 4
src/merkle/index.rs

@ -132,10 +132,7 @@ mod tests {
#[test] #[test]
fn test_node_index_value_too_high() { fn test_node_index_value_too_high() {
assert_eq!(
NodeIndex::new(0, 0).unwrap(),
NodeIndex { depth: 0, value: 0 }
);
assert_eq!(NodeIndex::new(0, 0).unwrap(), NodeIndex { depth: 0, value: 0 });
match NodeIndex::new(0, 1) { match NodeIndex::new(0, 1) {
Err(MerkleError::InvalidIndex { depth, value }) => { Err(MerkleError::InvalidIndex { depth, value }) => {
assert_eq!(depth, 0); assert_eq!(depth, 0);

+ 6
- 26
src/merkle/merkle_tree.rs

@ -109,10 +109,7 @@ impl MerkleTree {
index.move_up(); index.move_up();
} }
debug_assert!(
index.is_root(),
"the path walk must go all the way to the root"
);
debug_assert!(index.is_root(), "the path walk must go all the way to the root");
Ok(path.into()) Ok(path.into())
} }
@ -248,12 +245,7 @@ mod tests {
use core::mem::size_of; use core::mem::size_of;
use proptest::prelude::*; use proptest::prelude::*;
const LEAVES4: [Word; 4] = [
int_to_node(1),
int_to_node(2),
int_to_node(3),
int_to_node(4),
];
const LEAVES4: [Word; 4] = [int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
const LEAVES8: [Word; 8] = [ const LEAVES8: [Word; 8] = [
int_to_node(1), int_to_node(1),
@ -309,22 +301,10 @@ mod tests {
let (_, node2, node3) = compute_internal_nodes(); let (_, node2, node3) = compute_internal_nodes();
// check depth 2 // check depth 2
assert_eq!(
vec![LEAVES4[1], node3],
*tree.get_path(NodeIndex::make(2, 0)).unwrap()
);
assert_eq!(
vec![LEAVES4[0], node3],
*tree.get_path(NodeIndex::make(2, 1)).unwrap()
);
assert_eq!(
vec![LEAVES4[3], node2],
*tree.get_path(NodeIndex::make(2, 2)).unwrap()
);
assert_eq!(
vec![LEAVES4[2], node2],
*tree.get_path(NodeIndex::make(2, 3)).unwrap()
);
assert_eq!(vec![LEAVES4[1], node3], *tree.get_path(NodeIndex::make(2, 0)).unwrap());
assert_eq!(vec![LEAVES4[0], node3], *tree.get_path(NodeIndex::make(2, 1)).unwrap());
assert_eq!(vec![LEAVES4[3], node2], *tree.get_path(NodeIndex::make(2, 2)).unwrap());
assert_eq!(vec![LEAVES4[2], node2], *tree.get_path(NodeIndex::make(2, 3)).unwrap());
// check depth 1 // check depth 1
assert_eq!(vec![node3], *tree.get_path(NodeIndex::make(1, 0)).unwrap()); assert_eq!(vec![node3], *tree.get_path(NodeIndex::make(1, 0)).unwrap());

+ 1
- 3
src/merkle/mmr/accumulator.rs

@ -54,8 +54,6 @@ impl MmrPeaks {
pub fn verify(&self, value: Word, opening: MmrProof) -> bool { pub fn verify(&self, value: Word, opening: MmrProof) -> bool {
let root = &self.peaks[opening.peak_index()]; let root = &self.peaks[opening.peak_index()];
opening
.merkle_path
.verify(opening.relative_pos() as u64, value, root)
opening.merkle_path.verify(opening.relative_pos() as u64, value, root)
} }
} }

+ 1
- 4
src/merkle/mmr/full.rs

@ -280,10 +280,7 @@ impl<'a> Iterator for MmrNodes<'a> {
type Item = InnerNodeInfo; type Item = InnerNodeInfo;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
debug_assert!(
self.last_right.count_ones() <= 1,
"last_right tracks zero or one element"
);
debug_assert!(self.last_right.count_ones() <= 1, "last_right tracks zero or one element");
// only parent nodes are emitted, remove the single node tree from the forest // only parent nodes are emitted, remove the single node tree from the forest
let target = self.mmr.forest & (usize::MAX << 1); let target = self.mmr.forest & (usize::MAX << 1);

+ 18
- 78
src/merkle/mmr/tests.rs

@ -118,9 +118,7 @@ fn test_mmr_simple() {
postorder.push(LEAVES[2]); postorder.push(LEAVES[2]);
postorder.push(LEAVES[3]); postorder.push(LEAVES[3]);
postorder.push(*Rpo256::hash_elements(&[LEAVES[2], LEAVES[3]].concat())); postorder.push(*Rpo256::hash_elements(&[LEAVES[2], LEAVES[3]].concat()));
postorder.push(*Rpo256::hash_elements(
&[postorder[2], postorder[5]].concat(),
));
postorder.push(*Rpo256::hash_elements(&[postorder[2], postorder[5]].concat()));
postorder.push(LEAVES[4]); postorder.push(LEAVES[4]);
postorder.push(LEAVES[5]); postorder.push(LEAVES[5]);
postorder.push(*Rpo256::hash_elements(&[LEAVES[4], LEAVES[5]].concat())); postorder.push(*Rpo256::hash_elements(&[LEAVES[4], LEAVES[5]].concat()));
@ -201,10 +199,7 @@ fn test_mmr_open() {
let h23: Word = Rpo256::hash_elements(&LEAVES[2..4].concat()).into(); let h23: Word = Rpo256::hash_elements(&LEAVES[2..4].concat()).into();
// node at pos 7 is the root // node at pos 7 is the root
assert!(
mmr.open(7).is_err(),
"Element 7 is not in the tree, result should be None"
);
assert!(mmr.open(7).is_err(), "Element 7 is not in the tree, result should be None");
// node at pos 6 is the root // node at pos 6 is the root
let empty: MerklePath = MerklePath::new(vec![]); let empty: MerklePath = MerklePath::new(vec![]);
@ -297,41 +292,13 @@ fn test_mmr_open() {
#[test] #[test]
fn test_mmr_get() { fn test_mmr_get() {
let mmr: Mmr = LEAVES.into(); let mmr: Mmr = LEAVES.into();
assert_eq!(
mmr.get(0).unwrap(),
LEAVES[0],
"value at pos 0 must correspond"
);
assert_eq!(
mmr.get(1).unwrap(),
LEAVES[1],
"value at pos 1 must correspond"
);
assert_eq!(
mmr.get(2).unwrap(),
LEAVES[2],
"value at pos 2 must correspond"
);
assert_eq!(
mmr.get(3).unwrap(),
LEAVES[3],
"value at pos 3 must correspond"
);
assert_eq!(
mmr.get(4).unwrap(),
LEAVES[4],
"value at pos 4 must correspond"
);
assert_eq!(
mmr.get(5).unwrap(),
LEAVES[5],
"value at pos 5 must correspond"
);
assert_eq!(
mmr.get(6).unwrap(),
LEAVES[6],
"value at pos 6 must correspond"
);
assert_eq!(mmr.get(0).unwrap(), LEAVES[0], "value at pos 0 must correspond");
assert_eq!(mmr.get(1).unwrap(), LEAVES[1], "value at pos 1 must correspond");
assert_eq!(mmr.get(2).unwrap(), LEAVES[2], "value at pos 2 must correspond");
assert_eq!(mmr.get(3).unwrap(), LEAVES[3], "value at pos 3 must correspond");
assert_eq!(mmr.get(4).unwrap(), LEAVES[4], "value at pos 4 must correspond");
assert_eq!(mmr.get(5).unwrap(), LEAVES[5], "value at pos 5 must correspond");
assert_eq!(mmr.get(6).unwrap(), LEAVES[6], "value at pos 6 must correspond");
assert!(mmr.get(7).is_err()); assert!(mmr.get(7).is_err());
} }
@ -341,11 +308,7 @@ fn test_mmr_invariants() {
for v in 1..=1028 { for v in 1..=1028 {
mmr.add(int_to_node(v)); mmr.add(int_to_node(v));
let accumulator = mmr.accumulator(); let accumulator = mmr.accumulator();
assert_eq!(
v as usize,
mmr.forest(),
"MMR leaf count must increase by one on every add"
);
assert_eq!(v as usize, mmr.forest(), "MMR leaf count must increase by one on every add");
assert_eq!( assert_eq!(
v as usize, accumulator.num_leaves, v as usize, accumulator.num_leaves,
"MMR and its accumulator must match leaves count" "MMR and its accumulator must match leaves count"
@ -374,41 +337,21 @@ fn test_bit_position_iterator() {
assert_eq!(TrueBitPositionIterator::new(0).count(), 0); assert_eq!(TrueBitPositionIterator::new(0).count(), 0);
assert_eq!(TrueBitPositionIterator::new(0).rev().count(), 0); assert_eq!(TrueBitPositionIterator::new(0).rev().count(), 0);
assert_eq!(
TrueBitPositionIterator::new(1).collect::<Vec<u32>>(),
vec![0]
);
assert_eq!(
TrueBitPositionIterator::new(1).rev().collect::<Vec<u32>>(),
vec![0],
);
assert_eq!(TrueBitPositionIterator::new(1).collect::<Vec<u32>>(), vec![0]);
assert_eq!(TrueBitPositionIterator::new(1).rev().collect::<Vec<u32>>(), vec![0],);
assert_eq!(
TrueBitPositionIterator::new(2).collect::<Vec<u32>>(),
vec![1]
);
assert_eq!(
TrueBitPositionIterator::new(2).rev().collect::<Vec<u32>>(),
vec![1],
);
assert_eq!(TrueBitPositionIterator::new(2).collect::<Vec<u32>>(), vec![1]);
assert_eq!(TrueBitPositionIterator::new(2).rev().collect::<Vec<u32>>(), vec![1],);
assert_eq!(
TrueBitPositionIterator::new(3).collect::<Vec<u32>>(),
vec![0, 1],
);
assert_eq!(
TrueBitPositionIterator::new(3).rev().collect::<Vec<u32>>(),
vec![1, 0],
);
assert_eq!(TrueBitPositionIterator::new(3).collect::<Vec<u32>>(), vec![0, 1],);
assert_eq!(TrueBitPositionIterator::new(3).rev().collect::<Vec<u32>>(), vec![1, 0],);
assert_eq!( assert_eq!(
TrueBitPositionIterator::new(0b11010101).collect::<Vec<u32>>(), TrueBitPositionIterator::new(0b11010101).collect::<Vec<u32>>(),
vec![0, 2, 4, 6, 7], vec![0, 2, 4, 6, 7],
); );
assert_eq!( assert_eq!(
TrueBitPositionIterator::new(0b11010101)
.rev()
.collect::<Vec<u32>>(),
TrueBitPositionIterator::new(0b11010101).rev().collect::<Vec<u32>>(),
vec![7, 6, 4, 2, 0], vec![7, 6, 4, 2, 0],
); );
} }
@ -463,10 +406,7 @@ fn test_mmr_hash_peaks() {
// minimum length is 16 // minimum length is 16
let mut expected_peaks = [first_peak, second_peak, third_peak].to_vec(); let mut expected_peaks = [first_peak, second_peak, third_peak].to_vec();
expected_peaks.resize(16, [ZERO; WORD_SIZE]); expected_peaks.resize(16, [ZERO; WORD_SIZE]);
assert_eq!(
peaks.hash_peaks(),
*Rpo256::hash_elements(&expected_peaks.as_slice().concat())
);
assert_eq!(peaks.hash_peaks(), *Rpo256::hash_elements(&expected_peaks.as_slice().concat()));
} }
#[test] #[test]

+ 6
- 13
src/merkle/path_set.rs

@ -34,12 +34,10 @@ impl MerklePathSet {
where where
I: IntoIterator<Item = (u64, Word, MerklePath)>, I: IntoIterator<Item = (u64, Word, MerklePath)>,
{ {
paths
.into_iter()
.try_fold(self, |mut set, (index, value, path)| {
set.add_path(index, value, path)?;
Ok(set)
})
paths.into_iter().try_fold(self, |mut set, (index, value, path)| {
set.add_path(index, value, path)?;
Ok(set)
})
} }
// PUBLIC ACCESSORS // PUBLIC ACCESSORS
@ -291,14 +289,9 @@ mod tests {
let hash_6 = int_to_node(6); let hash_6 = int_to_node(6);
let index = 6_u64; let index = 6_u64;
let depth = 3_u8; let depth = 3_u8;
let set = MerklePathSet::new(depth)
.with_paths([(index, hash_6, path_6.into())])
.unwrap();
let set = MerklePathSet::new(depth).with_paths([(index, hash_6, path_6.into())]).unwrap();
assert_eq!(
int_to_node(6u64),
set.get_node(NodeIndex::make(depth, index)).unwrap()
);
assert_eq!(int_to_node(6u64), set.get_node(NodeIndex::make(depth, index)).unwrap());
} }
#[test] #[test]

+ 2
- 11
src/merkle/simple_smt/mod.rs

@ -131,12 +131,7 @@ impl SimpleSmt {
Err(MerkleError::DepthTooBig(index.depth() as u64)) Err(MerkleError::DepthTooBig(index.depth() as u64))
} else if index.depth() == self.depth() { } else if index.depth() == self.depth() {
self.get_leaf_node(index.value()) self.get_leaf_node(index.value())
.or_else(|| {
self.empty_hashes
.get(index.depth() as usize)
.copied()
.map(Word::from)
})
.or_else(|| self.empty_hashes.get(index.depth() as usize).copied().map(Word::from))
.ok_or(MerkleError::NodeNotInSet(index.value())) .ok_or(MerkleError::NodeNotInSet(index.value()))
} else { } else {
let branch_node = self.get_branch_node(&index); let branch_node = self.get_branch_node(&index);
@ -217,11 +212,7 @@ impl SimpleSmt {
let is_right = index.is_value_odd(); let is_right = index.is_value_odd();
index.move_up(); index.move_up();
let BranchNode { left, right } = self.get_branch_node(&index); let BranchNode { left, right } = self.get_branch_node(&index);
let (left, right) = if is_right {
(left, value)
} else {
(value, right)
};
let (left, right) = if is_right { (left, value) } else { (value, right) };
self.insert_branch_node(index, left, right); self.insert_branch_node(index, left, right);
value = Rpo256::merge(&[left, right]); value = Rpo256::merge(&[left, right]);
} }

+ 7
- 26
src/merkle/simple_smt/tests.rs

@ -8,12 +8,7 @@ use rand_utils::prng_array;
const KEYS4: [u64; 4] = [0, 1, 2, 3]; const KEYS4: [u64; 4] = [0, 1, 2, 3];
const KEYS8: [u64; 8] = [0, 1, 2, 3, 4, 5, 6, 7]; const KEYS8: [u64; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
const VALUES4: [Word; 4] = [
int_to_node(1),
int_to_node(2),
int_to_node(3),
int_to_node(4),
];
const VALUES4: [Word; 4] = [int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
const VALUES8: [Word; 8] = [ const VALUES8: [Word; 8] = [
int_to_node(1), int_to_node(1),
@ -56,8 +51,7 @@ fn build_sparse_tree() {
let key = 6; let key = 6;
let new_node = int_to_node(7); let new_node = int_to_node(7);
values[key as usize] = new_node; values[key as usize] = new_node;
smt.insert_leaf(key, new_node)
.expect("Failed to insert leaf");
smt.insert_leaf(key, new_node).expect("Failed to insert leaf");
let mt2 = MerkleTree::new(values.clone()).unwrap(); let mt2 = MerkleTree::new(values.clone()).unwrap();
assert_eq!(mt2.root(), smt.root()); assert_eq!(mt2.root(), smt.root());
assert_eq!( assert_eq!(
@ -69,8 +63,7 @@ fn build_sparse_tree() {
let key = 2; let key = 2;
let new_node = int_to_node(3); let new_node = int_to_node(3);
values[key as usize] = new_node; values[key as usize] = new_node;
smt.insert_leaf(key, new_node)
.expect("Failed to insert leaf");
smt.insert_leaf(key, new_node).expect("Failed to insert leaf");
let mt3 = MerkleTree::new(values).unwrap(); let mt3 = MerkleTree::new(values).unwrap();
assert_eq!(mt3.root(), smt.root()); assert_eq!(mt3.root(), smt.root());
assert_eq!( assert_eq!(
@ -116,22 +109,10 @@ fn get_path() {
let (_, node2, node3) = compute_internal_nodes(); let (_, node2, node3) = compute_internal_nodes();
// check depth 2 // check depth 2
assert_eq!(
vec![VALUES4[1], node3],
*tree.get_path(NodeIndex::make(2, 0)).unwrap()
);
assert_eq!(
vec![VALUES4[0], node3],
*tree.get_path(NodeIndex::make(2, 1)).unwrap()
);
assert_eq!(
vec![VALUES4[3], node2],
*tree.get_path(NodeIndex::make(2, 2)).unwrap()
);
assert_eq!(
vec![VALUES4[2], node2],
*tree.get_path(NodeIndex::make(2, 3)).unwrap()
);
assert_eq!(vec![VALUES4[1], node3], *tree.get_path(NodeIndex::make(2, 0)).unwrap());
assert_eq!(vec![VALUES4[0], node3], *tree.get_path(NodeIndex::make(2, 1)).unwrap());
assert_eq!(vec![VALUES4[3], node2], *tree.get_path(NodeIndex::make(2, 2)).unwrap());
assert_eq!(vec![VALUES4[2], node2], *tree.get_path(NodeIndex::make(2, 3)).unwrap());
// check depth 1 // check depth 1
assert_eq!(vec![node3], *tree.get_path(NodeIndex::make(1, 0)).unwrap()); assert_eq!(vec![node3], *tree.get_path(NodeIndex::make(1, 0)).unwrap());

+ 7
- 19
src/merkle/store/mod.rs

@ -184,15 +184,11 @@ impl MerkleStore {
let mut hash: RpoDigest = root.into(); let mut hash: RpoDigest = root.into();
// corner case: check the root is in the store when called with index `NodeIndex::root()` // corner case: check the root is in the store when called with index `NodeIndex::root()`
self.nodes
.get(&hash)
.ok_or(MerkleError::RootNotInStore(hash.into()))?;
self.nodes.get(&hash).ok_or(MerkleError::RootNotInStore(hash.into()))?;
for i in (0..index.depth()).rev() { for i in (0..index.depth()).rev() {
let node = self
.nodes
.get(&hash)
.ok_or(MerkleError::NodeNotInStore(hash.into(), index))?;
let node =
self.nodes.get(&hash).ok_or(MerkleError::NodeNotInStore(hash.into(), index))?;
let bit = (index.value() >> i) & 1; let bit = (index.value() >> i) & 1;
hash = if bit == 0 { node.left } else { node.right } hash = if bit == 0 { node.left } else { node.right }
@ -215,15 +211,11 @@ impl MerkleStore {
let mut path = Vec::with_capacity(index.depth().into()); let mut path = Vec::with_capacity(index.depth().into());
// corner case: check the root is in the store when called with index `NodeIndex::root()` // corner case: check the root is in the store when called with index `NodeIndex::root()`
self.nodes
.get(&hash)
.ok_or(MerkleError::RootNotInStore(hash.into()))?;
self.nodes.get(&hash).ok_or(MerkleError::RootNotInStore(hash.into()))?;
for i in (0..index.depth()).rev() { for i in (0..index.depth()).rev() {
let node = self
.nodes
.get(&hash)
.ok_or(MerkleError::NodeNotInStore(hash.into(), index))?;
let node =
self.nodes.get(&hash).ok_or(MerkleError::NodeNotInStore(hash.into(), index))?;
let bit = (index.value() >> i) & 1; let bit = (index.value() >> i) & 1;
hash = if bit == 0 { hash = if bit == 0 {
@ -302,11 +294,7 @@ impl MerkleStore {
}; };
// traverse down // traverse down
hash = if path & 1 == 0 {
children.left
} else {
children.right
};
hash = if path & 1 == 0 { children.left } else { children.right };
path >>= 1; path >>= 1;
} }

+ 29
- 104
src/merkle/store/tests.rs

@ -9,12 +9,7 @@ use crate::{
use std::error::Error; use std::error::Error;
const KEYS4: [u64; 4] = [0, 1, 2, 3]; const KEYS4: [u64; 4] = [0, 1, 2, 3];
const LEAVES4: [Word; 4] = [
int_to_node(1),
int_to_node(2),
int_to_node(3),
int_to_node(4),
];
const LEAVES4: [Word; 4] = [int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
const EMPTY: Word = [ZERO; WORD_SIZE]; const EMPTY: Word = [ZERO; WORD_SIZE];
#[test] #[test]
@ -90,9 +85,7 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
// STORE MERKLE PATH MATCHS ============================================================== // STORE MERKLE PATH MATCHS ==============================================================
// assert the merkle path returned by the store is the same as the one in the tree // assert the merkle path returned by the store is the same as the one in the tree
let result = store
.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 0))
.unwrap();
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 0)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[0], result.value, LEAVES4[0], result.value,
"Value for merkle path at index 0 must match leaf value" "Value for merkle path at index 0 must match leaf value"
@ -103,9 +96,7 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
"merkle path for index 0 must be the same for the MerkleTree and MerkleStore" "merkle path for index 0 must be the same for the MerkleTree and MerkleStore"
); );
let result = store
.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 1))
.unwrap();
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 1)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[1], result.value, LEAVES4[1], result.value,
"Value for merkle path at index 0 must match leaf value" "Value for merkle path at index 0 must match leaf value"
@ -116,9 +107,7 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
"merkle path for index 1 must be the same for the MerkleTree and MerkleStore" "merkle path for index 1 must be the same for the MerkleTree and MerkleStore"
); );
let result = store
.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 2))
.unwrap();
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 2)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[2], result.value, LEAVES4[2], result.value,
"Value for merkle path at index 0 must match leaf value" "Value for merkle path at index 0 must match leaf value"
@ -129,9 +118,7 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
"merkle path for index 0 must be the same for the MerkleTree and MerkleStore" "merkle path for index 0 must be the same for the MerkleTree and MerkleStore"
); );
let result = store
.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 3))
.unwrap();
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 3)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[3], result.value, LEAVES4[3], result.value,
"Value for merkle path at index 0 must match leaf value" "Value for merkle path at index 0 must match leaf value"
@ -172,10 +159,7 @@ fn test_leaf_paths_for_empty_trees() -> Result<(), MerkleError> {
let index = NodeIndex::make(depth, 0); let index = NodeIndex::make(depth, 0);
let store_path = store.get_path(smt.root(), index)?; let store_path = store.get_path(smt.root(), index)?;
let smt_path = smt.get_path(index)?; let smt_path = smt.get_path(index)?;
assert_eq!(
store_path.value, EMPTY,
"the leaf of an empty tree is always ZERO"
);
assert_eq!(store_path.value, EMPTY, "the leaf of an empty tree is always ZERO");
assert_eq!( assert_eq!(
store_path.path, smt_path, store_path.path, smt_path,
"the returned merkle path does not match the computed values" "the returned merkle path does not match the computed values"
@ -213,17 +197,11 @@ fn test_add_sparse_merkle_tree_one_level() -> Result<(), MerkleError> {
let idx = NodeIndex::make(1, 0); let idx = NodeIndex::make(1, 0);
assert_eq!(smt.get_node(idx).unwrap(), leaves2[0]); assert_eq!(smt.get_node(idx).unwrap(), leaves2[0]);
assert_eq!(
store.get_node(smt.root(), idx).unwrap(),
smt.get_node(idx).unwrap()
);
assert_eq!(store.get_node(smt.root(), idx).unwrap(), smt.get_node(idx).unwrap());
let idx = NodeIndex::make(1, 1); let idx = NodeIndex::make(1, 1);
assert_eq!(smt.get_node(idx).unwrap(), leaves2[1]); assert_eq!(smt.get_node(idx).unwrap(), leaves2[1]);
assert_eq!(
store.get_node(smt.root(), idx).unwrap(),
smt.get_node(idx).unwrap()
);
assert_eq!(store.get_node(smt.root(), idx).unwrap(), smt.get_node(idx).unwrap());
Ok(()) Ok(())
} }
@ -231,10 +209,8 @@ fn test_add_sparse_merkle_tree_one_level() -> Result<(), MerkleError> {
#[test] #[test]
fn test_sparse_merkle_tree() -> Result<(), MerkleError> { fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
let mut store = MerkleStore::default(); let mut store = MerkleStore::default();
store.add_sparse_merkle_tree(
SimpleSmt::MAX_DEPTH,
KEYS4.into_iter().zip(LEAVES4.into_iter()),
)?;
store
.add_sparse_merkle_tree(SimpleSmt::MAX_DEPTH, KEYS4.into_iter().zip(LEAVES4.into_iter()))?;
let smt = SimpleSmt::new(SimpleSmt::MAX_DEPTH) let smt = SimpleSmt::new(SimpleSmt::MAX_DEPTH)
.unwrap() .unwrap()
@ -299,9 +275,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
// STORE MERKLE PATH MATCHS ============================================================== // STORE MERKLE PATH MATCHS ==============================================================
// assert the merkle path returned by the store is the same as the one in the tree // assert the merkle path returned by the store is the same as the one in the tree
let result = store
.get_path(smt.root(), NodeIndex::make(smt.depth(), 0))
.unwrap();
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 0)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[0], result.value, LEAVES4[0], result.value,
"Value for merkle path at index 0 must match leaf value" "Value for merkle path at index 0 must match leaf value"
@ -312,9 +286,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
"merkle path for index 0 must be the same for the MerkleTree and MerkleStore" "merkle path for index 0 must be the same for the MerkleTree and MerkleStore"
); );
let result = store
.get_path(smt.root(), NodeIndex::make(smt.depth(), 1))
.unwrap();
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 1)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[1], result.value, LEAVES4[1], result.value,
"Value for merkle path at index 1 must match leaf value" "Value for merkle path at index 1 must match leaf value"
@ -325,9 +297,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
"merkle path for index 1 must be the same for the MerkleTree and MerkleStore" "merkle path for index 1 must be the same for the MerkleTree and MerkleStore"
); );
let result = store
.get_path(smt.root(), NodeIndex::make(smt.depth(), 2))
.unwrap();
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 2)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[2], result.value, LEAVES4[2], result.value,
"Value for merkle path at index 2 must match leaf value" "Value for merkle path at index 2 must match leaf value"
@ -338,9 +308,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
"merkle path for index 2 must be the same for the MerkleTree and MerkleStore" "merkle path for index 2 must be the same for the MerkleTree and MerkleStore"
); );
let result = store
.get_path(smt.root(), NodeIndex::make(smt.depth(), 3))
.unwrap();
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 3)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[3], result.value, LEAVES4[3], result.value,
"Value for merkle path at index 3 must match leaf value" "Value for merkle path at index 3 must match leaf value"
@ -351,13 +319,8 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
"merkle path for index 3 must be the same for the MerkleTree and MerkleStore" "merkle path for index 3 must be the same for the MerkleTree and MerkleStore"
); );
let result = store
.get_path(smt.root(), NodeIndex::make(smt.depth(), 4))
.unwrap();
assert_eq!(
EMPTY, result.value,
"Value for merkle path at index 4 must match leaf value"
);
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 4)).unwrap();
assert_eq!(EMPTY, result.value, "Value for merkle path at index 4 must match leaf value");
assert_eq!( assert_eq!(
smt.get_path(NodeIndex::make(smt.depth(), 4)), smt.get_path(NodeIndex::make(smt.depth(), 4)),
Ok(result.path), Ok(result.path),
@ -391,9 +354,7 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
]; ];
let mut store = MerkleStore::default(); let mut store = MerkleStore::default();
store
.add_merkle_paths(paths.clone())
.expect("the valid paths must work");
store.add_merkle_paths(paths.clone()).expect("the valid paths must work");
let depth = 2; let depth = 2;
let set = MerklePathSet::new(depth).with_paths(paths).unwrap(); let set = MerklePathSet::new(depth).with_paths(paths).unwrap();
@ -446,9 +407,7 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
// STORE MERKLE PATH MATCHS ============================================================== // STORE MERKLE PATH MATCHS ==============================================================
// assert the merkle path returned by the store is the same as the one in the set // assert the merkle path returned by the store is the same as the one in the set
let result = store
.get_path(set.root(), NodeIndex::make(set.depth(), 0))
.unwrap();
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 0)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[0], result.value, LEAVES4[0], result.value,
"Value for merkle path at index 0 must match leaf value" "Value for merkle path at index 0 must match leaf value"
@ -459,9 +418,7 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
"merkle path for index 0 must be the same for the MerkleTree and MerkleStore" "merkle path for index 0 must be the same for the MerkleTree and MerkleStore"
); );
let result = store
.get_path(set.root(), NodeIndex::make(set.depth(), 1))
.unwrap();
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 1)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[1], result.value, LEAVES4[1], result.value,
"Value for merkle path at index 0 must match leaf value" "Value for merkle path at index 0 must match leaf value"
@ -472,9 +429,7 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
"merkle path for index 1 must be the same for the MerkleTree and MerkleStore" "merkle path for index 1 must be the same for the MerkleTree and MerkleStore"
); );
let result = store
.get_path(set.root(), NodeIndex::make(set.depth(), 2))
.unwrap();
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 2)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[2], result.value, LEAVES4[2], result.value,
"Value for merkle path at index 0 must match leaf value" "Value for merkle path at index 0 must match leaf value"
@ -485,9 +440,7 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
"merkle path for index 0 must be the same for the MerkleTree and MerkleStore" "merkle path for index 0 must be the same for the MerkleTree and MerkleStore"
); );
let result = store
.get_path(set.root(), NodeIndex::make(set.depth(), 3))
.unwrap();
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 3)).unwrap();
assert_eq!( assert_eq!(
LEAVES4[3], result.value, LEAVES4[3], result.value,
"Value for merkle path at index 0 must match leaf value" "Value for merkle path at index 0 must match leaf value"
@ -546,13 +499,8 @@ fn store_path_opens_from_leaf() {
let root = Rpo256::merge(&[m.into(), n.into()]); let root = Rpo256::merge(&[m.into(), n.into()]);
let store = MerkleStore::default()
.with_merkle_tree([a, b, c, d, e, f, g, h])
.unwrap();
let path = store
.get_path(root.into(), NodeIndex::make(3, 1))
.unwrap()
.path;
let store = MerkleStore::default().with_merkle_tree([a, b, c, d, e, f, g, h]).unwrap();
let path = store.get_path(root.into(), NodeIndex::make(3, 1)).unwrap().path;
let expected = MerklePath::new([a.into(), j.into(), n.into()].to_vec()); let expected = MerklePath::new([a.into(), j.into(), n.into()].to_vec());
assert_eq!(path, expected); assert_eq!(path, expected);
@ -565,11 +513,7 @@ fn test_set_node() -> Result<(), MerkleError> {
let value = int_to_node(42); let value = int_to_node(42);
let index = NodeIndex::make(mtree.depth(), 0); let index = NodeIndex::make(mtree.depth(), 0);
let new_root = store.set_node(mtree.root(), index, value)?.root; let new_root = store.set_node(mtree.root(), index, value)?.root;
assert_eq!(
store.get_node(new_root, index),
Ok(value),
"Value must have changed"
);
assert_eq!(store.get_node(new_root, index), Ok(value), "Value must have changed");
Ok(()) Ok(())
} }
@ -604,26 +548,10 @@ fn test_constructors() -> Result<(), MerkleError> {
let d = 2; let d = 2;
let paths = [ let paths = [
(
0,
LEAVES4[0],
mtree.get_path(NodeIndex::make(d, 0)).unwrap(),
),
(
1,
LEAVES4[1],
mtree.get_path(NodeIndex::make(d, 1)).unwrap(),
),
(
2,
LEAVES4[2],
mtree.get_path(NodeIndex::make(d, 2)).unwrap(),
),
(
3,
LEAVES4[3],
mtree.get_path(NodeIndex::make(d, 3)).unwrap(),
),
(0, LEAVES4[0], mtree.get_path(NodeIndex::make(d, 0)).unwrap()),
(1, LEAVES4[1], mtree.get_path(NodeIndex::make(d, 1)).unwrap()),
(2, LEAVES4[2], mtree.get_path(NodeIndex::make(d, 2)).unwrap()),
(3, LEAVES4[3], mtree.get_path(NodeIndex::make(d, 3)).unwrap()),
]; ];
let store1 = MerkleStore::default().with_merkle_paths(paths.clone())?; let store1 = MerkleStore::default().with_merkle_paths(paths.clone())?;
@ -792,10 +720,7 @@ fn get_leaf_depth_works_with_depth_8() {
// duplicate the tree on `a` and assert the depth is short-circuited by such sub-tree // duplicate the tree on `a` and assert the depth is short-circuited by such sub-tree
let index = NodeIndex::new(8, a).unwrap(); let index = NodeIndex::new(8, a).unwrap();
root = store.set_node(root, index, root).unwrap().root; root = store.set_node(root, index, root).unwrap().root;
assert_eq!(
Err(MerkleError::DepthTooBig(9)),
store.get_leaf_depth(root, 8, a)
);
assert_eq!(Err(MerkleError::DepthTooBig(9)), store.get_leaf_depth(root, 8, a));
} }
#[cfg(std)] #[cfg(std)]

Loading…
Cancel
Save