spnr_lib/
flat_tree.rs

1//! Merkle Tree implementation based on Flat In-Order Tree.
2//!
3//! Flat In-Order Tree is described in DEP-0002:
4//! <https://github.com/datprotocol/DEPs/blob/master/proposals/0002-hypercore.md>
5//!
6//! A Flat In-Order Tree represents a binary tree as a list, also known as Bin Numbers defined in PPSP RFC 7574:
7//! <https://datatracker.ietf.org/doc/rfc7574/>
8//!
9//! We assume the max node index is 63-bit, which limits the max tree depth (level) to 62.
10//!
11//! A merkle tree with flat layout is storage friendly (i.e. no fragmentation and grows linearly) with O(1) leaf and node access.
12//! It stores all leave nodes, caches the hash of intermediate nodes, and provides efficient merkle path computation for verification purposes.
13
14/// Abstraction over the underlying storage to allow flexible choice of implementation.
15/// For example, an implementation may store multiple trees in a column format, while another may overlay in-memory cache on top of external storage.
16pub trait FlatStore<T> {
17    /// Writes a value at the given offset.
18    ///
19    /// Depending on the implementation, it may panic or silently fail if out of space.
20    /// It is up to the caller to check these conditions before calling this function.
21    fn write(&self, offset: u64, value: &T);
22
23    /// Reads a value off the given offset.
24    ///
25    /// Depending on the implementation, it may not be able to read any value out.
26    /// It is up to the caller to prevent errors (e.g. out-of-bound before calling this function.
27    fn read(&self, offset: u64, value: &mut T);
28}
29
30/// Abstraction over binary hash operation.
31/// The value of a merkle hash is computed by hashing its left branch and right branch.
32/// By default it assumes a value of "zero" if a branch does not exist.
33/// The actual hashing algorithm and the value of zeros at a given tree level are implementation dependent.
34pub trait Merkleable {
35    /// Return the zero at a given level (leaf level is 0).
36    fn zeros(level: usize) -> Self;
37
38    /// Return the hash of self with another.
39    fn hash(&self, another: &Self) -> Self;
40}
41
42/// Representation of a flat tree of element type `T` where the `'a` is the life-time parameter of the underlying [FlatStore].
43///
44/// At the moment the tree is append only, i.e. it can add new leave elements but not update or deletion.
45pub struct FlatTree<'a, T> {
46    store: &'a dyn FlatStore<T>,
47    // Total number of elements, including both leaves and internal nodes.
48    // Number of leaves is exactly size / 2.
49    size: u64,
50}
51
52/// Helper to iterate from a leaf node to one of the roots.
53pub struct LocalPathIterator<'a, T> {
54    tree: &'a FlatTree<'a, T>,
55    cursor: Option<(Index, Pos<T>)>,
56    root_indices: Vec<Index>,
57}
58
59/// Position of a node is either a leaf, a root, or a left or right node.
60#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
61pub enum Pos<T> {
62    Start(T),
63    Left(T),
64    Right(T),
65}
66
67impl<'a, T: Merkleable> Iterator for LocalPathIterator<'a, T> {
68    type Item = Pos<T>;
69
70    fn next(&mut self) -> Option<Self::Item> {
71        let mut cursor = None;
72        std::mem::swap(&mut cursor, &mut self.cursor);
73        match cursor {
74            Some((Index(i), value)) => {
75                let Index(p) = parent_of(Index(i));
76                if self.root_indices.iter().any(|x| *x == Index(i)) {
77                    self.cursor = None;
78                } else {
79                    //let parent = self.tree.read(p);
80                    let j = p * 2 - i;
81                    let v = self.tree.read(j);
82                    self.cursor =
83                        Some((Index(p), if j < i { Pos::Left(v) } else { Pos::Right(v) }));
84                }
85                Some(value)
86            }
87            None => None,
88        }
89    }
90}
91
92/// Helper to iterate from a leaf node to the top root (at a level that is equal to full tree depth).
93///
94/// Note that nodes in this path may not exist in the store and will have to be calculated.
95pub struct FullPathIterator<'a, T> {
96    tree: &'a FlatTree<'a, T>,
97    cursor: Option<(Index, Pos<T>)>,
98    roots: Vec<(Index, T)>,
99}
100
101impl<'a, T: Merkleable> Iterator for FullPathIterator<'a, T> {
102    type Item = Pos<T>;
103
104    fn next(&mut self) -> Option<Self::Item> {
105        let mut cursor = None;
106        std::mem::swap(&mut cursor, &mut self.cursor);
107        match cursor {
108            Some((Index(i), value)) => {
109                let Index(p) = parent_of(Index(i));
110                if Index(i) == self.roots[0].0 {
111                    self.cursor = None;
112                } else {
113                    let j = 2 * p - i;
114                    let hash = if let Some(k) = self.roots.iter().position(|(x, _)| *x == Index(j))
115                    {
116                        let (_, hash) = self.roots.remove(k);
117                        hash
118                    } else if j >= self.tree.size {
119                        let Level(l) = level_of(Index(j));
120                        T::zeros(l)
121                    } else {
122                        self.tree.read(j)
123                    };
124                    self.cursor = Some((
125                        Index(p),
126                        if j < i {
127                            Pos::Left(hash)
128                        } else {
129                            Pos::Right(hash)
130                        },
131                    ));
132                }
133                Some(value)
134            }
135            None => None,
136        }
137    }
138}
139
140impl<'a, T: Merkleable> FlatTree<'a, T> {
141    /// Return a [FlatTree] object of given size with the underlying [FlatStore] as storage.
142    /// If a non-zero size is given, it assumes a valid tree has been previously created on the same store.
143    pub fn new(store: &'a dyn FlatStore<T>, size: u64) -> Self {
144        Self { store, size }
145    }
146
147    /// Depth of a full tree.
148    pub fn depth(&self) -> usize {
149        if self.size == 0 {
150            return 0;
151        }
152        let w = self.size;
153        let mut n = 0;
154        let mut i = 1;
155        while w > i {
156            i *= 2;
157            n += 1;
158        }
159        n
160    }
161
162    /// Width of the tree (number of leave nodes).
163    pub fn width(&self) -> u64 {
164        self.size / 2
165    }
166
167    /// Return true if tree is empty.
168    pub fn is_empty(&self) -> bool {
169        self.size == 0
170    }
171
172    /// Number of leaves in the tree (same as width).
173    pub fn len(&self) -> u64 {
174        self.size / 2
175    }
176
177    /// Append a leaf value to the tree.
178    pub fn push(&mut self, mut value: T) {
179        let mut i = self.size;
180        self.store.write(i, &value);
181        let Level(l) = level_of(Index(i + 1));
182        self.store.write(i + 1, &T::zeros(l));
183        self.size += 2;
184        let mut level = 0;
185        loop {
186            let Index(p) = parent_of(Index(i));
187            let j = p * 2 - i;
188            if p >= self.size || j >= self.size {
189                break;
190            }
191            let mut sibling = T::zeros(level);
192            self.store.read(j, &mut sibling);
193            value = if i < j {
194                value.hash(&sibling)
195            } else {
196                sibling.hash(&value)
197            };
198            self.store.write(p, &value);
199            i = p;
200            level += 1;
201        }
202    }
203
204    /// Append a number of leaf values to the tree.
205    pub fn append(&mut self, value: Vec<T>) {
206        for v in value.into_iter() {
207            self.push(v)
208        }
209    }
210
211    /// Return the value at a given leaf index if it exists.
212    pub fn get(&self, leaf_index: u64) -> Option<T> {
213        if leaf_index >= self.len() {
214            None
215        } else {
216            Some(self.read(leaf_index * 2))
217        }
218    }
219
220    /// Iterate over all leaf values.
221    pub fn iter(&self) -> Box<dyn Iterator<Item = T> + '_> {
222        Box::new((0..self.len()).map(|i| self.get(i).unwrap()))
223    }
224
225    /// Return the top root of the full tree.
226    pub fn root(&self) -> T {
227        self.full_roots()
228            .into_iter()
229            .next()
230            .map(|x| x.1)
231            .unwrap_or_else(|| T::zeros(0))
232    }
233
234    #[cfg(test)]
235    /// Return a list of sub-tree roots.
236    fn local_roots(&self) -> Vec<T> {
237        roots_of(Width(self.width()))
238            .into_iter()
239            .map(|Index(i)| self.read(i))
240            .collect()
241    }
242
243    /// Return the full set of roots, arranged in descending order of depth, where the previous one is the parent of the next.
244    fn full_roots(&self) -> Vec<(Index, T)> {
245        let root_indices = roots_of(Width(self.width()));
246        let mut roots = Vec::new();
247        if root_indices.is_empty() {
248            return roots;
249        };
250        let mut n = root_indices.len() - 1;
251        let Index(mut i) = root_indices[n];
252        let mut hash = self.read(i);
253        let Level(mut level) = level_of(Index(i));
254        while n > 0 {
255            let Index(p) = parent_of(Index(i));
256            let j = p * 2 - i;
257            let sibling = if n > 0 && Index(j) == root_indices[n - 1] {
258                n -= 1;
259                self.read(j)
260            } else {
261                T::zeros(level)
262            };
263            let new_hash = if i < j {
264                hash.hash(&sibling)
265            } else {
266                sibling.hash(&hash)
267            };
268            roots.push((Index(i), hash));
269            hash = new_hash;
270            i = p;
271            level += 1;
272        }
273        roots.push((Index(i), hash));
274        roots.reverse();
275        roots
276    }
277
278    /// Return the merkle path iterating from the leaf at the given index to one of the local roots.
279    pub fn local_path(&self, i: u64) -> LocalPathIterator<'_, T> {
280        let cursor = self.get(i).map(|value| (Index(i * 2), Pos::Start(value)));
281        LocalPathIterator {
282            tree: self,
283            cursor,
284            root_indices: roots_of(Width(self.width())),
285        }
286    }
287
288    /// Return the merkle path iterating from the leaf at the given index to top root.
289    pub fn full_path(&self, i: u64) -> FullPathIterator<'_, T> {
290        let cursor = self.get(i).map(|value| (Index(i * 2), Pos::Start(value)));
291        FullPathIterator {
292            tree: self,
293            cursor,
294            roots: self.full_roots(),
295        }
296    }
297
298    /// Return the full path iterating from the given node index (either leaf or branch node) to top root.
299    /// Note that for leaf nodes, `node_index =  leaf_index * 2`.
300    pub fn full_path_from_node_index(&self, i: u64) -> FullPathIterator<'_, T>
301    where
302        T: Clone,
303    {
304        let roots = self.full_roots();
305        let index = Index(i);
306        let mut cursor = None;
307        if inside_tree(index, Width(self.width())) {
308            cursor = Some((index, Pos::Start(self.read(i))))
309        }
310        if cursor.is_none() {
311            cursor = roots.iter().find_map(|(j, r)| {
312                if index == *j {
313                    Some((index, Pos::Start(r.clone())))
314                } else {
315                    None
316                }
317            });
318        };
319        FullPathIterator {
320            tree: self,
321            cursor,
322            roots: self.full_roots(),
323        }
324    }
325
326    // Read the value at the given node index.
327    fn read(&self, i: u64) -> T {
328        let Level(l) = level_of(Index(i));
329        let mut x = T::zeros(l);
330        self.store.read(i, &mut x);
331        x
332    }
333}
334
335#[cfg(test)]
336fn debug_print<T: Merkleable>(tree: &FlatTree<'_, T>)
337where
338    T: std::fmt::Debug,
339{
340    let w = tree.width();
341    for (i, level) in tree_of(Width(w)).into_iter().enumerate() {
342        match level {
343            None => println!(),
344            Some(Level(l)) => {
345                for _ in 0..2 * l {
346                    print!(" ")
347                }
348                println!("{:?}", tree.read(i as u64));
349            }
350        }
351    }
352}
353
354#[cfg(test)]
355/// Return the list of levels of all indices in the tree of the given width.
356/// Indices of incomplete nodes (those do not have both children) do not have a level, and its corresponding value in the returned list is `None`.
357fn tree_of(w: Width) -> Vec<Option<Level>> {
358    let Width(n) = w;
359    let mut levels = Vec::new();
360    let m = (n - 1) * 2;
361    for i in 0..(m + 1) {
362        let Level(l) = level_of(Index(i));
363        let subtree_size = (1 << l) - 1;
364        if subtree_size + i > m {
365            levels.push(None)
366        } else {
367            levels.push(Some(Level(l)))
368        }
369    }
370    levels
371}
372
373/// Return true if the given Index is inside the tree of given Width.
374fn inside_tree(i: Index, w: Width) -> bool {
375    let Width(n) = w;
376    let m = (n - 1) * 2;
377    let Level(l) = level_of(i);
378    let subtree_size = (1 << l) - 1;
379    subtree_size + i.0 <= m
380}
381
382#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
383pub(crate) struct Level(usize);
384
385/// Max tree depth on a 64-bit architecture is 62.
386pub const MAX_LEVEL: usize = 62;
387
388impl From<Level> for usize {
389    fn from(l: Level) -> usize {
390        l.0
391    }
392}
393
394impl From<usize> for Level {
395    fn from(n: usize) -> Self {
396        assert!(n <= MAX_LEVEL, "level out of bound");
397        Level(n)
398    }
399}
400
401#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
402pub(crate) struct Width(u64);
403
404const MAX_WIDTH: u64 = 1 << MAX_LEVEL;
405
406impl From<Width> for u64 {
407    fn from(w: Width) -> u64 {
408        w.0
409    }
410}
411
412impl From<u64> for Width {
413    fn from(n: u64) -> Self {
414        assert!(n <= MAX_WIDTH, "width out of bound");
415        Width(n)
416    }
417}
418
419#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
420pub(crate) struct Index(u64);
421
422const MAX_ROOT_INDEX: u64 = MAX_WIDTH + 1;
423
424const MAX_INDEX: u64 = MAX_ROOT_INDEX * 2;
425
426impl From<Index> for u64 {
427    fn from(i: Index) -> u64 {
428        i.0
429    }
430}
431
432impl From<u64> for Index {
433    fn from(n: u64) -> Self {
434        assert!(n <= MAX_INDEX, "index out of bound");
435        Index(n)
436    }
437}
438
439/// Return the level of the given `node_index`.
440pub fn level_of_node_index(node_index: u64) -> usize {
441    level_of(Index(node_index)).0
442}
443
444/// Level is equal to trailing number of 1s in the index.
445fn level_of(Index(mut i): Index) -> Level {
446    let mut l = 0;
447    while i & 1 == 1 {
448        l += 1;
449        i /= 2;
450    }
451    Level(l)
452}
453
454/// Return the list of root indices given a tree width.
455fn roots_of(Width(w): Width) -> Vec<Index> {
456    let mut base = 1;
457    let mut i = w * 2;
458    let mut basis = Vec::new();
459    while i > 0 {
460        if i & 1 == 1 {
461            basis.push(base)
462        }
463        base *= 2;
464        i /= 2;
465    }
466    let n = basis.len();
467    let mut roots = Vec::with_capacity(n);
468    base = 0;
469    for i in 0..n {
470        let x = basis[n - i - 1];
471        roots.push(Index(base + x / 2 - 1));
472        base += x;
473    }
474    roots
475}
476
477/// Get the start index and step size at the given level, such that the sequence of indices at this level is: `[start, start + step .. ]`
478fn at_level(Level(l): Level) -> (Index, u64) {
479    (Index((1 << l) - 1), 1 << (l + 1))
480}
481
482/// Return the parent of the given index.
483fn parent_of(index: Index) -> Index {
484    let Index(i) = index;
485    assert!(i != MAX_ROOT_INDEX, "max root has no parent");
486    let Level(l) = level_of(index);
487    let (Index(start), step) = at_level(Level(l));
488    let (Index(start_), step_) = at_level(Level(l + 1));
489    let pos = (i - start) / step;
490    Index(start_ + step_ * (pos / 2))
491}
492
493#[cfg(test)]
494/// Return the children of the given index.
495fn children_of(index: Index) -> Option<(Index, Index)> {
496    let Index(i) = index;
497    let Level(l) = level_of(index);
498    if l == 0 {
499        return None;
500    };
501    let (Index(start), step) = at_level(Level(l));
502    let (Index(start_), step_) = at_level(Level(l - 1));
503    let pos = (i - start) / step;
504    let left = start_ + pos * 2 * step_;
505    let right = i * 2 - left;
506    Some((Index(left), Index(right)))
507}
508
509#[cfg(test)]
510mod tests {
511    use super::*;
512
513    #[test]
514    fn test_tree_of() {
515        assert_eq!(
516            tree_of(Width::from(7))
517                .iter()
518                .map(|x| x.map(|x| usize::from(x) as i64).unwrap_or(-1))
519                .collect::<Vec<_>>(),
520            [0, 1, 0, 2, 0, 1, 0, -1, 0, 1, 0, -1, 0]
521        );
522    }
523
524    #[test]
525    fn test_level_of() {
526        assert_eq!(level_of(Index::from(23)), Level::from(3));
527    }
528
529    #[test]
530    fn test_roots_of() {
531        assert_eq!(
532            roots_of(Width::from(7)),
533            [Index::from(3), Index::from(9), Index::from(12)]
534        );
535    }
536
537    #[test]
538    fn test_at_level() {
539        assert_eq!(at_level(Level::from(1)), (Index::from(1), 4));
540        assert_eq!(at_level(Level::from(2)), (Index::from(3), 8));
541    }
542
543    #[test]
544    fn test_parent_of() {
545        assert_eq!(parent_of(Index::from(3)), Index::from(7));
546        assert_eq!(parent_of(Index::from(23)), Index::from(15));
547    }
548
549    #[test]
550    #[should_panic]
551    fn test_parent_of_out_of_bound() {
552        parent_of(Index::from(MAX_ROOT_INDEX));
553    }
554
555    #[test]
556    fn test_children_of() {
557        assert_eq!(
558            children_of(Index::from(3)),
559            Some((Index::from(1), Index::from(5)))
560        );
561        assert_eq!(children_of(Index::from(6)), None);
562        assert_eq!(
563            children_of(Index::from(5)),
564            Some((Index::from(4), Index::from(6)))
565        );
566        assert_eq!(
567            children_of(Index::from(9)),
568            Some((Index::from(8), Index::from(10)))
569        );
570        assert_eq!(children_of(Index::from(12)), None);
571    }
572
573    use std::cell::RefCell;
574
575    impl FlatStore<String> for RefCell<Vec<String>> {
576        fn write(&self, offset: u64, value: &String) {
577            self.borrow_mut()[offset as usize] = value.clone()
578        }
579        fn read(&self, offset: u64, value: &mut String) {
580            *value = self.borrow()[offset as usize].clone()
581        }
582    }
583
584    impl Merkleable for String {
585        fn zeros(i: usize) -> String {
586            let mut s = "".to_string();
587            for _ in 0..i {
588                s.push(',')
589            }
590            s
591        }
592        fn hash(&self, another: &String) -> String {
593            format!("{},{}", self, another)
594        }
595    }
596
597    #[test]
598    fn test_empty_tree() {
599        let max_size = 32;
600        let store: RefCell<Vec<String>> =
601            RefCell::new((0..max_size).map(|_| String::new()).collect());
602        let tree = FlatTree::new(&store, 0);
603        assert!(tree.iter().next().is_none());
604        assert!(tree.local_roots().is_empty());
605        assert!(tree.full_roots().is_empty());
606        assert!(tree.root().is_empty());
607        assert!(tree.local_path(3).next().is_none());
608        assert!(tree.full_roots().is_empty());
609    }
610
611    #[test]
612    fn test_tree_depth() {
613        let max_size = 32;
614        let store: RefCell<Vec<String>> =
615            RefCell::new((0..max_size).map(|_| String::new()).collect());
616        let mut tree = FlatTree::new(&store, 0);
617        assert_eq!(tree.depth(), 0);
618        tree.push("0".to_string());
619        assert_eq!(tree.depth(), 1);
620        tree.push("1".to_string());
621        assert_eq!(tree.depth(), 2);
622        tree.push("2".to_string());
623        assert_eq!(tree.depth(), 3);
624        tree.push("3".to_string());
625        assert_eq!(tree.depth(), 3);
626        tree.push("4".to_string());
627        assert_eq!(tree.depth(), 4);
628    }
629
630    #[test]
631    fn test_tree() {
632        assert_eq!(String::zeros(0), "");
633        assert_eq!(String::zeros(1), ",");
634        let start = |x: &str| Pos::Start(x.to_string());
635        let left = |x: &str| Pos::Left(x.to_string());
636        let right = |x: &str| Pos::Right(x.to_string());
637        let max_size = 32;
638        let store: RefCell<Vec<String>> =
639            RefCell::new((0..max_size).map(|_| "X".to_string()).collect());
640        let mut tree = FlatTree::new(&store, 0);
641        for i in 0..3 {
642            println!("++++++++++++++++ {}", i);
643            tree.push(format!("{}", i));
644            debug_print(&tree);
645        }
646        assert_eq!(
647            tree.full_path(2).collect::<Vec<_>>(),
648            [start("2"), right(""), left("0,1"),]
649        );
650        assert_eq!(
651            tree.full_path_from_node_index(3).collect::<Vec<_>>(),
652            [start("0,1,2,"),]
653        );
654
655        for i in 3..13 {
656            println!("++++++++++++++++ {}", i);
657            tree.push(format!("{}", i));
658            debug_print(&tree);
659        }
660        assert_eq!(tree.depth(), 5);
661        for (i, leaf) in tree.iter().enumerate() {
662            assert_eq!(leaf, format!("{}", i));
663        }
664        assert_eq!(tree.local_roots(), ["0,1,2,3,4,5,6,7", "8,9,10,11", "12"]);
665        assert_eq!(
666            tree.local_path(3).collect::<Vec<_>>(),
667            [start("3"), left("2"), left("0,1"), right("4,5,6,7")]
668        );
669        assert_eq!(
670            tree.local_path(10).collect::<Vec<_>>(),
671            [start("10"), right("11"), left("8,9")]
672        );
673        assert_eq!(tree.local_path(12).collect::<Vec<_>>(), [start("12")]);
674        assert_eq!(
675            tree.full_roots(),
676            [
677                (Index(15), "0,1,2,3,4,5,6,7,8,9,10,11,12,,,".to_string()),
678                (Index(23), "8,9,10,11,12,,,".to_string()),
679                (Index(27), "12,,,".to_string()),
680                (Index(25), "12,".to_string()),
681                (Index(24), "12".to_string()),
682            ]
683        );
684        assert_eq!(
685            tree.full_path(2).collect::<Vec<_>>(),
686            [
687                start("2"),
688                right("3"),
689                left("0,1"),
690                right("4,5,6,7"),
691                right("8,9,10,11,12,,,"),
692            ]
693        );
694        assert_eq!(
695            tree.full_path(3).collect::<Vec<_>>(),
696            [
697                start("3"),
698                left("2"),
699                left("0,1"),
700                right("4,5,6,7"),
701                right("8,9,10,11,12,,,"),
702            ]
703        );
704        assert_eq!(
705            tree.full_path(10).collect::<Vec<_>>(),
706            [
707                start("10"),
708                right("11"),
709                left("8,9"),
710                right("12,,,"),
711                left("0,1,2,3,4,5,6,7"),
712            ]
713        );
714        assert_eq!(
715            tree.full_path(12).collect::<Vec<_>>(),
716            [
717                start("12"),
718                right(""),
719                right(","),
720                left("8,9,10,11"),
721                left("0,1,2,3,4,5,6,7"),
722            ]
723        );
724        assert_eq!(
725            tree.full_path_from_node_index(3).collect::<Vec<_>>(),
726            [start("0,1,2,3"), right("4,5,6,7"), right("8,9,10,11,12,,,"),]
727        );
728        assert_eq!(
729            tree.full_path_from_node_index(9).collect::<Vec<_>>(),
730            [
731                start("4,5"),
732                right("6,7"),
733                left("0,1,2,3"),
734                right("8,9,10,11,12,,,"),
735            ]
736        );
737        assert_eq!(
738            tree.full_path_from_node_index(15).collect::<Vec<_>>(),
739            [start("0,1,2,3,4,5,6,7,8,9,10,11,12,,,"),]
740        );
741        assert_eq!(
742            tree.full_path_from_node_index(23).collect::<Vec<_>>(),
743            [start("8,9,10,11,12,,,"), left("0,1,2,3,4,5,6,7"),]
744        );
745        assert_eq!(
746            tree.full_path_from_node_index(24).collect::<Vec<_>>(),
747            [
748                start("12"),
749                right(""),
750                right(","),
751                left("8,9,10,11"),
752                left("0,1,2,3,4,5,6,7")
753            ]
754        );
755        assert_eq!(tree.full_path_from_node_index(26).collect::<Vec<_>>(), []);
756        assert_eq!(
757            tree.full_path_from_node_index(27).collect::<Vec<_>>(),
758            [start("12,,,"), left("8,9,10,11"), left("0,1,2,3,4,5,6,7")],
759        );
760    }
761
762    use proptest::prelude::*;
763
764    proptest! {
765      #[test]
766      fn test_merkle_path(n in 0..30, i in 0..30) {
767        let max_size = 64;
768        if i < n {
769            let store: RefCell<Vec<String>> =
770                RefCell::new((0..max_size).map(|_| String::new()).collect());
771            let mut tree = FlatTree::new(&store, 0);
772            for x in 0..(n as usize) {
773                tree.push(format!("{}", x))
774            };
775            let mut root = String::new();
776            for p in tree.full_path(i as u64) {
777                println!("p = {:?}", p);
778                match p {
779                    Pos::Start(x) => root = x,
780                    Pos::Left(x) => root = x.hash(&root),
781                    Pos::Right(x) => root = root.hash(&x),
782                }
783            }
784            prop_assert_eq!(tree.root(), root);
785        }
786      }
787    }
788}