1use crate::{
2 hashed_cursor::{HashedCursor, HashedCursorFactory},
3 progress::{IntermediateStateRootState, StateRootProgress},
4 trie::StateRoot,
5 trie_cursor::{
6 depth_first::{self, DepthFirstTrieIterator},
7 noop::NoopTrieCursorFactory,
8 TrieCursor, TrieCursorFactory,
9 },
10 Nibbles,
11};
12use alloy_primitives::B256;
13use alloy_trie::BranchNodeCompact;
14use reth_execution_errors::StateRootError;
15use reth_storage_errors::db::DatabaseError;
16use std::cmp::{Ordering, Reverse};
17use tracing::trace;
18
19#[derive(Debug)]
21enum BranchNode {
22 Account(Nibbles, BranchNodeCompact),
23 Storage(B256, Nibbles, BranchNodeCompact),
24}
25
26#[derive(Debug)]
38struct StateRootBranchNodesIter<H> {
39 hashed_cursor_factory: H,
40 account_nodes: Vec<(Nibbles, BranchNodeCompact)>,
41 storage_tries: Vec<(B256, Vec<(Nibbles, BranchNodeCompact)>)>,
42 curr_storage: Option<(B256, Vec<(Nibbles, BranchNodeCompact)>)>,
43 intermediate_state: Option<Box<IntermediateStateRootState>>,
44 complete: bool,
45}
46
47impl<H> StateRootBranchNodesIter<H> {
48 fn new(hashed_cursor_factory: H) -> Self {
49 Self {
50 hashed_cursor_factory,
51 account_nodes: Default::default(),
52 storage_tries: Default::default(),
53 curr_storage: None,
54 intermediate_state: None,
55 complete: false,
56 }
57 }
58
59 fn sort_updates(updates: &mut [(Nibbles, BranchNodeCompact)]) {
65 updates.sort_unstable_by(|a, b| depth_first::cmp(&b.0, &a.0));
66 }
67}
68
69impl<H: HashedCursorFactory + Clone> Iterator for StateRootBranchNodesIter<H> {
70 type Item = Result<BranchNode, StateRootError>;
71
72 fn next(&mut self) -> Option<Self::Item> {
73 loop {
74 if let Some((account, storage_updates)) = self.curr_storage.as_mut() &&
77 let Some((path, node)) = storage_updates.pop()
78 {
79 let node = BranchNode::Storage(*account, path, node);
80 return Some(Ok(node))
81 }
82
83 if let Some((account, storage_updates)) = self.storage_tries.pop() {
86 debug_assert!(!storage_updates.is_empty());
87
88 self.curr_storage = Some((account, storage_updates));
89 continue;
90 }
91
92 if let Some((path, node)) = self.account_nodes.pop() {
94 return Some(Ok(BranchNode::Account(path, node)))
95 }
96
97 if self.complete {
101 return None
102 }
103
104 let state_root =
105 StateRoot::new(NoopTrieCursorFactory, self.hashed_cursor_factory.clone())
106 .with_intermediate_state(self.intermediate_state.take().map(|s| *s));
107
108 let updates = match state_root.root_with_progress() {
109 Err(err) => return Some(Err(err)),
110 Ok(StateRootProgress::Complete(_, _, updates)) => {
111 self.complete = true;
112 updates
113 }
114 Ok(StateRootProgress::Progress(intermediate_state, _, updates)) => {
115 self.intermediate_state = Some(intermediate_state);
116 updates
117 }
118 };
119
120 self.account_nodes.extend(updates.account_nodes);
123 Self::sort_updates(&mut self.account_nodes);
124
125 self.storage_tries = updates
126 .storage_tries
127 .into_iter()
128 .filter_map(|(account, t)| {
129 (!t.storage_nodes.is_empty()).then(|| {
130 let mut storage_nodes = t.storage_nodes.into_iter().collect::<Vec<_>>();
131 Self::sort_updates(&mut storage_nodes);
132 (account, storage_nodes)
133 })
134 })
135 .collect::<Vec<_>>();
136
137 self.storage_tries.sort_unstable_by_key(|a| Reverse(a.0));
145
146 }
148 }
149}
150
151#[derive(Debug, Clone, PartialEq, Eq)]
155pub enum Output {
156 AccountExtra(Nibbles, BranchNodeCompact),
158 StorageExtra(B256, Nibbles, BranchNodeCompact),
160 AccountWrong {
162 path: Nibbles,
164 expected: BranchNodeCompact,
166 found: BranchNodeCompact,
168 },
169 StorageWrong {
171 account: B256,
173 path: Nibbles,
175 expected: BranchNodeCompact,
177 found: BranchNodeCompact,
179 },
180 AccountMissing(Nibbles, BranchNodeCompact),
182 StorageMissing(B256, Nibbles, BranchNodeCompact),
184 Progress(Nibbles),
186}
187
188#[derive(Debug)]
191struct SingleVerifier<I> {
192 account: Option<B256>, trie_iter: I,
194 curr: Option<(Nibbles, BranchNodeCompact)>,
195}
196
197impl<C: TrieCursor> SingleVerifier<DepthFirstTrieIterator<C>> {
198 fn new(account: Option<B256>, trie_cursor: C) -> Result<Self, DatabaseError> {
199 let mut trie_iter = DepthFirstTrieIterator::new(trie_cursor);
200 let curr = trie_iter.next().transpose()?;
201 Ok(Self { account, trie_iter, curr })
202 }
203
204 const fn output_extra(&self, path: Nibbles, node: BranchNodeCompact) -> Output {
205 if let Some(account) = self.account {
206 Output::StorageExtra(account, path, node)
207 } else {
208 Output::AccountExtra(path, node)
209 }
210 }
211
212 const fn output_wrong(
213 &self,
214 path: Nibbles,
215 expected: BranchNodeCompact,
216 found: BranchNodeCompact,
217 ) -> Output {
218 if let Some(account) = self.account {
219 Output::StorageWrong { account, path, expected, found }
220 } else {
221 Output::AccountWrong { path, expected, found }
222 }
223 }
224
225 const fn output_missing(&self, path: Nibbles, node: BranchNodeCompact) -> Output {
226 if let Some(account) = self.account {
227 Output::StorageMissing(account, path, node)
228 } else {
229 Output::AccountMissing(path, node)
230 }
231 }
232
233 fn next(
239 &mut self,
240 outputs: &mut Vec<Output>,
241 path: Nibbles,
242 node: BranchNodeCompact,
243 ) -> Result<(), DatabaseError> {
244 loop {
245 if self.curr.is_none() {
248 outputs.push(self.output_missing(path, node));
249 return Ok(())
250 }
251
252 let (curr_path, curr_node) = self.curr.as_ref().expect("not None");
253 trace!(target: "trie::verify", account=?self.account, ?curr_path, ?path, "Current cursor node");
254
255 match depth_first::cmp(&path, curr_path) {
257 Ordering::Less => {
258 outputs.push(self.output_missing(path, node));
261 return Ok(())
262 }
263 Ordering::Equal => {
264 if *curr_node != node {
268 outputs.push(self.output_wrong(path, node, curr_node.clone()))
269 }
270 self.curr = self.trie_iter.next().transpose()?;
271 return Ok(())
272 }
273 Ordering::Greater => {
274 outputs.push(self.output_extra(*curr_path, curr_node.clone()));
278 self.curr = self.trie_iter.next().transpose()?;
279 }
282 }
283 }
284 }
285
286 fn finalize(&mut self, outputs: &mut Vec<Output>) -> Result<(), DatabaseError> {
289 loop {
290 if let Some((curr_path, curr_node)) = self.curr.take() {
291 outputs.push(self.output_extra(curr_path, curr_node));
292 self.curr = self.trie_iter.next().transpose()?;
293 } else {
294 return Ok(())
295 }
296 }
297 }
298}
299
300#[derive(Debug)]
304pub struct Verifier<'a, T: TrieCursorFactory, H> {
305 trie_cursor_factory: &'a T,
306 hashed_cursor_factory: H,
307 branch_node_iter: StateRootBranchNodesIter<H>,
308 outputs: Vec<Output>,
309 account: SingleVerifier<DepthFirstTrieIterator<T::AccountTrieCursor<'a>>>,
310 storage: Option<(B256, SingleVerifier<DepthFirstTrieIterator<T::StorageTrieCursor<'a>>>)>,
311 complete: bool,
312}
313
314impl<'a, T: TrieCursorFactory, H: HashedCursorFactory + Clone> Verifier<'a, T, H> {
315 pub fn new(
317 trie_cursor_factory: &'a T,
318 hashed_cursor_factory: H,
319 ) -> Result<Self, DatabaseError> {
320 Ok(Self {
321 trie_cursor_factory,
322 hashed_cursor_factory: hashed_cursor_factory.clone(),
323 branch_node_iter: StateRootBranchNodesIter::new(hashed_cursor_factory),
324 outputs: Default::default(),
325 account: SingleVerifier::new(None, trie_cursor_factory.account_trie_cursor()?)?,
326 storage: None,
327 complete: false,
328 })
329 }
330}
331
332impl<'a, T: TrieCursorFactory, H: HashedCursorFactory + Clone> Verifier<'a, T, H> {
333 fn new_storage(
334 &mut self,
335 account: B256,
336 path: Nibbles,
337 node: BranchNodeCompact,
338 ) -> Result<(), DatabaseError> {
339 let trie_cursor = self.trie_cursor_factory.storage_trie_cursor(account)?;
340 let mut storage = SingleVerifier::new(Some(account), trie_cursor)?;
341 storage.next(&mut self.outputs, path, node)?;
342 self.storage = Some((account, storage));
343 Ok(())
344 }
345
346 fn verify_empty_storages(
351 &mut self,
352 last_account: B256,
353 next_account: B256,
354 start_inclusive: bool,
355 end_inclusive: bool,
356 ) -> Result<(), DatabaseError> {
357 let mut account_cursor = self.hashed_cursor_factory.hashed_account_cursor()?;
358 let mut account_seeked = false;
359
360 if !start_inclusive {
361 account_seeked = true;
362 account_cursor.seek(last_account)?;
363 }
364
365 loop {
366 let Some((curr_account, _)) = (if account_seeked {
367 account_cursor.next()?
368 } else {
369 account_seeked = true;
370 account_cursor.seek(last_account)?
371 }) else {
372 return Ok(())
373 };
374
375 if curr_account < next_account || (end_inclusive && curr_account == next_account) {
376 trace!(target: "trie::verify", account = ?curr_account, "Verifying account has empty storage");
377
378 let mut storage_cursor =
379 self.trie_cursor_factory.storage_trie_cursor(curr_account)?;
380 let mut seeked = false;
381 while let Some((path, node)) = if seeked {
382 storage_cursor.next()?
383 } else {
384 seeked = true;
385 storage_cursor.seek(Nibbles::new())?
386 } {
387 self.outputs.push(Output::StorageExtra(curr_account, path, node));
388 }
389 } else {
390 return Ok(())
391 }
392 }
393 }
394
395 fn try_next(&mut self) -> Result<(), StateRootError> {
396 match self.branch_node_iter.next().transpose()? {
397 None => {
398 self.account.finalize(&mut self.outputs)?;
399 if let Some((prev_account, storage)) = self.storage.as_mut() {
400 storage.finalize(&mut self.outputs)?;
401
402 let prev_account = *prev_account;
405
406 let max_account = B256::repeat_byte(0xFFu8);
408
409 self.verify_empty_storages(prev_account, max_account, false, true)?;
410 }
411 self.complete = true;
412 }
413 Some(BranchNode::Account(path, node)) => {
414 trace!(target: "trie::verify", ?path, "Account node from state root");
415 self.account.next(&mut self.outputs, path, node)?;
416 if !path.is_empty() {
418 self.outputs.push(Output::Progress(path));
419 }
420 }
421 Some(BranchNode::Storage(account, path, node)) => {
422 trace!(target: "trie::verify", ?account, ?path, "Storage node from state root");
423 match self.storage.as_mut() {
424 None => {
425 self.verify_empty_storages(B256::ZERO, account, true, false)?;
427 self.new_storage(account, path, node)?;
428 }
429 Some((prev_account, storage)) if *prev_account == account => {
430 storage.next(&mut self.outputs, path, node)?;
431 }
432 Some((prev_account, storage)) => {
433 storage.finalize(&mut self.outputs)?;
434 let prev_account = *prev_account;
436 self.verify_empty_storages(prev_account, account, false, false)?;
437 self.new_storage(account, path, node)?;
438 }
439 }
440 }
441 }
442
443 self.outputs.reverse();
446 Ok(())
447 }
448}
449
450impl<'a, T: TrieCursorFactory, H: HashedCursorFactory + Clone> Iterator for Verifier<'a, T, H> {
451 type Item = Result<Output, StateRootError>;
452
453 fn next(&mut self) -> Option<Self::Item> {
454 loop {
455 if let Some(output) = self.outputs.pop() {
456 return Some(Ok(output))
457 }
458
459 if self.complete {
460 return None
461 }
462
463 if let Err(err) = self.try_next() {
464 return Some(Err(err))
465 }
466 }
467 }
468}
469
470#[cfg(test)]
471mod tests {
472
473 use super::*;
474 use crate::{
475 hashed_cursor::mock::MockHashedCursorFactory,
476 trie_cursor::mock::{MockTrieCursor, MockTrieCursorFactory},
477 };
478 use alloy_primitives::{keccak256, map::B256Map, Address, U256};
479 use alloy_trie::TrieMask;
480 use assert_matches::assert_matches;
481 use reth_primitives_traits::Account;
482 use std::collections::BTreeMap;
483
484 fn test_branch_node(
486 state_mask: u16,
487 tree_mask: u16,
488 hash_mask: u16,
489 hashes: Vec<B256>,
490 ) -> BranchNodeCompact {
491 let expected_hashes = hash_mask.count_ones() as usize;
493 let mut final_hashes = hashes;
494 let mut counter = 100u8;
495 while final_hashes.len() < expected_hashes {
496 final_hashes.push(B256::repeat_byte(counter));
497 counter += 1;
498 }
499 final_hashes.truncate(expected_hashes);
500
501 BranchNodeCompact::new(
502 TrieMask::new(state_mask),
503 TrieMask::new(tree_mask),
504 TrieMask::new(hash_mask),
505 final_hashes,
506 None,
507 )
508 }
509
510 fn create_mock_cursor(trie_nodes: BTreeMap<Nibbles, BranchNodeCompact>) -> MockTrieCursor {
512 let factory = MockTrieCursorFactory::new(trie_nodes, B256Map::default());
513 factory.account_trie_cursor().unwrap()
514 }
515
516 #[test]
517 fn test_state_root_branch_nodes_iter_empty() {
518 let factory = MockHashedCursorFactory::new(BTreeMap::new(), B256Map::default());
520 let mut iter = StateRootBranchNodesIter::new(factory);
521
522 let mut count = 0;
524 for result in iter.by_ref() {
525 assert!(result.is_ok(), "Unexpected error: {:?}", result.unwrap_err());
526 count += 1;
527 assert!(count <= 1000, "Too many iterations");
529 }
530
531 assert!(iter.complete);
532 }
533
534 #[test]
535 #[allow(clippy::needless_update)]
536 fn test_state_root_branch_nodes_iter_basic() {
537 let mut accounts = BTreeMap::new();
539 let mut storage_tries = B256Map::default();
540
541 let addr1 = keccak256(Address::with_last_byte(1));
543 accounts.insert(
544 addr1,
545 Account {
546 nonce: 1,
547 balance: U256::from(1000),
548 bytecode_hash: Some(keccak256(b"code1")),
549 ..Default::default()
550 },
551 );
552
553 let mut storage1 = BTreeMap::new();
555 storage1.insert(keccak256(B256::with_last_byte(1)), U256::from(100));
556 storage1.insert(keccak256(B256::with_last_byte(2)), U256::from(200));
557 storage_tries.insert(addr1, storage1);
558
559 let factory = MockHashedCursorFactory::new(accounts, storage_tries);
560 let mut iter = StateRootBranchNodesIter::new(factory);
561
562 let mut account_paths = Vec::new();
564 let mut storage_paths_by_account: B256Map<Vec<Nibbles>> = B256Map::default();
565 let mut iterations = 0;
566
567 for result in iter.by_ref() {
568 iterations += 1;
569 assert!(iterations <= 10000, "Too many iterations - possible infinite loop");
570
571 match result {
572 Ok(BranchNode::Account(path, _)) => {
573 account_paths.push(path);
574 }
575 Ok(BranchNode::Storage(account, path, _)) => {
576 storage_paths_by_account.entry(account).or_default().push(path);
577 }
578 Err(e) => panic!("Unexpected error: {:?}", e),
579 }
580 }
581
582 for i in 1..account_paths.len() {
584 assert!(
585 account_paths[i - 1] < account_paths[i],
586 "Account paths should be in ascending order"
587 );
588 }
589
590 for (account, paths) in storage_paths_by_account {
592 for i in 1..paths.len() {
593 assert!(
594 paths[i - 1] < paths[i],
595 "Storage paths for account {:?} should be in ascending order",
596 account
597 );
598 }
599 }
600
601 assert!(iter.complete);
602 }
603
604 #[test]
605 #[allow(clippy::needless_update)]
606 fn test_state_root_branch_nodes_iter_multiple_accounts() {
607 let mut accounts = BTreeMap::new();
609 let mut storage_tries = B256Map::default();
610
611 for i in 1u8..=3 {
613 let addr = keccak256([i; 20]);
614 accounts.insert(
615 addr,
616 Account {
617 nonce: i as u64,
618 balance: U256::from(i as u64 * 1000),
619 bytecode_hash: (i == 2).then(|| keccak256([i])),
620 ..Default::default()
621 },
622 );
623
624 let mut storage = BTreeMap::new();
626 for j in 0..i {
627 storage.insert(keccak256(B256::with_last_byte(j)), U256::from(j as u64 * 10));
628 }
629 if !storage.is_empty() {
630 storage_tries.insert(addr, storage);
631 }
632 }
633
634 let factory = MockHashedCursorFactory::new(accounts, storage_tries);
635 let mut iter = StateRootBranchNodesIter::new(factory);
636
637 let mut seen_storage_accounts = Vec::new();
639 let mut current_storage_account = None;
640 let mut iterations = 0;
641
642 for result in iter.by_ref() {
643 iterations += 1;
644 assert!(iterations <= 10000, "Too many iterations");
645
646 match result {
647 Ok(BranchNode::Storage(account, _, _)) => {
648 if current_storage_account != Some(account) {
649 assert!(
651 !seen_storage_accounts.contains(&account),
652 "Should not revisit storage account {:?}",
653 account
654 );
655 seen_storage_accounts.push(account);
656 current_storage_account = Some(account);
657 }
658 }
659 Ok(BranchNode::Account(_, _)) => {
660 }
662 Err(e) => panic!("Unexpected error: {:?}", e),
663 }
664 }
665
666 assert!(iter.complete);
667 }
668
669 #[test]
670 fn test_single_verifier_new() {
671 let trie_nodes = BTreeMap::from([(
673 Nibbles::from_nibbles([0x1]),
674 test_branch_node(0b1111, 0, 0, vec![]),
675 )]);
676
677 let cursor = create_mock_cursor(trie_nodes);
678 let verifier = SingleVerifier::new(None, cursor).unwrap();
679
680 assert!(verifier.curr.is_some());
682 }
683
684 #[test]
685 fn test_single_verifier_next_exact_match() {
686 let node1 = test_branch_node(0b1111, 0, 0b1111, vec![B256::repeat_byte(1u8)]);
688 let node2 = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::repeat_byte(2u8)]);
689
690 let trie_nodes = BTreeMap::from([
691 (Nibbles::from_nibbles([0x1]), node1.clone()),
692 (Nibbles::from_nibbles([0x2]), node2),
693 ]);
694
695 let cursor = create_mock_cursor(trie_nodes);
696 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
697 let mut outputs = Vec::new();
698
699 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
701
702 assert!(outputs.is_empty());
704 }
705
706 #[test]
707 fn test_single_verifier_next_wrong_value() {
708 let node_in_trie = test_branch_node(0b1111, 0, 0b1111, vec![B256::repeat_byte(1u8)]);
710 let node_expected = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::repeat_byte(2u8)]);
711
712 let trie_nodes = BTreeMap::from([(Nibbles::from_nibbles([0x1]), node_in_trie.clone())]);
713
714 let cursor = create_mock_cursor(trie_nodes);
715 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
716 let mut outputs = Vec::new();
717
718 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node_expected.clone()).unwrap();
720
721 assert_eq!(outputs.len(), 1);
723 assert_matches!(
724 &outputs[0],
725 Output::AccountWrong { path, expected, found }
726 if *path == Nibbles::from_nibbles([0x1]) && *expected == node_expected && *found == node_in_trie
727 );
728 }
729
730 #[test]
731 fn test_single_verifier_next_missing() {
732 let node1 = test_branch_node(0b1111, 0, 0b1111, vec![B256::repeat_byte(1u8)]);
734 let node_missing = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::repeat_byte(2u8)]);
735
736 let trie_nodes = BTreeMap::from([(Nibbles::from_nibbles([0x3]), node1)]);
737
738 let cursor = create_mock_cursor(trie_nodes);
739 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
740 let mut outputs = Vec::new();
741
742 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node_missing.clone()).unwrap();
744
745 assert_eq!(outputs.len(), 1);
747 assert_matches!(
748 &outputs[0],
749 Output::AccountMissing(path, node)
750 if *path == Nibbles::from_nibbles([0x1]) && *node == node_missing
751 );
752 }
753
754 #[test]
755 fn test_single_verifier_next_extra() {
756 let node_root = test_branch_node(0b1110, 0, 0b1110, vec![]); let node1 = test_branch_node(0b0001, 0, 0b0001, vec![]);
760 let node2 = test_branch_node(0b0010, 0, 0b0010, vec![]);
761 let node3 = test_branch_node(0b0100, 0, 0b0100, vec![]);
762
763 let trie_nodes = BTreeMap::from([
764 (Nibbles::new(), node_root.clone()),
765 (Nibbles::from_nibbles([0x1]), node1.clone()),
766 (Nibbles::from_nibbles([0x2]), node2.clone()),
767 (Nibbles::from_nibbles([0x3]), node3.clone()),
768 ]);
769
770 let cursor = create_mock_cursor(trie_nodes);
771 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
772 let mut outputs = Vec::new();
773
774 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
777 verifier.next(&mut outputs, Nibbles::from_nibbles([0x3]), node3).unwrap();
778 verifier.finalize(&mut outputs).unwrap();
779
780 if outputs.len() != 2 {
782 eprintln!("Expected 2 outputs, got {}:", outputs.len());
783 for inc in &outputs {
784 eprintln!(" {:?}", inc);
785 }
786 }
787 assert_eq!(outputs.len(), 2);
788 assert_matches!(
789 &outputs[0],
790 Output::AccountExtra(path, node)
791 if *path == Nibbles::from_nibbles([0x2]) && *node == node2
792 );
793 assert_matches!(
794 &outputs[1],
795 Output::AccountExtra(path, node)
796 if *path == Nibbles::new() && *node == node_root
797 );
798 }
799
800 #[test]
801 fn test_single_verifier_finalize() {
802 let node_root = test_branch_node(0b1110, 0, 0b1110, vec![]); let node1 = test_branch_node(0b0001, 0, 0b0001, vec![]);
805 let node2 = test_branch_node(0b0010, 0, 0b0010, vec![]);
806 let node3 = test_branch_node(0b0100, 0, 0b0100, vec![]);
807
808 let trie_nodes = BTreeMap::from([
809 (Nibbles::new(), node_root.clone()),
810 (Nibbles::from_nibbles([0x1]), node1.clone()),
811 (Nibbles::from_nibbles([0x2]), node2.clone()),
812 (Nibbles::from_nibbles([0x3]), node3.clone()),
813 ]);
814
815 let cursor = create_mock_cursor(trie_nodes);
816 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
817 let mut outputs = Vec::new();
818
819 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
822 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2]), node2).unwrap();
823 assert!(outputs.is_empty());
824
825 verifier.finalize(&mut outputs).unwrap();
827
828 assert_eq!(outputs.len(), 2);
830 assert_matches!(
831 &outputs[0],
832 Output::AccountExtra(path, node)
833 if *path == Nibbles::from_nibbles([0x3]) && *node == node3
834 );
835 assert_matches!(
836 &outputs[1],
837 Output::AccountExtra(path, node)
838 if *path == Nibbles::new() && *node == node_root
839 );
840 }
841
842 #[test]
843 fn test_single_verifier_storage_trie() {
844 let account = B256::repeat_byte(42u8);
846 let node = test_branch_node(0b1111, 0, 0b1111, vec![B256::repeat_byte(1u8)]);
847
848 let trie_nodes = BTreeMap::from([(Nibbles::from_nibbles([0x1]), node)]);
849
850 let cursor = create_mock_cursor(trie_nodes);
851 let mut verifier = SingleVerifier::new(Some(account), cursor).unwrap();
852 let mut outputs = Vec::new();
853
854 let missing_node = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::repeat_byte(2u8)]);
856 verifier.next(&mut outputs, Nibbles::from_nibbles([0x0]), missing_node.clone()).unwrap();
857
858 assert_eq!(outputs.len(), 1);
860 assert_matches!(
861 &outputs[0],
862 Output::StorageMissing(acc, path, node)
863 if *acc == account && *path == Nibbles::from_nibbles([0x0]) && *node == missing_node
864 );
865 }
866
867 #[test]
868 fn test_single_verifier_empty_trie() {
869 let trie_nodes = BTreeMap::new();
871 let cursor = create_mock_cursor(trie_nodes);
872 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
873 let mut outputs = Vec::new();
874
875 let node = test_branch_node(0b1111, 0, 0b1111, vec![B256::repeat_byte(1u8)]);
877 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node.clone()).unwrap();
878
879 assert_eq!(outputs.len(), 1);
880 assert_matches!(
881 &outputs[0],
882 Output::AccountMissing(path, n)
883 if *path == Nibbles::from_nibbles([0x1]) && *n == node
884 );
885 }
886
887 #[test]
888 fn test_single_verifier_depth_first_ordering() {
889 let node_root = test_branch_node(0b0110, 0, 0b0110, vec![]); let node1 = test_branch_node(0b0110, 0, 0b0110, vec![]); let node11 = test_branch_node(0b0001, 0, 0b0001, vec![]); let node12 = test_branch_node(0b0010, 0, 0b0010, vec![]); let node2 = test_branch_node(0b0100, 0, 0b0100, vec![]); let trie_nodes = BTreeMap::from([
901 (Nibbles::new(), node_root.clone()), (Nibbles::from_nibbles([0x1]), node1.clone()), (Nibbles::from_nibbles([0x1, 0x1]), node11.clone()), (Nibbles::from_nibbles([0x1, 0x2]), node12.clone()), (Nibbles::from_nibbles([0x2]), node2.clone()), ]);
907
908 let cursor = create_mock_cursor(trie_nodes);
909 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
910 let mut outputs = Vec::new();
911
912 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1]), node11).unwrap();
915 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x2]), node12).unwrap();
916 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
917 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2]), node2).unwrap();
918 verifier.next(&mut outputs, Nibbles::new(), node_root).unwrap();
919 verifier.finalize(&mut outputs).unwrap();
920
921 if !outputs.is_empty() {
923 eprintln!(
924 "Test test_single_verifier_depth_first_ordering failed with {} outputs:",
925 outputs.len()
926 );
927 for inc in &outputs {
928 eprintln!(" {:?}", inc);
929 }
930 }
931 assert!(outputs.is_empty());
932 }
933
934 #[test]
935 fn test_single_verifier_wrong_depth_first_order() {
936 let node_root = test_branch_node(0b0010, 0, 0b0010, vec![]); let node1 = test_branch_node(0b0010, 0, 0b0010, vec![]); let node11 = test_branch_node(0b0001, 0, 0b0001, vec![]); let trie_nodes = BTreeMap::from([
943 (Nibbles::new(), node_root.clone()),
944 (Nibbles::from_nibbles([0x1]), node1.clone()),
945 (Nibbles::from_nibbles([0x1, 0x1]), node11.clone()),
946 ]);
947
948 let cursor = create_mock_cursor(trie_nodes);
949 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
950 let mut outputs = Vec::new();
951
952 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1]), node11).unwrap();
956 verifier.next(&mut outputs, Nibbles::new(), node_root).unwrap();
957 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
958
959 assert!(!outputs.is_empty());
961 }
962
963 #[test]
964 fn test_single_verifier_complex_depth_first() {
965 let node_root = test_branch_node(0b0110, 0, 0b0110, vec![]); let node1 = test_branch_node(0b0110, 0, 0b0110, vec![]); let node11 = test_branch_node(0b0110, 0, 0b0110, vec![]); let node111 = test_branch_node(0b0001, 0, 0b0001, vec![]); let node112 = test_branch_node(0b0010, 0, 0b0010, vec![]); let node12 = test_branch_node(0b0100, 0, 0b0100, vec![]); let node2 = test_branch_node(0b0010, 0, 0b0010, vec![]); let node21 = test_branch_node(0b0001, 0, 0b0001, vec![]); let trie_nodes = BTreeMap::from([
980 (Nibbles::new(), node_root.clone()),
981 (Nibbles::from_nibbles([0x1]), node1.clone()),
982 (Nibbles::from_nibbles([0x1, 0x1]), node11.clone()),
983 (Nibbles::from_nibbles([0x1, 0x1, 0x1]), node111.clone()),
984 (Nibbles::from_nibbles([0x1, 0x1, 0x2]), node112.clone()),
985 (Nibbles::from_nibbles([0x1, 0x2]), node12.clone()),
986 (Nibbles::from_nibbles([0x2]), node2.clone()),
987 (Nibbles::from_nibbles([0x2, 0x1]), node21.clone()),
988 ]);
989
990 let cursor = create_mock_cursor(trie_nodes);
991 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
992 let mut outputs = Vec::new();
993
994 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1, 0x1]), node111).unwrap();
997 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1, 0x2]), node112).unwrap();
998 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1]), node11).unwrap();
999 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x2]), node12).unwrap();
1000 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
1001 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2, 0x1]), node21).unwrap();
1002 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2]), node2).unwrap();
1003 verifier.next(&mut outputs, Nibbles::new(), node_root).unwrap();
1004 verifier.finalize(&mut outputs).unwrap();
1005
1006 if !outputs.is_empty() {
1008 eprintln!(
1009 "Test test_single_verifier_complex_depth_first failed with {} outputs:",
1010 outputs.len()
1011 );
1012 for inc in &outputs {
1013 eprintln!(" {:?}", inc);
1014 }
1015 }
1016 assert!(outputs.is_empty());
1017 }
1018}