1use super::TrieCursor;
2use crate::{BranchNodeCompact, Nibbles};
3use reth_storage_errors::db::DatabaseError;
4use std::{cmp::Ordering, iter::FusedIterator};
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 self.complete = true;
122 return Some(Err(err))
123 }
124 }
125 }
126}
127
128impl<C: TrieCursor> FusedIterator for DepthFirstTrieIterator<C> {}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133 use crate::trie_cursor::{mock::MockTrieCursorFactory, TrieCursorFactory};
134 use alloy_trie::TrieMask;
135 use std::{collections::BTreeMap, sync::Arc};
136
137 struct FailingTrieCursor;
139
140 impl TrieCursor for FailingTrieCursor {
141 fn seek_exact(
142 &mut self,
143 _key: Nibbles,
144 ) -> Result<Option<(Nibbles, BranchNodeCompact)>, DatabaseError> {
145 Err(DatabaseError::Other("test error".to_string()))
146 }
147
148 fn seek(
149 &mut self,
150 _key: Nibbles,
151 ) -> Result<Option<(Nibbles, BranchNodeCompact)>, DatabaseError> {
152 Err(DatabaseError::Other("test error".to_string()))
153 }
154
155 fn next(&mut self) -> Result<Option<(Nibbles, BranchNodeCompact)>, DatabaseError> {
156 Err(DatabaseError::Other("test error".to_string()))
157 }
158
159 fn current(&mut self) -> Result<Option<Nibbles>, DatabaseError> {
160 Err(DatabaseError::Other("test error".to_string()))
161 }
162
163 fn reset(&mut self) {}
164 }
165
166 fn create_test_node(state_nibbles: &[u8], tree_nibbles: &[u8]) -> BranchNodeCompact {
167 let mut state_mask = TrieMask::default();
168 for &nibble in state_nibbles {
169 state_mask.set_bit(nibble);
170 }
171
172 let mut tree_mask = TrieMask::default();
173 for &nibble in tree_nibbles {
174 tree_mask.set_bit(nibble);
175 }
176
177 BranchNodeCompact {
178 state_mask,
179 tree_mask,
180 hash_mask: TrieMask::default(),
181 hashes: Arc::new(vec![]),
182 root_hash: None,
183 }
184 }
185
186 #[test]
187 fn test_depth_first_cmp() {
188 let child = Nibbles::from_nibbles([0x1, 0x1]);
190 let parent = Nibbles::from_nibbles([0x1]);
191 assert_eq!(cmp(&child, &parent), Ordering::Less);
192 assert_eq!(cmp(&parent, &child), Ordering::Greater);
193
194 let deep = Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4]);
196 let ancestor = Nibbles::from_nibbles([0x1, 0x2]);
197 assert_eq!(cmp(&deep, &ancestor), Ordering::Less);
198 assert_eq!(cmp(&ancestor, &deep), Ordering::Greater);
199
200 let sibling1 = Nibbles::from_nibbles([0x1, 0x2]);
202 let sibling2 = Nibbles::from_nibbles([0x1, 0x3]);
203 assert_eq!(cmp(&sibling1, &sibling2), Ordering::Less);
204 assert_eq!(cmp(&sibling2, &sibling1), Ordering::Greater);
205
206 let branch1 = Nibbles::from_nibbles([0x1]);
208 let branch2 = Nibbles::from_nibbles([0x2]);
209 assert_eq!(cmp(&branch1, &branch2), Ordering::Less);
210 assert_eq!(cmp(&branch2, &branch1), Ordering::Greater);
211
212 let empty = Nibbles::new();
214 let non_empty = Nibbles::from_nibbles([0x0]);
215 assert_eq!(cmp(&non_empty, &empty), Ordering::Less);
216 assert_eq!(cmp(&empty, &non_empty), Ordering::Greater);
217
218 let same1 = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
220 let same2 = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
221 assert_eq!(cmp(&same1, &same2), Ordering::Equal);
222 }
223
224 #[test]
225 fn test_depth_first_ordering_complex() {
226 let mut paths = [
228 Nibbles::from_nibbles([0x1]), Nibbles::from_nibbles([0x2]), Nibbles::from_nibbles([0x1, 0x1]), Nibbles::from_nibbles([0x1, 0x2]), ];
233
234 paths.reverse();
236
237 paths.sort_by(cmp);
239
240 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])); }
246
247 #[test]
248 fn test_depth_first_ordering_tree() {
249 let mut paths = vec![
251 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]), ];
260
261 paths.reverse();
263
264 paths.sort_by(cmp);
266
267 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()); }
280
281 #[test]
282 fn test_empty_trie() {
283 let factory = MockTrieCursorFactory::new(BTreeMap::new(), Default::default());
284 let cursor = factory.account_trie_cursor().unwrap();
285 let mut iter = DepthFirstTrieIterator::new(cursor);
286 assert!(iter.next().is_none());
287 }
288
289 #[test]
290 fn test_single_node() {
291 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
292 let node = create_test_node(&[0x4], &[0x5]);
293
294 let mut nodes = BTreeMap::new();
295 nodes.insert(path, node.clone());
296 let factory = MockTrieCursorFactory::new(nodes, Default::default());
297 let cursor = factory.account_trie_cursor().unwrap();
298 let mut iter = DepthFirstTrieIterator::new(cursor);
299
300 let result = iter.next().unwrap().unwrap();
301 assert_eq!(result.0, path);
302 assert_eq!(result.1, node);
303 assert!(iter.next().is_none());
304 }
305
306 #[test]
307 fn test_depth_first_order() {
308 let nodes = vec![
317 (Nibbles::default(), create_test_node(&[], &[0x1, 0x2])),
319 (Nibbles::from_nibbles([0x1]), create_test_node(&[], &[0x2, 0x3])),
321 (Nibbles::from_nibbles([0x1, 0x2]), create_test_node(&[0xF], &[])),
323 (Nibbles::from_nibbles([0x1, 0x3]), create_test_node(&[0xF], &[])),
324 (Nibbles::from_nibbles([0x2]), create_test_node(&[], &[0x4])),
326 (Nibbles::from_nibbles([0x2, 0x4]), create_test_node(&[0xF], &[])),
328 ];
329
330 let nodes_map: BTreeMap<_, _> = nodes.into_iter().collect();
331 let factory = MockTrieCursorFactory::new(nodes_map, Default::default());
332 let cursor = factory.account_trie_cursor().unwrap();
333 let iter = DepthFirstTrieIterator::new(cursor);
334
335 let expected_order = vec![
344 Nibbles::from_nibbles([0x1, 0x2]),
345 Nibbles::from_nibbles([0x1, 0x3]),
346 Nibbles::from_nibbles([0x1]),
347 Nibbles::from_nibbles([0x2, 0x4]),
348 Nibbles::from_nibbles([0x2]),
349 Nibbles::default(),
350 ];
351
352 let mut actual_order = Vec::new();
353 for result in iter {
354 let (path, _) = result.unwrap();
355 actual_order.push(path);
356 }
357
358 assert_eq!(actual_order, expected_order);
359 }
360
361 #[test]
362 fn test_complex_tree() {
363 let nodes = vec![
365 (Nibbles::default(), create_test_node(&[], &[0x0, 0x5, 0xA, 0xF])),
367 (Nibbles::from_nibbles([0x0]), create_test_node(&[], &[0x1, 0x2])),
369 (Nibbles::from_nibbles([0x0, 0x1]), create_test_node(&[0x3], &[])),
370 (Nibbles::from_nibbles([0x0, 0x2]), create_test_node(&[0x4], &[])),
371 (Nibbles::from_nibbles([0x5]), create_test_node(&[0xB], &[])),
373 (Nibbles::from_nibbles([0xA]), create_test_node(&[], &[0xB])),
375 (Nibbles::from_nibbles([0xA, 0xB]), create_test_node(&[], &[0xC])),
376 (Nibbles::from_nibbles([0xA, 0xB, 0xC]), create_test_node(&[0xD], &[])),
377 (Nibbles::from_nibbles([0xF]), create_test_node(&[0xE], &[])),
379 ];
380
381 let nodes_map: BTreeMap<_, _> = nodes.into_iter().collect();
382 let factory = MockTrieCursorFactory::new(nodes_map, Default::default());
383 let cursor = factory.account_trie_cursor().unwrap();
384 let iter = DepthFirstTrieIterator::new(cursor);
385
386 let expected_order = vec![
388 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(), ];
398
399 let mut actual_order = Vec::new();
400 for result in iter {
401 let (path, _node) = result.unwrap();
402 actual_order.push(path);
403 }
404
405 assert_eq!(actual_order, expected_order);
406 }
407
408 #[test]
409 fn test_iterator_terminates_on_error() {
410 let mut iter = DepthFirstTrieIterator::new(FailingTrieCursor);
411
412 assert!(iter.next().unwrap().is_err());
414 assert!(iter.next().is_none());
416 }
417}