@@ -324,22 +324,29 @@ impl<H: Hasher, S: DynamicTreeStorage<H>> DynamicMerkleTree<H, S> {
324
324
}
325
325
326
326
#[ 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 > {
328
328
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 ) ;
330
336
331
- let mut index = index_from_leaf ( num_leaves - 1 ) ;
332
- let mut subtree_base = storage_len >> 2 ;
333
337
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
+ }
343
350
}
344
351
}
345
352
@@ -358,17 +365,6 @@ impl<H: Hasher> DynamicMerkleTree<H, MmapVec<H>> {
358
365
assert ! ( depth > 0 ) ;
359
366
let storage = MmapVec :: restore ( empty_value, config. file_path ) ?;
360
367
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;
372
368
373
369
let mut tree = DynamicMerkleTree {
374
370
depth,
@@ -1021,6 +1017,20 @@ mod tests {
1021
1017
}
1022
1018
}
1023
1019
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
+
1024
1034
#[ test]
1025
1035
fn test_push ( ) {
1026
1036
let num_leaves = 1 << 3 ;
@@ -1045,10 +1055,9 @@ mod tests {
1045
1055
& empty,
1046
1056
& leaves,
1047
1057
) ;
1048
- for i in 0 ..10000 {
1058
+ for _ in 0 ..100000 {
1049
1059
tree. push ( 3 ) . unwrap ( ) ;
1050
1060
1051
- println ! ( "restoring {i}" ) ;
1052
1061
let restored =
1053
1062
DynamicMerkleTree :: < TestHasher , MmapVec < _ > > :: restore ( config. clone ( ) , 20 , & empty)
1054
1063
. unwrap ( ) ;
0 commit comments