1use super::TrieCursor;
2use crate::{BranchNodeCompact, Nibbles};
3use reth_storage_errors::db::DatabaseError;
4use std::cmp::Ordering;
5use tracing::trace;
6
7pub fn cmp(a: &Nibbles, b: &Nibbles) -> Ordering {
11 reth_trie_common::depth_first_cmp(a, b)
12}
13
14#[derive(Debug)]
20pub struct DepthFirstTrieIterator<C: TrieCursor> {
21 cursor: C,
23 initialized: bool,
25 stack: Vec<(Nibbles, BranchNodeCompact)>,
27 next: Vec<(Nibbles, BranchNodeCompact)>,
29 complete: bool,
31}
32
33impl<C: TrieCursor> DepthFirstTrieIterator<C> {
34 pub fn new(cursor: C) -> Self {
36 Self {
37 cursor,
38 initialized: false,
39 stack: Default::default(),
40 next: Default::default(),
41 complete: false,
42 }
43 }
44
45 fn push(&mut self, path: Nibbles, node: BranchNodeCompact) {
46 loop {
47 match self.stack.last() {
48 None => {
49 self.stack.push((path, node));
52 break
53 }
54 Some((top_path, _)) if path.starts_with(top_path) => {
55 self.stack.push((path, node));
59 break
60 }
61 Some((_, _)) => {
62 self.next.push(self.stack.pop().expect("stack is not empty"));
66 }
67 }
68 }
69
70 self.next.reverse();
73 }
74
75 fn fill_next(&mut self) -> Result<(), DatabaseError> {
76 debug_assert!(self.next.is_empty());
77
78 loop {
79 let Some((path, node)) = (if self.initialized {
80 self.cursor.next()?
81 } else {
82 self.initialized = true;
83 self.cursor.seek(Nibbles::new())?
84 }) else {
85 self.complete = true;
89 self.next = core::mem::take(&mut self.stack);
90 return Ok(())
91 };
92
93 trace!(
94 target: "trie::trie_cursor::depth_first",
95 ?path,
96 "Iterated from cursor",
97 );
98
99 self.push(path, node);
100 if !self.next.is_empty() {
101 return Ok(())
102 }
103 }
104 }
105}
106
107impl<C: TrieCursor> Iterator for DepthFirstTrieIterator<C> {
108 type Item = Result<(Nibbles, BranchNodeCompact), DatabaseError>;
109
110 fn next(&mut self) -> Option<Self::Item> {
111 loop {
112 if let Some(next) = self.next.pop() {
113 return Some(Ok(next))
114 }
115
116 if self.complete {
117 return None
118 }
119
120 if let Err(err) = self.fill_next() {
121 return Some(Err(err))
122 }
123 }
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use crate::trie_cursor::{mock::MockTrieCursorFactory, TrieCursorFactory};
131 use alloy_trie::TrieMask;
132 use std::{collections::BTreeMap, sync::Arc};
133
134 fn create_test_node(state_nibbles: &[u8], tree_nibbles: &[u8]) -> BranchNodeCompact {
135 let mut state_mask = TrieMask::default();
136 for &nibble in state_nibbles {
137 state_mask.set_bit(nibble);
138 }
139
140 let mut tree_mask = TrieMask::default();
141 for &nibble in tree_nibbles {
142 tree_mask.set_bit(nibble);
143 }
144
145 BranchNodeCompact {
146 state_mask,
147 tree_mask,
148 hash_mask: TrieMask::default(),
149 hashes: Arc::new(vec![]),
150 root_hash: None,
151 }
152 }
153
154 #[test]
155 fn test_depth_first_cmp() {
156 let child = Nibbles::from_nibbles([0x1, 0x1]);
158 let parent = Nibbles::from_nibbles([0x1]);
159 assert_eq!(cmp(&child, &parent), Ordering::Less);
160 assert_eq!(cmp(&parent, &child), Ordering::Greater);
161
162 let deep = Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4]);
164 let ancestor = Nibbles::from_nibbles([0x1, 0x2]);
165 assert_eq!(cmp(&deep, &ancestor), Ordering::Less);
166 assert_eq!(cmp(&ancestor, &deep), Ordering::Greater);
167
168 let sibling1 = Nibbles::from_nibbles([0x1, 0x2]);
170 let sibling2 = Nibbles::from_nibbles([0x1, 0x3]);
171 assert_eq!(cmp(&sibling1, &sibling2), Ordering::Less);
172 assert_eq!(cmp(&sibling2, &sibling1), Ordering::Greater);
173
174 let branch1 = Nibbles::from_nibbles([0x1]);
176 let branch2 = Nibbles::from_nibbles([0x2]);
177 assert_eq!(cmp(&branch1, &branch2), Ordering::Less);
178 assert_eq!(cmp(&branch2, &branch1), Ordering::Greater);
179
180 let empty = Nibbles::new();
182 let non_empty = Nibbles::from_nibbles([0x0]);
183 assert_eq!(cmp(&non_empty, &empty), Ordering::Less);
184 assert_eq!(cmp(&empty, &non_empty), Ordering::Greater);
185
186 let same1 = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
188 let same2 = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
189 assert_eq!(cmp(&same1, &same2), Ordering::Equal);
190 }
191
192 #[test]
193 fn test_depth_first_ordering_complex() {
194 let mut paths = [
196 Nibbles::from_nibbles([0x1]), Nibbles::from_nibbles([0x2]), Nibbles::from_nibbles([0x1, 0x1]), Nibbles::from_nibbles([0x1, 0x2]), ];
201
202 paths.reverse();
204
205 paths.sort_by(cmp);
207
208 assert_eq!(paths[0], Nibbles::from_nibbles([0x1, 0x1])); assert_eq!(paths[1], Nibbles::from_nibbles([0x1, 0x2])); assert_eq!(paths[2], Nibbles::from_nibbles([0x1])); assert_eq!(paths[3], Nibbles::from_nibbles([0x2])); }
214
215 #[test]
216 fn test_depth_first_ordering_tree() {
217 let mut paths = vec![
219 Nibbles::new(), Nibbles::from_nibbles([0x1]), Nibbles::from_nibbles([0x1, 0x1]), Nibbles::from_nibbles([0x1, 0x1, 0x1]), Nibbles::from_nibbles([0x1, 0x1, 0x2]), Nibbles::from_nibbles([0x1, 0x2]), Nibbles::from_nibbles([0x2]), Nibbles::from_nibbles([0x2, 0x1]), ];
228
229 paths.reverse();
231
232 paths.sort_by(cmp);
234
235 assert_eq!(paths[0], Nibbles::from_nibbles([0x1, 0x1, 0x1])); assert_eq!(paths[1], Nibbles::from_nibbles([0x1, 0x1, 0x2])); assert_eq!(paths[2], Nibbles::from_nibbles([0x1, 0x1])); assert_eq!(paths[3], Nibbles::from_nibbles([0x1, 0x2])); assert_eq!(paths[4], Nibbles::from_nibbles([0x1])); assert_eq!(paths[5], Nibbles::from_nibbles([0x2, 0x1])); assert_eq!(paths[6], Nibbles::from_nibbles([0x2])); assert_eq!(paths[7], Nibbles::new()); }
247
248 #[test]
249 fn test_empty_trie() {
250 let factory = MockTrieCursorFactory::new(BTreeMap::new(), Default::default());
251 let cursor = factory.account_trie_cursor().unwrap();
252 let mut iter = DepthFirstTrieIterator::new(cursor);
253 assert!(iter.next().is_none());
254 }
255
256 #[test]
257 fn test_single_node() {
258 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
259 let node = create_test_node(&[0x4], &[0x5]);
260
261 let mut nodes = BTreeMap::new();
262 nodes.insert(path, node.clone());
263 let factory = MockTrieCursorFactory::new(nodes, Default::default());
264 let cursor = factory.account_trie_cursor().unwrap();
265 let mut iter = DepthFirstTrieIterator::new(cursor);
266
267 let result = iter.next().unwrap().unwrap();
268 assert_eq!(result.0, path);
269 assert_eq!(result.1, node);
270 assert!(iter.next().is_none());
271 }
272
273 #[test]
274 fn test_depth_first_order() {
275 let nodes = vec![
284 (Nibbles::default(), create_test_node(&[], &[0x1, 0x2])),
286 (Nibbles::from_nibbles([0x1]), create_test_node(&[], &[0x2, 0x3])),
288 (Nibbles::from_nibbles([0x1, 0x2]), create_test_node(&[0xF], &[])),
290 (Nibbles::from_nibbles([0x1, 0x3]), create_test_node(&[0xF], &[])),
291 (Nibbles::from_nibbles([0x2]), create_test_node(&[], &[0x4])),
293 (Nibbles::from_nibbles([0x2, 0x4]), create_test_node(&[0xF], &[])),
295 ];
296
297 let nodes_map: BTreeMap<_, _> = nodes.into_iter().collect();
298 let factory = MockTrieCursorFactory::new(nodes_map, Default::default());
299 let cursor = factory.account_trie_cursor().unwrap();
300 let iter = DepthFirstTrieIterator::new(cursor);
301
302 let expected_order = vec![
311 Nibbles::from_nibbles([0x1, 0x2]),
312 Nibbles::from_nibbles([0x1, 0x3]),
313 Nibbles::from_nibbles([0x1]),
314 Nibbles::from_nibbles([0x2, 0x4]),
315 Nibbles::from_nibbles([0x2]),
316 Nibbles::default(),
317 ];
318
319 let mut actual_order = Vec::new();
320 for result in iter {
321 let (path, _) = result.unwrap();
322 actual_order.push(path);
323 }
324
325 assert_eq!(actual_order, expected_order);
326 }
327
328 #[test]
329 fn test_complex_tree() {
330 let nodes = vec![
332 (Nibbles::default(), create_test_node(&[], &[0x0, 0x5, 0xA, 0xF])),
334 (Nibbles::from_nibbles([0x0]), create_test_node(&[], &[0x1, 0x2])),
336 (Nibbles::from_nibbles([0x0, 0x1]), create_test_node(&[0x3], &[])),
337 (Nibbles::from_nibbles([0x0, 0x2]), create_test_node(&[0x4], &[])),
338 (Nibbles::from_nibbles([0x5]), create_test_node(&[0xB], &[])),
340 (Nibbles::from_nibbles([0xA]), create_test_node(&[], &[0xB])),
342 (Nibbles::from_nibbles([0xA, 0xB]), create_test_node(&[], &[0xC])),
343 (Nibbles::from_nibbles([0xA, 0xB, 0xC]), create_test_node(&[0xD], &[])),
344 (Nibbles::from_nibbles([0xF]), create_test_node(&[0xE], &[])),
346 ];
347
348 let nodes_map: BTreeMap<_, _> = nodes.into_iter().collect();
349 let factory = MockTrieCursorFactory::new(nodes_map, Default::default());
350 let cursor = factory.account_trie_cursor().unwrap();
351 let iter = DepthFirstTrieIterator::new(cursor);
352
353 let expected_order = vec![
355 Nibbles::from_nibbles([0x0, 0x1]), Nibbles::from_nibbles([0x0, 0x2]), Nibbles::from_nibbles([0x0]), Nibbles::from_nibbles([0x5]), Nibbles::from_nibbles([0xA, 0xB, 0xC]), Nibbles::from_nibbles([0xA, 0xB]), Nibbles::from_nibbles([0xA]), Nibbles::from_nibbles([0xF]), Nibbles::default(), ];
365
366 let mut actual_order = Vec::new();
367 for result in iter {
368 let (path, _node) = result.unwrap();
369 actual_order.push(path);
370 }
371
372 assert_eq!(actual_order, expected_order);
373 }
374}