Skip to content

Commit bd83da3

Browse files
committedMar 28, 2024
leaf from hash
1 parent 141d273 commit bd83da3

File tree

1 file changed

+35
-26
lines changed

1 file changed

+35
-26
lines changed
 

‎src/dynamic_merkle_tree.rs

+35-26
Original file line numberDiff line numberDiff line change
@@ -324,22 +324,29 @@ impl<H: Hasher, S: DynamicTreeStorage<H>> DynamicMerkleTree<H, S> {
324324
}
325325

326326
#[must_use]
327-
pub fn get_leaf_from_hash(&self, hash: H::Hash) -> usize {
327+
pub fn get_leaf_from_hash(&self, hash: H::Hash) -> Option<usize> {
328328
let num_leaves = self.num_leaves();
329-
let storage_len = self.storage.len();
329+
if num_leaves == 0 {
330+
return None;
331+
}
332+
333+
let mut end = index_from_leaf(num_leaves - 1) + 1; // 4
334+
let prev_pow = end.next_power_of_two() >> 1;
335+
let mut start = prev_pow + (prev_pow >> 1);
330336

331-
let mut index = index_from_leaf(num_leaves - 1);
332-
let mut subtree_base = storage_len >> 2;
333337
loop {
334-
let end = index.next_power_of_two();
335-
let start = end - (end >> 2);
336-
(start..end)
337-
.rev()
338-
.find(|&i| self.storage[i] == hash)
339-
.map(|i| {
340-
index = i;
341-
subtree_base >>= 1;
342-
});
338+
match (start..end).rev().find(|&i| self.storage[i] == hash) {
339+
Some(index) => {
340+
return Some(leaf_from_index(index));
341+
}
342+
None => {
343+
if start == 1 {
344+
return None;
345+
}
346+
start /= 2;
347+
end = (start + 1).next_power_of_two();
348+
}
349+
}
343350
}
344351
}
345352

@@ -358,17 +365,6 @@ impl<H: Hasher> DynamicMerkleTree<H, MmapVec<H>> {
358365
assert!(depth > 0);
359366
let storage = MmapVec::restore(empty_value, config.file_path)?;
360367
let sparse_column = Self::sparse_column(depth, empty_value);
361-
let storage_slice: &[H::Hash] = &storage;
362-
let base_len = storage_slice.len() >> 1;
363-
let quarter = base_len >> 1;
364-
let start = base_len + quarter;
365-
let last_leaf_index = storage_slice[(start)..]
366-
.iter()
367-
.enumerate()
368-
.rev()
369-
.find_map(|(i, &val)| (val != *empty_value).then_some(i))
370-
.expect("no leaves found")
371-
+ start;
372368

373369
let mut tree = DynamicMerkleTree {
374370
depth,
@@ -1021,6 +1017,20 @@ mod tests {
10211017
}
10221018
}
10231019

1020+
#[test]
1021+
fn test_get_leaf_from_hash() {
1022+
let empty = 0;
1023+
let mut tree = DynamicMerkleTree::<TestHasher>::new((), 10, &empty);
1024+
for i in 1..=64 {
1025+
tree.push(i).unwrap();
1026+
let first = tree.get_leaf_from_hash(1).unwrap();
1027+
let this = tree.get_leaf_from_hash(i).unwrap();
1028+
assert_eq!(first, 0);
1029+
assert_eq!(this, i - 1);
1030+
}
1031+
assert!(tree.get_leaf_from_hash(65).is_none());
1032+
}
1033+
10241034
#[test]
10251035
fn test_push() {
10261036
let num_leaves = 1 << 3;
@@ -1045,10 +1055,9 @@ mod tests {
10451055
&empty,
10461056
&leaves,
10471057
);
1048-
for i in 0..10000 {
1058+
for _ in 0..100000 {
10491059
tree.push(3).unwrap();
10501060

1051-
println!("restoring {i}");
10521061
let restored =
10531062
DynamicMerkleTree::<TestHasher, MmapVec<_>>::restore(config.clone(), 20, &empty)
10541063
.unwrap();

0 commit comments

Comments
 (0)