fuel_merkle/common/
position_path.rs

1use crate::common::{
2    AsPathIterator,
3    Position,
4    node::Node,
5    path_iterator::PathIter,
6};
7
8use super::path::Side;
9
10/// # PositionPath
11///
12/// A PositionPath represents the path of positions created by traversing a
13/// binary tree from the root position to the leaf position. The shape of the
14/// tree determines path traversal, and can be described accurately by the
15/// number of leaves comprising the tree. For example, traversing to the fifth
16/// leaf of a balanced eight-leaf tree will generate a different path than
17/// traversing to the fifth leaf of an imbalanced five-leaf tree.
18///
19/// A PositionPath exposes an `iter()` method for performing iteration on this
20/// path. Each iteration returns a tuple containing the next position in the
21/// path and the corresponding side node. Because the tree may be imbalanced, as
22/// described by the path's `leaves_count` parameter, the side node may not
23/// necessarily be the direct sibling of the path node; rather, it can be a
24/// position at a lower spot in the tree altogether.
25pub struct PositionPath {
26    root: Position,
27    leaf: Position,
28    leaves_count: u64,
29}
30
31impl PositionPath {
32    pub fn new(root: Position, leaf: Position, leaves_count: u64) -> Self {
33        debug_assert!(leaves_count > 0);
34        Self {
35            root,
36            leaf,
37            leaves_count,
38        }
39    }
40
41    pub fn iter(self) -> PositionPathIter {
42        PositionPathIter::new(self.root, self.leaf, self.leaves_count)
43    }
44}
45
46pub struct PositionPathIter {
47    rightmost_position: Position,
48    current_side_node: Option<Position>,
49    path_iter: PathIter<Position>,
50}
51
52impl PositionPathIter {
53    /// Panics if leaves_count is zero, as the tree is not valid
54    pub fn new(root: Position, leaf: Position, leaves_count: u64) -> Self {
55        Self {
56            rightmost_position: Position::from_leaf_index(
57                leaves_count
58                    .checked_sub(1)
59                    .expect("Path to a tree without leaves"),
60            )
61            .unwrap(),
62            current_side_node: None,
63            path_iter: root.as_path_iter(&leaf.leaf_key()),
64        }
65    }
66}
67
68impl Iterator for PositionPathIter {
69    type Item = (Position, Position);
70
71    fn next(&mut self) -> Option<Self::Item> {
72        // Find the next set of path and side positions by iterating from the
73        // given root position to the given leaf position and evaluating each
74        // position against the tree described by the leaves count.
75        let iter = self.path_iter.by_ref().map(|(path, side)| {
76            // SAFETY: Path iteration over positions is infallible. Path
77            // positions and side positions are both guaranteed to be valid in
78            // this context.
79            (path.unwrap(), side.unwrap())
80        });
81        for (path, side) in iter {
82            let mut side = Position::from_in_order_index(side);
83            // To determine if the position is in the tree, we observe that the
84            // highest in-order index belongs to the tree's rightmost leaf
85            // position (as defined by the `leaves_count` parameter) and that
86            // all path nodes will have an in-order index less than or equal to
87            // the in-order index of this rightmost leaf position. If a path
88            // position has an in-order index greater than that of the rightmost
89            // leaf position, it is invalid in the context of this tree and must
90            // be discarded. However, the corresponding side node is valid (or
91            // is the ancestor of a valid side node) and represents the side
92            // node of a deeper path position that is also valid (i.e., has
93            // in-order index less than or equal to that of the rightmost leaf).
94            // We can save reference to it now so that we can generate the path
95            // node and side node pair later, once both nodes are encountered.
96            if path.in_order_index() <= self.rightmost_position.in_order_index() {
97                // If we previously encountered a side node corresponding to an
98                // invalid path node, we observe that the next valid path node
99                // always pairs with this side node. Once the path and side node
100                // have been paired, we continue to pair path and side nodes
101                // normally.
102                if let Some(node) = self.current_side_node.take() {
103                    side = node;
104                }
105
106                // A side node with an in-order index greater than the index of
107                // the rightmost leaf position is invalid and does not exist in
108                // the context of this tree. The invalid side node will always
109                // be the ancestor of the correct side node. Furthermore, the
110                // correct side node will always be a leftward descendent of
111                // this invalid side node.
112                while side.in_order_index() > self.rightmost_position.in_order_index() {
113                    side = side.child(Side::Left).expect("Verified above");
114                }
115
116                return Some((path, side))
117            } else {
118                // If the path node is invalid, save reference to the
119                // corresponding side node.
120                if self.current_side_node.is_none() {
121                    self.current_side_node = Some(side);
122                }
123            }
124        }
125
126        None
127    }
128}
129
130#[cfg(test)]
131mod test {
132    use crate::common::Position;
133    use alloc::vec::Vec;
134
135    #[test]
136    fn test_path_set_returns_path_and_side_nodes_for_1_leaf() {
137        let root = Position::from_in_order_index(0);
138        let leaf = Position::from_leaf_index_unwrap(0);
139        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
140            root.path(&leaf, 1).iter().unzip();
141        let expected_path = [Position::from_in_order_index(0)];
142        let expected_side = [Position::from_in_order_index(0)];
143        assert_eq!(path_positions, expected_path);
144        assert_eq!(side_positions, expected_side);
145    }
146
147    #[test]
148    fn test_path_set_returns_path_and_side_nodes_for_4_leaves() {
149        //       03
150        //      /  \
151        //     /    \
152        //   01      05
153        //  /  \    /  \
154        // 00  02  04  06
155        // 00  01  02  03
156
157        let root = Position::from_in_order_index(3);
158
159        let leaf = Position::from_leaf_index_unwrap(0);
160        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
161            root.path(&leaf, 4).iter().unzip();
162        let expected_path = [
163            Position::from_in_order_index(3),
164            Position::from_in_order_index(1),
165            Position::from_in_order_index(0),
166        ];
167        let expected_side = [
168            Position::from_in_order_index(3),
169            Position::from_in_order_index(5),
170            Position::from_in_order_index(2),
171        ];
172        assert_eq!(path_positions, expected_path);
173        assert_eq!(side_positions, expected_side);
174
175        let leaf = Position::from_leaf_index_unwrap(1);
176        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
177            root.path(&leaf, 4).iter().unzip();
178        let expected_path = [
179            Position::from_in_order_index(3),
180            Position::from_in_order_index(1),
181            Position::from_in_order_index(2),
182        ];
183        let expected_side = [
184            Position::from_in_order_index(3),
185            Position::from_in_order_index(5),
186            Position::from_in_order_index(0),
187        ];
188        assert_eq!(path_positions, expected_path);
189        assert_eq!(side_positions, expected_side);
190
191        let leaf = Position::from_leaf_index_unwrap(2);
192        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
193            root.path(&leaf, 4).iter().unzip();
194        let expected_path = [
195            Position::from_in_order_index(3),
196            Position::from_in_order_index(5),
197            Position::from_in_order_index(4),
198        ];
199        let expected_side = [
200            Position::from_in_order_index(3),
201            Position::from_in_order_index(1),
202            Position::from_in_order_index(6),
203        ];
204        assert_eq!(path_positions, expected_path);
205        assert_eq!(side_positions, expected_side);
206
207        let leaf = Position::from_leaf_index_unwrap(3);
208        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
209            root.path(&leaf, 4).iter().unzip();
210        let expected_path = [
211            Position::from_in_order_index(3),
212            Position::from_in_order_index(5),
213            Position::from_in_order_index(6),
214        ];
215        let expected_side = [
216            Position::from_in_order_index(3),
217            Position::from_in_order_index(1),
218            Position::from_in_order_index(4),
219        ];
220        assert_eq!(path_positions, expected_path);
221        assert_eq!(side_positions, expected_side);
222    }
223
224    #[test]
225    fn test_path_set_returns_path_and_side_nodes_for_5_leaves() {
226        //          07
227        //         /  \
228        //       03    \
229        //      /  \    \
230        //     /    \    \
231        //   01      05   \
232        //  /  \    /  \   \
233        // 00  02  04  06  08
234        // 00  01  02  03  04
235
236        let root = Position::from_in_order_index(7);
237
238        let leaf = Position::from_leaf_index_unwrap(0);
239        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
240            root.path(&leaf, 5).iter().unzip();
241        let expected_path = [
242            Position::from_in_order_index(7),
243            Position::from_in_order_index(3),
244            Position::from_in_order_index(1),
245            Position::from_in_order_index(0),
246        ];
247        let expected_side = [
248            Position::from_in_order_index(7),
249            Position::from_in_order_index(8),
250            Position::from_in_order_index(5),
251            Position::from_in_order_index(2),
252        ];
253        assert_eq!(path_positions, expected_path);
254        assert_eq!(side_positions, expected_side);
255
256        let leaf = Position::from_leaf_index_unwrap(1);
257        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
258            root.path(&leaf, 5).iter().unzip();
259        let expected_path = [
260            Position::from_in_order_index(7),
261            Position::from_in_order_index(3),
262            Position::from_in_order_index(1),
263            Position::from_in_order_index(2),
264        ];
265        let expected_side = [
266            Position::from_in_order_index(7),
267            Position::from_in_order_index(8),
268            Position::from_in_order_index(5),
269            Position::from_in_order_index(0),
270        ];
271        assert_eq!(path_positions, expected_path);
272        assert_eq!(side_positions, expected_side);
273
274        let leaf = Position::from_leaf_index_unwrap(2);
275        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
276            root.path(&leaf, 5).iter().unzip();
277        let expected_path = [
278            Position::from_in_order_index(7),
279            Position::from_in_order_index(3),
280            Position::from_in_order_index(5),
281            Position::from_in_order_index(4),
282        ];
283        let expected_side = [
284            Position::from_in_order_index(7),
285            Position::from_in_order_index(8),
286            Position::from_in_order_index(1),
287            Position::from_in_order_index(6),
288        ];
289        assert_eq!(path_positions, expected_path);
290        assert_eq!(side_positions, expected_side);
291
292        let leaf = Position::from_leaf_index_unwrap(3);
293        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
294            root.path(&leaf, 5).iter().unzip();
295        let expected_path = [
296            Position::from_in_order_index(7),
297            Position::from_in_order_index(3),
298            Position::from_in_order_index(5),
299            Position::from_in_order_index(6),
300        ];
301        let expected_side = [
302            Position::from_in_order_index(7),
303            Position::from_in_order_index(8),
304            Position::from_in_order_index(1),
305            Position::from_in_order_index(4),
306        ];
307        assert_eq!(path_positions, expected_path);
308        assert_eq!(side_positions, expected_side);
309
310        let leaf = Position::from_leaf_index_unwrap(4);
311        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
312            root.path(&leaf, 5).iter().unzip();
313        let expected_path = [
314            Position::from_in_order_index(7),
315            Position::from_in_order_index(8),
316        ];
317        let expected_side = [
318            Position::from_in_order_index(7),
319            Position::from_in_order_index(3),
320        ];
321        assert_eq!(path_positions, expected_path);
322        assert_eq!(side_positions, expected_side);
323    }
324
325    #[test]
326    fn test_path_set_returns_path_and_side_nodes_for_6_leaves() {
327        //            07
328        //           /  \
329        //          /    \
330        //         /      \
331        //       03        \
332        //      /  \        \
333        //     /    \        \
334        //   01      05      09
335        //  /  \    /  \    /  \
336        // 00  02  04  06  08  10
337        // 00  01  02  03  04  05
338
339        let root = Position::from_in_order_index(7);
340
341        let leaf = Position::from_leaf_index_unwrap(0);
342        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
343            root.path(&leaf, 6).iter().unzip();
344        let expected_path = [
345            Position::from_in_order_index(7),
346            Position::from_in_order_index(3),
347            Position::from_in_order_index(1),
348            Position::from_in_order_index(0),
349        ];
350        let expected_side = [
351            Position::from_in_order_index(7),
352            Position::from_in_order_index(9),
353            Position::from_in_order_index(5),
354            Position::from_in_order_index(2),
355        ];
356        assert_eq!(path_positions, expected_path);
357        assert_eq!(side_positions, expected_side);
358
359        let leaf = Position::from_leaf_index_unwrap(1);
360        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
361            root.path(&leaf, 6).iter().unzip();
362        let expected_path = [
363            Position::from_in_order_index(7),
364            Position::from_in_order_index(3),
365            Position::from_in_order_index(1),
366            Position::from_in_order_index(2),
367        ];
368        let expected_side = [
369            Position::from_in_order_index(7),
370            Position::from_in_order_index(9),
371            Position::from_in_order_index(5),
372            Position::from_in_order_index(0),
373        ];
374        assert_eq!(path_positions, expected_path);
375        assert_eq!(side_positions, expected_side);
376
377        let leaf = Position::from_leaf_index_unwrap(2);
378        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
379            root.path(&leaf, 6).iter().unzip();
380        let expected_path = [
381            Position::from_in_order_index(7),
382            Position::from_in_order_index(3),
383            Position::from_in_order_index(5),
384            Position::from_in_order_index(4),
385        ];
386        let expected_side = [
387            Position::from_in_order_index(7),
388            Position::from_in_order_index(9),
389            Position::from_in_order_index(1),
390            Position::from_in_order_index(6),
391        ];
392        assert_eq!(path_positions, expected_path);
393        assert_eq!(side_positions, expected_side);
394
395        let leaf = Position::from_leaf_index_unwrap(3);
396        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
397            root.path(&leaf, 6).iter().unzip();
398        let expected_path = [
399            Position::from_in_order_index(7),
400            Position::from_in_order_index(3),
401            Position::from_in_order_index(5),
402            Position::from_in_order_index(6),
403        ];
404        let expected_side = [
405            Position::from_in_order_index(7),
406            Position::from_in_order_index(9),
407            Position::from_in_order_index(1),
408            Position::from_in_order_index(4),
409        ];
410        assert_eq!(path_positions, expected_path);
411        assert_eq!(side_positions, expected_side);
412
413        let leaf = Position::from_leaf_index_unwrap(4);
414        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
415            root.path(&leaf, 6).iter().unzip();
416        let expected_path = [
417            Position::from_in_order_index(7),
418            Position::from_in_order_index(9),
419            Position::from_in_order_index(8),
420        ];
421        let expected_side = [
422            Position::from_in_order_index(7),
423            Position::from_in_order_index(3),
424            Position::from_in_order_index(10),
425        ];
426        assert_eq!(path_positions, expected_path);
427        assert_eq!(side_positions, expected_side);
428
429        let leaf = Position::from_leaf_index_unwrap(5);
430        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
431            root.path(&leaf, 6).iter().unzip();
432        let expected_path = [
433            Position::from_in_order_index(7),
434            Position::from_in_order_index(9),
435            Position::from_in_order_index(10),
436        ];
437        let expected_side = [
438            Position::from_in_order_index(7),
439            Position::from_in_order_index(3),
440            Position::from_in_order_index(8),
441        ];
442        assert_eq!(path_positions, expected_path);
443        assert_eq!(side_positions, expected_side);
444    }
445
446    #[test]
447    fn test_path_set_returns_path_and_side_nodes_for_7_leaves() {
448        //               07
449        //              /  \
450        //             /    \
451        //            /      \
452        //           /        \
453        //          /          \
454        //         /            \
455        //       03              11
456        //      /  \            /  \
457        //     /    \          /    \
458        //   01      05      09      \
459        //  /  \    /  \    /  \      \
460        // 00  02  04  06  08  10     12
461        // 00  01  02  03  04  05     06
462
463        let root = Position::from_in_order_index(7);
464
465        let leaf = Position::from_leaf_index_unwrap(0);
466        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
467            root.path(&leaf, 7).iter().unzip();
468        let expected_path = [
469            Position::from_in_order_index(7),
470            Position::from_in_order_index(3),
471            Position::from_in_order_index(1),
472            Position::from_in_order_index(0),
473        ];
474        let expected_side = [
475            Position::from_in_order_index(7),
476            Position::from_in_order_index(11),
477            Position::from_in_order_index(5),
478            Position::from_in_order_index(2),
479        ];
480        assert_eq!(path_positions, expected_path);
481        assert_eq!(side_positions, expected_side);
482
483        let leaf = Position::from_leaf_index_unwrap(1);
484        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
485            root.path(&leaf, 7).iter().unzip();
486        let expected_path = [
487            Position::from_in_order_index(7),
488            Position::from_in_order_index(3),
489            Position::from_in_order_index(1),
490            Position::from_in_order_index(2),
491        ];
492        let expected_side = [
493            Position::from_in_order_index(7),
494            Position::from_in_order_index(11),
495            Position::from_in_order_index(5),
496            Position::from_in_order_index(0),
497        ];
498        assert_eq!(path_positions, expected_path);
499        assert_eq!(side_positions, expected_side);
500
501        let leaf = Position::from_leaf_index_unwrap(2);
502        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
503            root.path(&leaf, 7).iter().unzip();
504        let expected_path = [
505            Position::from_in_order_index(7),
506            Position::from_in_order_index(3),
507            Position::from_in_order_index(5),
508            Position::from_in_order_index(4),
509        ];
510        let expected_side = [
511            Position::from_in_order_index(7),
512            Position::from_in_order_index(11),
513            Position::from_in_order_index(1),
514            Position::from_in_order_index(6),
515        ];
516        assert_eq!(path_positions, expected_path);
517        assert_eq!(side_positions, expected_side);
518
519        let leaf = Position::from_leaf_index_unwrap(3);
520        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
521            root.path(&leaf, 7).iter().unzip();
522        let expected_path = [
523            Position::from_in_order_index(7),
524            Position::from_in_order_index(3),
525            Position::from_in_order_index(5),
526            Position::from_in_order_index(6),
527        ];
528        let expected_side = [
529            Position::from_in_order_index(7),
530            Position::from_in_order_index(11),
531            Position::from_in_order_index(1),
532            Position::from_in_order_index(4),
533        ];
534        assert_eq!(path_positions, expected_path);
535        assert_eq!(side_positions, expected_side);
536
537        let leaf = Position::from_leaf_index_unwrap(4);
538        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
539            root.path(&leaf, 7).iter().unzip();
540        let expected_path = [
541            Position::from_in_order_index(7),
542            Position::from_in_order_index(11),
543            Position::from_in_order_index(9),
544            Position::from_in_order_index(8),
545        ];
546        let expected_side = [
547            Position::from_in_order_index(7),
548            Position::from_in_order_index(3),
549            Position::from_in_order_index(12),
550            Position::from_in_order_index(10),
551        ];
552        assert_eq!(path_positions, expected_path);
553        assert_eq!(side_positions, expected_side);
554
555        let leaf = Position::from_leaf_index_unwrap(5);
556        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
557            root.path(&leaf, 7).iter().unzip();
558        let expected_path = [
559            Position::from_in_order_index(7),
560            Position::from_in_order_index(11),
561            Position::from_in_order_index(9),
562            Position::from_in_order_index(10),
563        ];
564        let expected_side = [
565            Position::from_in_order_index(7),
566            Position::from_in_order_index(3),
567            Position::from_in_order_index(12),
568            Position::from_in_order_index(8),
569        ];
570        assert_eq!(path_positions, expected_path);
571        assert_eq!(side_positions, expected_side);
572
573        let leaf = Position::from_leaf_index_unwrap(6);
574        let (path_positions, side_positions): (Vec<Position>, Vec<Position>) =
575            root.path(&leaf, 7).iter().unzip();
576        let expected_path = [
577            Position::from_in_order_index(7),
578            Position::from_in_order_index(11),
579            Position::from_in_order_index(12),
580        ];
581        let expected_side = [
582            Position::from_in_order_index(7),
583            Position::from_in_order_index(3),
584            Position::from_in_order_index(9),
585        ];
586        assert_eq!(path_positions, expected_path);
587        assert_eq!(side_positions, expected_side);
588    }
589}