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()); }
279
280 #[test]
281 fn test_empty_trie() {
282 let factory = MockTrieCursorFactory::new(BTreeMap::new(), Default::default());
283 let cursor = factory.account_trie_cursor().unwrap();
284 let mut iter = DepthFirstTrieIterator::new(cursor);
285 assert!(iter.next().is_none());
286 }
287
288 #[test]
289 fn test_single_node() {
290 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
291 let node = create_test_node(&[0x4], &[0x5]);
292
293 let mut nodes = BTreeMap::new();
294 nodes.insert(path, node.clone());
295 let factory = MockTrieCursorFactory::new(nodes, Default::default());
296 let cursor = factory.account_trie_cursor().unwrap();
297 let mut iter = DepthFirstTrieIterator::new(cursor);
298
299 let result = iter.next().unwrap().unwrap();
300 assert_eq!(result.0, path);
301 assert_eq!(result.1, node);
302 assert!(iter.next().is_none());
303 }
304
305 #[test]
306 fn test_depth_first_order() {
307 let nodes = vec![
316 (Nibbles::default(), create_test_node(&[], &[0x1, 0x2])),
318 (Nibbles::from_nibbles([0x1]), create_test_node(&[], &[0x2, 0x3])),
320 (Nibbles::from_nibbles([0x1, 0x2]), create_test_node(&[0xF], &[])),
322 (Nibbles::from_nibbles([0x1, 0x3]), create_test_node(&[0xF], &[])),
323 (Nibbles::from_nibbles([0x2]), create_test_node(&[], &[0x4])),
325 (Nibbles::from_nibbles([0x2, 0x4]), create_test_node(&[0xF], &[])),
327 ];
328
329 let nodes_map: BTreeMap<_, _> = nodes.into_iter().collect();
330 let factory = MockTrieCursorFactory::new(nodes_map, Default::default());
331 let cursor = factory.account_trie_cursor().unwrap();
332 let iter = DepthFirstTrieIterator::new(cursor);
333
334 let expected_order = vec![
343 Nibbles::from_nibbles([0x1, 0x2]),
344 Nibbles::from_nibbles([0x1, 0x3]),
345 Nibbles::from_nibbles([0x1]),
346 Nibbles::from_nibbles([0x2, 0x4]),
347 Nibbles::from_nibbles([0x2]),
348 Nibbles::default(),
349 ];
350
351 let mut actual_order = Vec::new();
352 for result in iter {
353 let (path, _) = result.unwrap();
354 actual_order.push(path);
355 }
356
357 assert_eq!(actual_order, expected_order);
358 }
359
360 #[test]
361 fn test_complex_tree() {
362 let nodes = vec![
364 (Nibbles::default(), create_test_node(&[], &[0x0, 0x5, 0xA, 0xF])),
366 (Nibbles::from_nibbles([0x0]), create_test_node(&[], &[0x1, 0x2])),
368 (Nibbles::from_nibbles([0x0, 0x1]), create_test_node(&[0x3], &[])),
369 (Nibbles::from_nibbles([0x0, 0x2]), create_test_node(&[0x4], &[])),
370 (Nibbles::from_nibbles([0x5]), create_test_node(&[0xB], &[])),
372 (Nibbles::from_nibbles([0xA]), create_test_node(&[], &[0xB])),
374 (Nibbles::from_nibbles([0xA, 0xB]), create_test_node(&[], &[0xC])),
375 (Nibbles::from_nibbles([0xA, 0xB, 0xC]), create_test_node(&[0xD], &[])),
376 (Nibbles::from_nibbles([0xF]), create_test_node(&[0xE], &[])),
378 ];
379
380 let nodes_map: BTreeMap<_, _> = nodes.into_iter().collect();
381 let factory = MockTrieCursorFactory::new(nodes_map, Default::default());
382 let cursor = factory.account_trie_cursor().unwrap();
383 let iter = DepthFirstTrieIterator::new(cursor);
384
385 let expected_order = vec![
387 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(), ];
397
398 let mut actual_order = Vec::new();
399 for result in iter {
400 let (path, _node) = result.unwrap();
401 actual_order.push(path);
402 }
403
404 assert_eq!(actual_order, expected_order);
405 }
406
407 #[test]
408 fn test_iterator_terminates_on_error() {
409 let mut iter = DepthFirstTrieIterator::new(FailingTrieCursor);
410
411 assert!(iter.next().unwrap().is_err());
413 assert!(iter.next().is_none());
415 }
416}