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 if let Some((path, node)) = storage_updates.pop() {
78 let node = BranchNode::Storage(*account, path, node);
79 return Some(Ok(node))
80 }
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<T: TrieCursorFactory, H> {
305 trie_cursor_factory: T,
306 hashed_cursor_factory: H,
307 branch_node_iter: StateRootBranchNodesIter<H>,
308 outputs: Vec<Output>,
309 account: SingleVerifier<DepthFirstTrieIterator<T::AccountTrieCursor>>,
310 storage: Option<(B256, SingleVerifier<DepthFirstTrieIterator<T::StorageTrieCursor>>)>,
311 complete: bool,
312}
313
314impl<T: TrieCursorFactory + Clone, H: HashedCursorFactory + Clone> Verifier<T, H> {
315 pub fn new(trie_cursor_factory: T, hashed_cursor_factory: H) -> Result<Self, DatabaseError> {
317 Ok(Self {
318 trie_cursor_factory: trie_cursor_factory.clone(),
319 hashed_cursor_factory: hashed_cursor_factory.clone(),
320 branch_node_iter: StateRootBranchNodesIter::new(hashed_cursor_factory),
321 outputs: Default::default(),
322 account: SingleVerifier::new(None, trie_cursor_factory.account_trie_cursor()?)?,
323 storage: None,
324 complete: false,
325 })
326 }
327}
328
329impl<T: TrieCursorFactory, H: HashedCursorFactory + Clone> Verifier<T, H> {
330 fn new_storage(
331 &mut self,
332 account: B256,
333 path: Nibbles,
334 node: BranchNodeCompact,
335 ) -> Result<(), DatabaseError> {
336 let trie_cursor = self.trie_cursor_factory.storage_trie_cursor(account)?;
337 let mut storage = SingleVerifier::new(Some(account), trie_cursor)?;
338 storage.next(&mut self.outputs, path, node)?;
339 self.storage = Some((account, storage));
340 Ok(())
341 }
342
343 fn verify_empty_storages(
348 &mut self,
349 last_account: B256,
350 next_account: B256,
351 start_inclusive: bool,
352 end_inclusive: bool,
353 ) -> Result<(), DatabaseError> {
354 let mut account_cursor = self.hashed_cursor_factory.hashed_account_cursor()?;
355 let mut account_seeked = false;
356
357 if !start_inclusive {
358 account_seeked = true;
359 account_cursor.seek(last_account)?;
360 }
361
362 loop {
363 let Some((curr_account, _)) = (if account_seeked {
364 account_cursor.next()?
365 } else {
366 account_seeked = true;
367 account_cursor.seek(last_account)?
368 }) else {
369 return Ok(())
370 };
371
372 if curr_account < next_account || (end_inclusive && curr_account == next_account) {
373 trace!(target: "trie::verify", account = ?curr_account, "Verying account has empty storage");
374
375 let mut storage_cursor =
376 self.trie_cursor_factory.storage_trie_cursor(curr_account)?;
377 let mut seeked = false;
378 while let Some((path, node)) = if seeked {
379 storage_cursor.next()?
380 } else {
381 seeked = true;
382 storage_cursor.seek(Nibbles::new())?
383 } {
384 self.outputs.push(Output::StorageExtra(curr_account, path, node));
385 }
386 } else {
387 return Ok(())
388 }
389 }
390 }
391
392 fn try_next(&mut self) -> Result<(), StateRootError> {
393 match self.branch_node_iter.next().transpose()? {
394 None => {
395 self.account.finalize(&mut self.outputs)?;
396 if let Some((prev_account, storage)) = self.storage.as_mut() {
397 storage.finalize(&mut self.outputs)?;
398
399 let prev_account = *prev_account;
402
403 let mut max_account = B256::ZERO;
405 max_account.reverse();
406
407 self.verify_empty_storages(prev_account, max_account, false, true)?;
408 }
409 self.complete = true;
410 }
411 Some(BranchNode::Account(path, node)) => {
412 trace!(target: "trie::verify", ?path, "Account node from state root");
413 self.account.next(&mut self.outputs, path, node)?;
414 if !path.is_empty() {
416 self.outputs.push(Output::Progress(path));
417 }
418 }
419 Some(BranchNode::Storage(account, path, node)) => {
420 trace!(target: "trie::verify", ?account, ?path, "Storage node from state root");
421 match self.storage.as_mut() {
422 None => {
423 self.verify_empty_storages(B256::ZERO, account, true, false)?;
425 self.new_storage(account, path, node)?;
426 }
427 Some((prev_account, storage)) if *prev_account == account => {
428 storage.next(&mut self.outputs, path, node)?;
429 }
430 Some((prev_account, storage)) => {
431 storage.finalize(&mut self.outputs)?;
432 let prev_account = *prev_account;
434 self.verify_empty_storages(prev_account, account, false, false)?;
435 self.new_storage(account, path, node)?;
436 }
437 }
438 }
439 }
440
441 self.outputs.reverse();
444 Ok(())
445 }
446}
447
448impl<T: TrieCursorFactory, H: HashedCursorFactory + Clone> Iterator for Verifier<T, H> {
449 type Item = Result<Output, StateRootError>;
450
451 fn next(&mut self) -> Option<Self::Item> {
452 loop {
453 if let Some(output) = self.outputs.pop() {
454 return Some(Ok(output))
455 }
456
457 if self.complete {
458 return None
459 }
460
461 if let Err(err) = self.try_next() {
462 return Some(Err(err))
463 }
464 }
465 }
466}
467
468#[cfg(test)]
469mod tests {
470 use super::*;
471 use crate::{
472 hashed_cursor::mock::MockHashedCursorFactory,
473 trie_cursor::mock::{MockTrieCursor, MockTrieCursorFactory},
474 };
475 use alloy_primitives::{address, keccak256, map::B256Map, U256};
476 use alloy_trie::TrieMask;
477 use assert_matches::assert_matches;
478 use reth_primitives_traits::Account;
479 use std::collections::BTreeMap;
480
481 fn test_branch_node(
483 state_mask: u16,
484 tree_mask: u16,
485 hash_mask: u16,
486 hashes: Vec<B256>,
487 ) -> BranchNodeCompact {
488 let expected_hashes = hash_mask.count_ones() as usize;
490 let mut final_hashes = hashes;
491 let mut counter = 100u8;
492 while final_hashes.len() < expected_hashes {
493 final_hashes.push(B256::from([counter; 32]));
494 counter += 1;
495 }
496 final_hashes.truncate(expected_hashes);
497
498 BranchNodeCompact::new(
499 TrieMask::new(state_mask),
500 TrieMask::new(tree_mask),
501 TrieMask::new(hash_mask),
502 final_hashes,
503 None,
504 )
505 }
506
507 fn create_mock_cursor(trie_nodes: BTreeMap<Nibbles, BranchNodeCompact>) -> MockTrieCursor {
509 let factory = MockTrieCursorFactory::new(trie_nodes, B256Map::default());
510 factory.account_trie_cursor().unwrap()
511 }
512
513 #[test]
514 fn test_state_root_branch_nodes_iter_empty() {
515 let factory = MockHashedCursorFactory::new(BTreeMap::new(), B256Map::default());
517 let mut iter = StateRootBranchNodesIter::new(factory);
518
519 let mut count = 0;
521 for result in iter.by_ref() {
522 assert!(result.is_ok(), "Unexpected error: {:?}", result.unwrap_err());
523 count += 1;
524 assert!(count <= 1000, "Too many iterations");
526 }
527
528 assert!(iter.complete);
529 }
530
531 #[test]
532 fn test_state_root_branch_nodes_iter_basic() {
533 let mut accounts = BTreeMap::new();
535 let mut storage_tries = B256Map::default();
536
537 let addr1 = keccak256(address!("0000000000000000000000000000000000000001"));
539 accounts.insert(
540 addr1,
541 Account {
542 nonce: 1,
543 balance: U256::from(1000),
544 bytecode_hash: Some(keccak256(b"code1")),
545 },
546 );
547
548 let mut storage1 = BTreeMap::new();
550 storage1.insert(keccak256(B256::from(U256::from(1))), U256::from(100));
551 storage1.insert(keccak256(B256::from(U256::from(2))), U256::from(200));
552 storage_tries.insert(addr1, storage1);
553
554 let factory = MockHashedCursorFactory::new(accounts, storage_tries);
555 let mut iter = StateRootBranchNodesIter::new(factory);
556
557 let mut account_paths = Vec::new();
559 let mut storage_paths_by_account: B256Map<Vec<Nibbles>> = B256Map::default();
560 let mut iterations = 0;
561
562 for result in iter.by_ref() {
563 iterations += 1;
564 assert!(iterations <= 10000, "Too many iterations - possible infinite loop");
565
566 match result {
567 Ok(BranchNode::Account(path, _)) => {
568 account_paths.push(path);
569 }
570 Ok(BranchNode::Storage(account, path, _)) => {
571 storage_paths_by_account.entry(account).or_default().push(path);
572 }
573 Err(e) => panic!("Unexpected error: {:?}", e),
574 }
575 }
576
577 for i in 1..account_paths.len() {
579 assert!(
580 account_paths[i - 1] < account_paths[i],
581 "Account paths should be in ascending order"
582 );
583 }
584
585 for (account, paths) in storage_paths_by_account {
587 for i in 1..paths.len() {
588 assert!(
589 paths[i - 1] < paths[i],
590 "Storage paths for account {:?} should be in ascending order",
591 account
592 );
593 }
594 }
595
596 assert!(iter.complete);
597 }
598
599 #[test]
600 fn test_state_root_branch_nodes_iter_multiple_accounts() {
601 let mut accounts = BTreeMap::new();
603 let mut storage_tries = B256Map::default();
604
605 for i in 1u8..=3 {
607 let addr = keccak256([i; 20]);
608 accounts.insert(
609 addr,
610 Account {
611 nonce: i as u64,
612 balance: U256::from(i as u64 * 1000),
613 bytecode_hash: (i == 2).then(|| keccak256([i])),
614 },
615 );
616
617 let mut storage = BTreeMap::new();
619 for j in 0..i {
620 storage.insert(keccak256(B256::from(U256::from(j))), U256::from(j as u64 * 10));
621 }
622 if !storage.is_empty() {
623 storage_tries.insert(addr, storage);
624 }
625 }
626
627 let factory = MockHashedCursorFactory::new(accounts, storage_tries);
628 let mut iter = StateRootBranchNodesIter::new(factory);
629
630 let mut seen_storage_accounts = Vec::new();
632 let mut current_storage_account = None;
633 let mut iterations = 0;
634
635 for result in iter.by_ref() {
636 iterations += 1;
637 assert!(iterations <= 10000, "Too many iterations");
638
639 match result {
640 Ok(BranchNode::Storage(account, _, _)) => {
641 if current_storage_account != Some(account) {
642 assert!(
644 !seen_storage_accounts.contains(&account),
645 "Should not revisit storage account {:?}",
646 account
647 );
648 seen_storage_accounts.push(account);
649 current_storage_account = Some(account);
650 }
651 }
652 Ok(BranchNode::Account(_, _)) => {
653 }
655 Err(e) => panic!("Unexpected error: {:?}", e),
656 }
657 }
658
659 assert!(iter.complete);
660 }
661
662 #[test]
663 fn test_single_verifier_new() {
664 let trie_nodes = BTreeMap::from([(
666 Nibbles::from_nibbles([0x1]),
667 test_branch_node(0b1111, 0, 0, vec![]),
668 )]);
669
670 let cursor = create_mock_cursor(trie_nodes);
671 let verifier = SingleVerifier::new(None, cursor).unwrap();
672
673 assert!(verifier.curr.is_some());
675 }
676
677 #[test]
678 fn test_single_verifier_next_exact_match() {
679 let node1 = test_branch_node(0b1111, 0, 0b1111, vec![B256::from([1u8; 32])]);
681 let node2 = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::from([2u8; 32])]);
682
683 let trie_nodes = BTreeMap::from([
684 (Nibbles::from_nibbles([0x1]), node1.clone()),
685 (Nibbles::from_nibbles([0x2]), node2),
686 ]);
687
688 let cursor = create_mock_cursor(trie_nodes);
689 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
690 let mut outputs = Vec::new();
691
692 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
694
695 assert!(outputs.is_empty());
697 }
698
699 #[test]
700 fn test_single_verifier_next_wrong_value() {
701 let node_in_trie = test_branch_node(0b1111, 0, 0b1111, vec![B256::from([1u8; 32])]);
703 let node_expected = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::from([2u8; 32])]);
704
705 let trie_nodes = BTreeMap::from([(Nibbles::from_nibbles([0x1]), node_in_trie.clone())]);
706
707 let cursor = create_mock_cursor(trie_nodes);
708 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
709 let mut outputs = Vec::new();
710
711 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node_expected.clone()).unwrap();
713
714 assert_eq!(outputs.len(), 1);
716 assert_matches!(
717 &outputs[0],
718 Output::AccountWrong { path, expected, found }
719 if *path == Nibbles::from_nibbles([0x1]) && *expected == node_expected && *found == node_in_trie
720 );
721 }
722
723 #[test]
724 fn test_single_verifier_next_missing() {
725 let node1 = test_branch_node(0b1111, 0, 0b1111, vec![B256::from([1u8; 32])]);
727 let node_missing = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::from([2u8; 32])]);
728
729 let trie_nodes = BTreeMap::from([(Nibbles::from_nibbles([0x3]), node1)]);
730
731 let cursor = create_mock_cursor(trie_nodes);
732 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
733 let mut outputs = Vec::new();
734
735 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node_missing.clone()).unwrap();
737
738 assert_eq!(outputs.len(), 1);
740 assert_matches!(
741 &outputs[0],
742 Output::AccountMissing(path, node)
743 if *path == Nibbles::from_nibbles([0x1]) && *node == node_missing
744 );
745 }
746
747 #[test]
748 fn test_single_verifier_next_extra() {
749 let node_root = test_branch_node(0b1110, 0, 0b1110, vec![]); let node1 = test_branch_node(0b0001, 0, 0b0001, vec![]);
753 let node2 = test_branch_node(0b0010, 0, 0b0010, vec![]);
754 let node3 = test_branch_node(0b0100, 0, 0b0100, vec![]);
755
756 let trie_nodes = BTreeMap::from([
757 (Nibbles::new(), node_root.clone()),
758 (Nibbles::from_nibbles([0x1]), node1.clone()),
759 (Nibbles::from_nibbles([0x2]), node2.clone()),
760 (Nibbles::from_nibbles([0x3]), node3.clone()),
761 ]);
762
763 let cursor = create_mock_cursor(trie_nodes);
764 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
765 let mut outputs = Vec::new();
766
767 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
770 verifier.next(&mut outputs, Nibbles::from_nibbles([0x3]), node3).unwrap();
771 verifier.finalize(&mut outputs).unwrap();
772
773 if outputs.len() != 2 {
775 eprintln!("Expected 2 outputs, got {}:", outputs.len());
776 for inc in &outputs {
777 eprintln!(" {:?}", inc);
778 }
779 }
780 assert_eq!(outputs.len(), 2);
781 assert_matches!(
782 &outputs[0],
783 Output::AccountExtra(path, node)
784 if *path == Nibbles::from_nibbles([0x2]) && *node == node2
785 );
786 assert_matches!(
787 &outputs[1],
788 Output::AccountExtra(path, node)
789 if *path == Nibbles::new() && *node == node_root
790 );
791 }
792
793 #[test]
794 fn test_single_verifier_finalize() {
795 let node_root = test_branch_node(0b1110, 0, 0b1110, vec![]); let node1 = test_branch_node(0b0001, 0, 0b0001, vec![]);
798 let node2 = test_branch_node(0b0010, 0, 0b0010, vec![]);
799 let node3 = test_branch_node(0b0100, 0, 0b0100, vec![]);
800
801 let trie_nodes = BTreeMap::from([
802 (Nibbles::new(), node_root.clone()),
803 (Nibbles::from_nibbles([0x1]), node1.clone()),
804 (Nibbles::from_nibbles([0x2]), node2.clone()),
805 (Nibbles::from_nibbles([0x3]), node3.clone()),
806 ]);
807
808 let cursor = create_mock_cursor(trie_nodes);
809 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
810 let mut outputs = Vec::new();
811
812 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
815 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2]), node2).unwrap();
816 assert!(outputs.is_empty());
817
818 verifier.finalize(&mut outputs).unwrap();
820
821 assert_eq!(outputs.len(), 2);
823 assert_matches!(
824 &outputs[0],
825 Output::AccountExtra(path, node)
826 if *path == Nibbles::from_nibbles([0x3]) && *node == node3
827 );
828 assert_matches!(
829 &outputs[1],
830 Output::AccountExtra(path, node)
831 if *path == Nibbles::new() && *node == node_root
832 );
833 }
834
835 #[test]
836 fn test_single_verifier_storage_trie() {
837 let account = B256::from([42u8; 32]);
839 let node = test_branch_node(0b1111, 0, 0b1111, vec![B256::from([1u8; 32])]);
840
841 let trie_nodes = BTreeMap::from([(Nibbles::from_nibbles([0x1]), node)]);
842
843 let cursor = create_mock_cursor(trie_nodes);
844 let mut verifier = SingleVerifier::new(Some(account), cursor).unwrap();
845 let mut outputs = Vec::new();
846
847 let missing_node = test_branch_node(0b0101, 0b0001, 0b0100, vec![B256::from([2u8; 32])]);
849 verifier.next(&mut outputs, Nibbles::from_nibbles([0x0]), missing_node.clone()).unwrap();
850
851 assert_eq!(outputs.len(), 1);
853 assert_matches!(
854 &outputs[0],
855 Output::StorageMissing(acc, path, node)
856 if *acc == account && *path == Nibbles::from_nibbles([0x0]) && *node == missing_node
857 );
858 }
859
860 #[test]
861 fn test_single_verifier_empty_trie() {
862 let trie_nodes = BTreeMap::new();
864 let cursor = create_mock_cursor(trie_nodes);
865 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
866 let mut outputs = Vec::new();
867
868 let node = test_branch_node(0b1111, 0, 0b1111, vec![B256::from([1u8; 32])]);
870 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node.clone()).unwrap();
871
872 assert_eq!(outputs.len(), 1);
873 assert_matches!(
874 &outputs[0],
875 Output::AccountMissing(path, n)
876 if *path == Nibbles::from_nibbles([0x1]) && *n == node
877 );
878 }
879
880 #[test]
881 fn test_single_verifier_depth_first_ordering() {
882 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([
894 (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()), ]);
900
901 let cursor = create_mock_cursor(trie_nodes);
902 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
903 let mut outputs = Vec::new();
904
905 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1]), node11).unwrap();
908 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x2]), node12).unwrap();
909 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
910 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2]), node2).unwrap();
911 verifier.next(&mut outputs, Nibbles::new(), node_root).unwrap();
912 verifier.finalize(&mut outputs).unwrap();
913
914 if !outputs.is_empty() {
916 eprintln!(
917 "Test test_single_verifier_depth_first_ordering failed with {} outputs:",
918 outputs.len()
919 );
920 for inc in &outputs {
921 eprintln!(" {:?}", inc);
922 }
923 }
924 assert!(outputs.is_empty());
925 }
926
927 #[test]
928 fn test_single_verifier_wrong_depth_first_order() {
929 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([
936 (Nibbles::new(), node_root.clone()),
937 (Nibbles::from_nibbles([0x1]), node1.clone()),
938 (Nibbles::from_nibbles([0x1, 0x1]), node11.clone()),
939 ]);
940
941 let cursor = create_mock_cursor(trie_nodes);
942 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
943 let mut outputs = Vec::new();
944
945 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1]), node11).unwrap();
949 verifier.next(&mut outputs, Nibbles::new(), node_root).unwrap();
950 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
951
952 assert!(!outputs.is_empty());
954 }
955
956 #[test]
957 fn test_single_verifier_complex_depth_first() {
958 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([
971 (Nibbles::new(), node_root.clone()),
972 (Nibbles::from_nibbles([0x1]), node1.clone()),
973 (Nibbles::from_nibbles([0x1, 0x1]), node11.clone()),
974 (Nibbles::from_nibbles([0x1, 0x1, 0x1]), node111.clone()),
975 (Nibbles::from_nibbles([0x1, 0x1, 0x2]), node112.clone()),
976 (Nibbles::from_nibbles([0x1, 0x2]), node12.clone()),
977 (Nibbles::from_nibbles([0x2]), node2.clone()),
978 (Nibbles::from_nibbles([0x2, 0x1]), node21.clone()),
979 ]);
980
981 let cursor = create_mock_cursor(trie_nodes);
982 let mut verifier = SingleVerifier::new(None, cursor).unwrap();
983 let mut outputs = Vec::new();
984
985 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1, 0x1]), node111).unwrap();
988 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1, 0x2]), node112).unwrap();
989 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x1]), node11).unwrap();
990 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1, 0x2]), node12).unwrap();
991 verifier.next(&mut outputs, Nibbles::from_nibbles([0x1]), node1).unwrap();
992 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2, 0x1]), node21).unwrap();
993 verifier.next(&mut outputs, Nibbles::from_nibbles([0x2]), node2).unwrap();
994 verifier.next(&mut outputs, Nibbles::new(), node_root).unwrap();
995 verifier.finalize(&mut outputs).unwrap();
996
997 if !outputs.is_empty() {
999 eprintln!(
1000 "Test test_single_verifier_complex_depth_first failed with {} outputs:",
1001 outputs.len()
1002 );
1003 for inc in &outputs {
1004 eprintln!(" {:?}", inc);
1005 }
1006 }
1007 assert!(outputs.is_empty());
1008 }
1009}