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;
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(|a, b| b.0.cmp(&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, "Verying 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::from([0xFFu8; 32]);
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 use super::*;
473 use crate::{
474 hashed_cursor::mock::MockHashedCursorFactory,
475 trie_cursor::mock::{MockTrieCursor, MockTrieCursorFactory},
476 };
477 use alloy_primitives::{address, keccak256, map::B256Map, U256};
478 use alloy_trie::TrieMask;
479 use assert_matches::assert_matches;
480 use reth_primitives_traits::Account;
481 use std::collections::BTreeMap;
482
483 fn test_branch_node(
485 state_mask: u16,
486 tree_mask: u16,
487 hash_mask: u16,
488 hashes: Vec<B256>,
489 ) -> BranchNodeCompact {
490 let expected_hashes = hash_mask.count_ones() as usize;
492 let mut final_hashes = hashes;
493 let mut counter = 100u8;
494 while final_hashes.len() < expected_hashes {
495 final_hashes.push(B256::from([counter; 32]));
496 counter += 1;
497 }
498 final_hashes.truncate(expected_hashes);
499
500 BranchNodeCompact::new(
501 TrieMask::new(state_mask),
502 TrieMask::new(tree_mask),
503 TrieMask::new(hash_mask),
504 final_hashes,
505 None,
506 )
507 }
508
509 fn create_mock_cursor(trie_nodes: BTreeMap<Nibbles, BranchNodeCompact>) -> MockTrieCursor {
511 let factory = MockTrieCursorFactory::new(trie_nodes, B256Map::default());
512 factory.account_trie_cursor().unwrap()
513 }
514
515 #[test]
516 fn test_state_root_branch_nodes_iter_empty() {
517 let factory = MockHashedCursorFactory::new(BTreeMap::new(), B256Map::default());
519 let mut iter = StateRootBranchNodesIter::new(factory);
520
521 let mut count = 0;
523 for result in iter.by_ref() {
524 assert!(result.is_ok(), "Unexpected error: {:?}", result.unwrap_err());
525 count += 1;
526 assert!(count <= 1000, "Too many iterations");
528 }
529
530 assert!(iter.complete);
531 }
532
533 #[test]
534 fn test_state_root_branch_nodes_iter_basic() {
535 let mut accounts = BTreeMap::new();
537 let mut storage_tries = B256Map::default();
538
539 let addr1 = keccak256(address!("0000000000000000000000000000000000000001"));
541 accounts.insert(
542 addr1,
543 Account {
544 nonce: 1,
545 balance: U256::from(1000),
546 bytecode_hash: Some(keccak256(b"code1")),
547 },
548 );
549
550 let mut storage1 = BTreeMap::new();
552 storage1.insert(keccak256(B256::from(U256::from(1))), U256::from(100));
553 storage1.insert(keccak256(B256::from(U256::from(2))), U256::from(200));
554 storage_tries.insert(addr1, storage1);
555
556 let factory = MockHashedCursorFactory::new(accounts, storage_tries);
557 let mut iter = StateRootBranchNodesIter::new(factory);
558
559 let mut account_paths = Vec::new();
561 let mut storage_paths_by_account: B256Map<Vec<Nibbles>> = B256Map::default();
562 let mut iterations = 0;
563
564 for result in iter.by_ref() {
565 iterations += 1;
566 assert!(iterations <= 10000, "Too many iterations - possible infinite loop");
567
568 match result {
569 Ok(BranchNode::Account(path, _)) => {
570 account_paths.push(path);
571 }
572 Ok(BranchNode::Storage(account, path, _)) => {
573 storage_paths_by_account.entry(account).or_default().push(path);
574 }
575 Err(e) => panic!("Unexpected error: {:?}", e),
576 }
577 }
578
579 for i in 1..account_paths.len() {
581 assert!(
582 account_paths[i - 1] < account_paths[i],
583 "Account paths should be in ascending order"
584 );
585 }
586
587 for (account, paths) in storage_paths_by_account {
589 for i in 1..paths.len() {
590 assert!(
591 paths[i - 1] < paths[i],
592 "Storage paths for account {:?} should be in ascending order",
593 account
594 );
595 }
596 }
597
598 assert!(iter.complete);
599 }
600
601 #[test]
602 fn test_state_root_branch_nodes_iter_multiple_accounts() {
603 let mut accounts = BTreeMap::new();
605 let mut storage_tries = B256Map::default();
606
607 for i in 1u8..=3 {
609 let addr = keccak256([i; 20]);
610 accounts.insert(
611 addr,
612 Account {
613 nonce: i as u64,
614 balance: U256::from(i as u64 * 1000),
615 bytecode_hash: (i == 2).then(|| keccak256([i])),
616 },
617 );
618
619 let mut storage = BTreeMap::new();
621 for j in 0..i {
622 storage.insert(keccak256(B256::from(U256::from(j))), U256::from(j as u64 * 10));
623 }
624 if !storage.is_empty() {
625 storage_tries.insert(addr, storage);
626 }
627 }
628
629 let factory = MockHashedCursorFactory::new(accounts, storage_tries);
630 let mut iter = StateRootBranchNodesIter::new(factory);
631
632 let mut seen_storage_accounts = Vec::new();
634 let mut current_storage_account = None;
635 let mut iterations = 0;
636
637 for result in iter.by_ref() {
638 iterations += 1;
639 assert!(iterations <= 10000, "Too many iterations");
640
641 match result {
642 Ok(BranchNode::Storage(account, _, _)) => {
643 if current_storage_account != Some(account) {
644 assert!(
646 !seen_storage_accounts.contains(&account),
647 "Should not revisit storage account {:?}",
648 account
649 );
650 seen_storage_accounts.push(account);
651 current_storage_account = Some(account);
652 }
653 }
654 Ok(BranchNode::Account(_, _)) => {
655 }
657 Err(e) => panic!("Unexpected error: {:?}", e),
658 }
659 }
660
661 assert!(iter.complete);
662 }
663
664 #[test]
665 fn test_single_verifier_new() {
666 let trie_nodes = BTreeMap::from([(
668 Nibbles::from_nibbles([0x1]),
669 test_branch_node(0b1111, 0, 0, vec![]),
670 )]);
671
672 let cursor = create_mock_cursor(trie_nodes);
673 let verifier = SingleVerifier::new(None, cursor).unwrap();
674
675 assert!(verifier.curr.is_some());
677 }
678
679 #[test]
680 fn test_single_verifier_next_exact_match() {
681 let node1 = test_branch_node(0b1111, 0, 0b1111, vec![B256::from([1u8; 32])]);
683 let node2 = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::from([2u8; 32])]);
684
685 let trie_nodes = BTreeMap::from([
686 (Nibbles::from_nibbles([0x1]), node1.clone()),
687 (Nibbles::from_nibbles([0x2]), node2),
688 ]);
689
690 let cursor = create_mock_cursor(trie_nodes);
691 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
692 let mut outputs = Vec::new();
693
694 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
696
697 assert!(outputs.is_empty());
699 }
700
701 #[test]
702 fn test_single_verifier_next_wrong_value() {
703 let node_in_trie = test_branch_node(0b1111, 0, 0b1111, vec![B256::from([1u8; 32])]);
705 let node_expected = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::from([2u8; 32])]);
706
707 let trie_nodes = BTreeMap::from([(Nibbles::from_nibbles([0x1]), node_in_trie.clone())]);
708
709 let cursor = create_mock_cursor(trie_nodes);
710 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
711 let mut outputs = Vec::new();
712
713 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node_expected.clone()).unwrap();
715
716 assert_eq!(outputs.len(), 1);
718 assert_matches!(
719 &outputs[0],
720 Output::AccountWrong { path, expected, found }
721 if *path == Nibbles::from_nibbles([0x1]) && *expected == node_expected && *found == node_in_trie
722 );
723 }
724
725 #[test]
726 fn test_single_verifier_next_missing() {
727 let node1 = test_branch_node(0b1111, 0, 0b1111, vec![B256::from([1u8; 32])]);
729 let node_missing = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::from([2u8; 32])]);
730
731 let trie_nodes = BTreeMap::from([(Nibbles::from_nibbles([0x3]), node1)]);
732
733 let cursor = create_mock_cursor(trie_nodes);
734 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
735 let mut outputs = Vec::new();
736
737 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node_missing.clone()).unwrap();
739
740 assert_eq!(outputs.len(), 1);
742 assert_matches!(
743 &outputs[0],
744 Output::AccountMissing(path, node)
745 if *path == Nibbles::from_nibbles([0x1]) && *node == node_missing
746 );
747 }
748
749 #[test]
750 fn test_single_verifier_next_extra() {
751 let node_root = test_branch_node(0b1110, 0, 0b1110, vec![]); let node1 = test_branch_node(0b0001, 0, 0b0001, vec![]);
755 let node2 = test_branch_node(0b0010, 0, 0b0010, vec![]);
756 let node3 = test_branch_node(0b0100, 0, 0b0100, vec![]);
757
758 let trie_nodes = BTreeMap::from([
759 (Nibbles::new(), node_root.clone()),
760 (Nibbles::from_nibbles([0x1]), node1.clone()),
761 (Nibbles::from_nibbles([0x2]), node2.clone()),
762 (Nibbles::from_nibbles([0x3]), node3.clone()),
763 ]);
764
765 let cursor = create_mock_cursor(trie_nodes);
766 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
767 let mut outputs = Vec::new();
768
769 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
772 verifier.next(&mut outputs, Nibbles::from_nibbles([0x3]), node3).unwrap();
773 verifier.finalize(&mut outputs).unwrap();
774
775 if outputs.len() != 2 {
777 eprintln!("Expected 2 outputs, got {}:", outputs.len());
778 for inc in &outputs {
779 eprintln!(" {:?}", inc);
780 }
781 }
782 assert_eq!(outputs.len(), 2);
783 assert_matches!(
784 &outputs[0],
785 Output::AccountExtra(path, node)
786 if *path == Nibbles::from_nibbles([0x2]) && *node == node2
787 );
788 assert_matches!(
789 &outputs[1],
790 Output::AccountExtra(path, node)
791 if *path == Nibbles::new() && *node == node_root
792 );
793 }
794
795 #[test]
796 fn test_single_verifier_finalize() {
797 let node_root = test_branch_node(0b1110, 0, 0b1110, vec![]); let node1 = test_branch_node(0b0001, 0, 0b0001, vec![]);
800 let node2 = test_branch_node(0b0010, 0, 0b0010, vec![]);
801 let node3 = test_branch_node(0b0100, 0, 0b0100, vec![]);
802
803 let trie_nodes = BTreeMap::from([
804 (Nibbles::new(), node_root.clone()),
805 (Nibbles::from_nibbles([0x1]), node1.clone()),
806 (Nibbles::from_nibbles([0x2]), node2.clone()),
807 (Nibbles::from_nibbles([0x3]), node3.clone()),
808 ]);
809
810 let cursor = create_mock_cursor(trie_nodes);
811 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
812 let mut outputs = Vec::new();
813
814 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
817 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2]), node2).unwrap();
818 assert!(outputs.is_empty());
819
820 verifier.finalize(&mut outputs).unwrap();
822
823 assert_eq!(outputs.len(), 2);
825 assert_matches!(
826 &outputs[0],
827 Output::AccountExtra(path, node)
828 if *path == Nibbles::from_nibbles([0x3]) && *node == node3
829 );
830 assert_matches!(
831 &outputs[1],
832 Output::AccountExtra(path, node)
833 if *path == Nibbles::new() && *node == node_root
834 );
835 }
836
837 #[test]
838 fn test_single_verifier_storage_trie() {
839 let account = B256::from([42u8; 32]);
841 let node = test_branch_node(0b1111, 0, 0b1111, vec![B256::from([1u8; 32])]);
842
843 let trie_nodes = BTreeMap::from([(Nibbles::from_nibbles([0x1]), node)]);
844
845 let cursor = create_mock_cursor(trie_nodes);
846 let mut verifier = SingleVerifier::new(Some(account), cursor).unwrap();
847 let mut outputs = Vec::new();
848
849 let missing_node = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::from([2u8; 32])]);
851 verifier.next(&mut outputs, Nibbles::from_nibbles([0x0]), missing_node.clone()).unwrap();
852
853 assert_eq!(outputs.len(), 1);
855 assert_matches!(
856 &outputs[0],
857 Output::StorageMissing(acc, path, node)
858 if *acc == account && *path == Nibbles::from_nibbles([0x0]) && *node == missing_node
859 );
860 }
861
862 #[test]
863 fn test_single_verifier_empty_trie() {
864 let trie_nodes = BTreeMap::new();
866 let cursor = create_mock_cursor(trie_nodes);
867 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
868 let mut outputs = Vec::new();
869
870 let node = test_branch_node(0b1111, 0, 0b1111, vec![B256::from([1u8; 32])]);
872 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node.clone()).unwrap();
873
874 assert_eq!(outputs.len(), 1);
875 assert_matches!(
876 &outputs[0],
877 Output::AccountMissing(path, n)
878 if *path == Nibbles::from_nibbles([0x1]) && *n == node
879 );
880 }
881
882 #[test]
883 fn test_single_verifier_depth_first_ordering() {
884 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([
896 (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()), ]);
902
903 let cursor = create_mock_cursor(trie_nodes);
904 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
905 let mut outputs = Vec::new();
906
907 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1]), node11).unwrap();
910 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x2]), node12).unwrap();
911 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
912 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2]), node2).unwrap();
913 verifier.next(&mut outputs, Nibbles::new(), node_root).unwrap();
914 verifier.finalize(&mut outputs).unwrap();
915
916 if !outputs.is_empty() {
918 eprintln!(
919 "Test test_single_verifier_depth_first_ordering failed with {} outputs:",
920 outputs.len()
921 );
922 for inc in &outputs {
923 eprintln!(" {:?}", inc);
924 }
925 }
926 assert!(outputs.is_empty());
927 }
928
929 #[test]
930 fn test_single_verifier_wrong_depth_first_order() {
931 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([
938 (Nibbles::new(), node_root.clone()),
939 (Nibbles::from_nibbles([0x1]), node1.clone()),
940 (Nibbles::from_nibbles([0x1, 0x1]), node11.clone()),
941 ]);
942
943 let cursor = create_mock_cursor(trie_nodes);
944 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
945 let mut outputs = Vec::new();
946
947 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1]), node11).unwrap();
951 verifier.next(&mut outputs, Nibbles::new(), node_root).unwrap();
952 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
953
954 assert!(!outputs.is_empty());
956 }
957
958 #[test]
959 fn test_single_verifier_complex_depth_first() {
960 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([
973 (Nibbles::new(), node_root.clone()),
974 (Nibbles::from_nibbles([0x1]), node1.clone()),
975 (Nibbles::from_nibbles([0x1, 0x1]), node11.clone()),
976 (Nibbles::from_nibbles([0x1, 0x1, 0x1]), node111.clone()),
977 (Nibbles::from_nibbles([0x1, 0x1, 0x2]), node112.clone()),
978 (Nibbles::from_nibbles([0x1, 0x2]), node12.clone()),
979 (Nibbles::from_nibbles([0x2]), node2.clone()),
980 (Nibbles::from_nibbles([0x2, 0x1]), node21.clone()),
981 ]);
982
983 let cursor = create_mock_cursor(trie_nodes);
984 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
985 let mut outputs = Vec::new();
986
987 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1, 0x1]), node111).unwrap();
990 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1, 0x2]), node112).unwrap();
991 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1]), node11).unwrap();
992 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x2]), node12).unwrap();
993 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
994 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2, 0x1]), node21).unwrap();
995 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2]), node2).unwrap();
996 verifier.next(&mut outputs, Nibbles::new(), node_root).unwrap();
997 verifier.finalize(&mut outputs).unwrap();
998
999 if !outputs.is_empty() {
1001 eprintln!(
1002 "Test test_single_verifier_complex_depth_first failed with {} outputs:",
1003 outputs.len()
1004 );
1005 for inc in &outputs {
1006 eprintln!(" {:?}", inc);
1007 }
1008 }
1009 assert!(outputs.is_empty());
1010 }
1011}