1use crate::{
2 provider::{RevealedNode, TrieNodeProvider},
3 LeafLookup, LeafLookupError, RevealedSparseNode, SparseTrieInterface, SparseTrieUpdates,
4 TrieMasks,
5};
6use alloc::{
7 borrow::Cow,
8 boxed::Box,
9 fmt,
10 string::{String, ToString},
11 vec,
12 vec::Vec,
13};
14use alloy_primitives::{
15 hex, keccak256,
16 map::{Entry, HashMap, HashSet},
17 B256,
18};
19use alloy_rlp::Decodable;
20use reth_execution_errors::{SparseTrieErrorKind, SparseTrieResult};
21use reth_trie_common::{
22 prefix_set::{PrefixSet, PrefixSetMut},
23 BranchNodeCompact, BranchNodeRef, ExtensionNodeRef, LeafNodeRef, Nibbles, RlpNode, TrieMask,
24 TrieNode, CHILD_INDEX_RANGE, EMPTY_ROOT_HASH,
25};
26use smallvec::SmallVec;
27use tracing::{trace, warn};
28
29const SPARSE_TRIE_SUBTRIE_HASHES_LEVEL: usize = 2;
32
33#[derive(PartialEq, Eq, Debug)]
46pub enum SparseTrie<T = SerialSparseTrie> {
47 Blind(Option<Box<T>>),
55 Revealed(Box<T>),
61}
62
63impl<T: Default> Default for SparseTrie<T> {
64 fn default() -> Self {
65 Self::Blind(None)
66 }
67}
68
69impl<T: SparseTrieInterface + Default> SparseTrie<T> {
70 pub fn revealed_empty() -> Self {
81 Self::Revealed(Box::default())
82 }
83
84 pub fn reveal_root(
96 &mut self,
97 root: TrieNode,
98 masks: TrieMasks,
99 retain_updates: bool,
100 ) -> SparseTrieResult<&mut T> {
101 if self.is_blind() {
104 let mut revealed_trie = if let Self::Blind(Some(cleared_trie)) = core::mem::take(self) {
105 cleared_trie
106 } else {
107 Box::default()
108 };
109
110 *revealed_trie = revealed_trie.with_root(root, masks, retain_updates)?;
111 *self = Self::Revealed(revealed_trie);
112 }
113
114 Ok(self.as_revealed_mut().unwrap())
115 }
116}
117
118impl<T: SparseTrieInterface> SparseTrie<T> {
119 pub const fn blind() -> Self {
132 Self::Blind(None)
133 }
134
135 pub const fn is_blind(&self) -> bool {
137 matches!(self, Self::Blind(_))
138 }
139
140 pub const fn is_revealed(&self) -> bool {
142 matches!(self, Self::Revealed(_))
143 }
144
145 pub const fn as_revealed_ref(&self) -> Option<&T> {
149 if let Self::Revealed(revealed) = self {
150 Some(revealed)
151 } else {
152 None
153 }
154 }
155
156 pub fn as_revealed_mut(&mut self) -> Option<&mut T> {
160 if let Self::Revealed(revealed) = self {
161 Some(revealed)
162 } else {
163 None
164 }
165 }
166
167 pub fn wipe(&mut self) -> SparseTrieResult<()> {
172 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
173 revealed.wipe();
174 Ok(())
175 }
176
177 pub fn root(&mut self) -> Option<B256> {
188 Some(self.as_revealed_mut()?.root())
189 }
190
191 pub fn root_with_updates(&mut self) -> Option<(B256, SparseTrieUpdates)> {
204 let revealed = self.as_revealed_mut()?;
205 Some((revealed.root(), revealed.take_updates()))
206 }
207
208 pub fn clear(self) -> Self {
212 match self {
213 Self::Blind(_) => self,
214 Self::Revealed(mut trie) => {
215 trie.clear();
216 Self::Blind(Some(trie))
217 }
218 }
219 }
220
221 pub fn update_leaf(
227 &mut self,
228 path: Nibbles,
229 value: Vec<u8>,
230 provider: impl TrieNodeProvider,
231 ) -> SparseTrieResult<()> {
232 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
233 revealed.update_leaf(path, value, provider)?;
234 Ok(())
235 }
236
237 pub fn remove_leaf(
243 &mut self,
244 path: &Nibbles,
245 provider: impl TrieNodeProvider,
246 ) -> SparseTrieResult<()> {
247 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
248 revealed.remove_leaf(path, provider)?;
249 Ok(())
250 }
251}
252
253#[derive(Clone, PartialEq, Eq)]
267pub struct SerialSparseTrie {
268 nodes: HashMap<Nibbles, SparseNode>,
271 branch_node_tree_masks: HashMap<Nibbles, TrieMask>,
273 branch_node_hash_masks: HashMap<Nibbles, TrieMask>,
275 values: HashMap<Nibbles, Vec<u8>>,
278 prefix_set: PrefixSetMut,
281 updates: Option<SparseTrieUpdates>,
283 rlp_buf: Vec<u8>,
285}
286
287impl fmt::Debug for SerialSparseTrie {
288 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
289 f.debug_struct("SerialSparseTrie")
290 .field("nodes", &self.nodes)
291 .field("branch_tree_masks", &self.branch_node_tree_masks)
292 .field("branch_hash_masks", &self.branch_node_hash_masks)
293 .field("values", &self.values)
294 .field("prefix_set", &self.prefix_set)
295 .field("updates", &self.updates)
296 .field("rlp_buf", &hex::encode(&self.rlp_buf))
297 .finish_non_exhaustive()
298 }
299}
300
301fn encode_nibbles(nibbles: &Nibbles) -> String {
303 let encoded = hex::encode(nibbles.pack());
304 encoded[..nibbles.len()].to_string()
305}
306
307impl fmt::Display for SerialSparseTrie {
308 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309 let mut stack = Vec::new();
311 let mut visited = HashSet::new();
312
313 const INDENT: &str = " ";
315
316 stack.push((Nibbles::default(), self.nodes_ref().get(&Nibbles::default()).unwrap(), 0));
318
319 while let Some((path, node, depth)) = stack.pop() {
320 if !visited.insert(path) {
321 continue;
322 }
323
324 if f.alternate() {
326 write!(f, "{}", INDENT.repeat(depth))?;
327 }
328
329 let packed_path = if depth == 0 { String::from("Root") } else { encode_nibbles(&path) };
330
331 match node {
332 SparseNode::Empty | SparseNode::Hash(_) => {
333 writeln!(f, "{packed_path} -> {node:?}")?;
334 }
335 SparseNode::Leaf { key, .. } => {
336 let mut full_path = path;
338 full_path.extend(key);
339 let packed_path = encode_nibbles(&full_path);
340
341 writeln!(f, "{packed_path} -> {node:?}")?;
342 }
343 SparseNode::Extension { key, .. } => {
344 writeln!(f, "{packed_path} -> {node:?}")?;
345
346 let mut child_path = path;
348 child_path.extend(key);
349 if let Some(child_node) = self.nodes_ref().get(&child_path) {
350 stack.push((child_path, child_node, depth + 1));
351 }
352 }
353 SparseNode::Branch { state_mask, .. } => {
354 writeln!(f, "{packed_path} -> {node:?}")?;
355
356 for i in CHILD_INDEX_RANGE.rev() {
357 if state_mask.is_bit_set(i) {
358 let mut child_path = path;
359 child_path.push_unchecked(i);
360 if let Some(child_node) = self.nodes_ref().get(&child_path) {
361 stack.push((child_path, child_node, depth + 1));
362 }
363 }
364 }
365 }
366 }
367 }
368
369 Ok(())
370 }
371}
372
373impl Default for SerialSparseTrie {
374 fn default() -> Self {
375 Self {
376 nodes: HashMap::from_iter([(Nibbles::default(), SparseNode::Empty)]),
377 branch_node_tree_masks: HashMap::default(),
378 branch_node_hash_masks: HashMap::default(),
379 values: HashMap::default(),
380 prefix_set: PrefixSetMut::default(),
381 updates: None,
382 rlp_buf: Vec::new(),
383 }
384 }
385}
386
387impl SparseTrieInterface for SerialSparseTrie {
388 fn with_root(
389 mut self,
390 root: TrieNode,
391 masks: TrieMasks,
392 retain_updates: bool,
393 ) -> SparseTrieResult<Self> {
394 self = self.with_updates(retain_updates);
395
396 let path = Nibbles::default();
399 let _removed_root = self.nodes.remove(&path).expect("root node should exist");
400 debug_assert_eq!(_removed_root, SparseNode::Empty);
401
402 self.reveal_node(path, root, masks)?;
403 Ok(self)
404 }
405
406 fn with_updates(mut self, retain_updates: bool) -> Self {
407 if retain_updates {
408 self.updates = Some(SparseTrieUpdates::default());
409 }
410 self
411 }
412
413 fn reserve_nodes(&mut self, additional: usize) {
414 self.nodes.reserve(additional);
415 }
416 fn reveal_node(
417 &mut self,
418 path: Nibbles,
419 node: TrieNode,
420 masks: TrieMasks,
421 ) -> SparseTrieResult<()> {
422 trace!(target: "trie::sparse", ?path, ?node, ?masks, "reveal_node called");
423
424 if self.nodes.get(&path).is_some_and(|node| !node.is_hash()) {
426 return Ok(())
427 }
428
429 if let Some(tree_mask) = masks.tree_mask {
430 self.branch_node_tree_masks.insert(path, tree_mask);
431 }
432 if let Some(hash_mask) = masks.hash_mask {
433 self.branch_node_hash_masks.insert(path, hash_mask);
434 }
435
436 match node {
437 TrieNode::EmptyRoot => {
438 debug_assert!(path.is_empty());
440 self.nodes.insert(path, SparseNode::Empty);
441 }
442 TrieNode::Branch(branch) => {
443 let mut stack_ptr = branch.as_ref().first_child_index();
445 for idx in CHILD_INDEX_RANGE {
446 if branch.state_mask.is_bit_set(idx) {
447 let mut child_path = path;
448 child_path.push_unchecked(idx);
449 self.reveal_node_or_hash(child_path, &branch.stack[stack_ptr])?;
451 stack_ptr += 1;
452 }
453 }
454 match self.nodes.entry(path) {
457 Entry::Occupied(mut entry) => match entry.get() {
458 SparseNode::Hash(hash) => {
460 entry.insert(SparseNode::Branch {
461 state_mask: branch.state_mask,
462 hash: Some(*hash),
465 store_in_db_trie: Some(
466 masks.hash_mask.is_some_and(|mask| !mask.is_empty()) ||
467 masks.tree_mask.is_some_and(|mask| !mask.is_empty()),
468 ),
469 });
470 }
471 SparseNode::Branch { .. } | SparseNode::Extension { .. } => {}
474 node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => {
476 return Err(SparseTrieErrorKind::Reveal {
477 path: *entry.key(),
478 node: Box::new(node.clone()),
479 }
480 .into())
481 }
482 },
483 Entry::Vacant(entry) => {
484 entry.insert(SparseNode::new_branch(branch.state_mask));
485 }
486 }
487 }
488 TrieNode::Extension(ext) => match self.nodes.entry(path) {
489 Entry::Occupied(mut entry) => match entry.get() {
490 SparseNode::Hash(hash) => {
492 let mut child_path = *entry.key();
493 child_path.extend(&ext.key);
494 entry.insert(SparseNode::Extension {
495 key: ext.key,
496 hash: Some(*hash),
499 store_in_db_trie: None,
500 });
501 self.reveal_node_or_hash(child_path, &ext.child)?;
502 }
503 SparseNode::Extension { .. } | SparseNode::Branch { .. } => {}
506 node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => {
508 return Err(SparseTrieErrorKind::Reveal {
509 path: *entry.key(),
510 node: Box::new(node.clone()),
511 }
512 .into())
513 }
514 },
515 Entry::Vacant(entry) => {
516 let mut child_path = *entry.key();
517 child_path.extend(&ext.key);
518 entry.insert(SparseNode::new_ext(ext.key));
519 self.reveal_node_or_hash(child_path, &ext.child)?;
520 }
521 },
522 TrieNode::Leaf(leaf) => match self.nodes.entry(path) {
523 Entry::Occupied(mut entry) => match entry.get() {
524 SparseNode::Hash(hash) => {
526 let mut full = *entry.key();
527 full.extend(&leaf.key);
528 self.values.insert(full, leaf.value.clone());
529 entry.insert(SparseNode::Leaf {
530 key: leaf.key,
531 hash: Some(*hash),
534 });
535 }
536 SparseNode::Leaf { .. } => {}
538 node @ (SparseNode::Empty |
540 SparseNode::Extension { .. } |
541 SparseNode::Branch { .. }) => {
542 return Err(SparseTrieErrorKind::Reveal {
543 path: *entry.key(),
544 node: Box::new(node.clone()),
545 }
546 .into())
547 }
548 },
549 Entry::Vacant(entry) => {
550 let mut full = *entry.key();
551 full.extend(&leaf.key);
552 entry.insert(SparseNode::new_leaf(leaf.key));
553 self.values.insert(full, leaf.value.clone());
554 }
555 },
556 }
557
558 Ok(())
559 }
560
561 fn reveal_nodes(&mut self, mut nodes: Vec<RevealedSparseNode>) -> SparseTrieResult<()> {
562 nodes.sort_unstable_by_key(|node| node.path);
563 for node in nodes {
564 self.reveal_node(node.path, node.node, node.masks)?;
565 }
566 Ok(())
567 }
568
569 fn update_leaf<P: TrieNodeProvider>(
570 &mut self,
571 full_path: Nibbles,
572 value: Vec<u8>,
573 provider: P,
574 ) -> SparseTrieResult<()> {
575 trace!(target: "trie::sparse", ?full_path, ?value, "update_leaf called");
576
577 self.prefix_set.insert(full_path);
578 let existing = self.values.insert(full_path, value);
579 if existing.is_some() {
580 return Ok(())
582 }
583
584 let mut current = Nibbles::default();
585 while let Some(node) = self.nodes.get_mut(¤t) {
586 match node {
587 SparseNode::Empty => {
588 *node = SparseNode::new_leaf(full_path);
589 break
590 }
591 &mut SparseNode::Hash(hash) => {
592 return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into())
593 }
594 SparseNode::Leaf { key: current_key, .. } => {
595 current.extend(current_key);
596
597 if current == full_path {
599 unreachable!("we already checked leaf presence in the beginning");
600 }
601
602 let common = current.common_prefix_length(&full_path);
604
605 let new_ext_key = current.slice(current.len() - current_key.len()..common);
607 *node = SparseNode::new_ext(new_ext_key);
608
609 self.nodes.reserve(3);
611 self.nodes.insert(
612 current.slice(..common),
613 SparseNode::new_split_branch(
614 current.get_unchecked(common),
615 full_path.get_unchecked(common),
616 ),
617 );
618 self.nodes.insert(
619 full_path.slice(..=common),
620 SparseNode::new_leaf(full_path.slice(common + 1..)),
621 );
622 self.nodes.insert(
623 current.slice(..=common),
624 SparseNode::new_leaf(current.slice(common + 1..)),
625 );
626
627 break;
628 }
629 SparseNode::Extension { key, .. } => {
630 current.extend(key);
631
632 if !full_path.starts_with(¤t) {
633 let common = current.common_prefix_length(&full_path);
635 *key = current.slice(current.len() - key.len()..common);
636
637 if self.updates.is_some() {
641 if self.nodes.get(¤t).unwrap().is_hash() {
643 warn!(
644 target: "trie::sparse",
645 leaf_full_path = ?full_path,
646 child_path = ?current,
647 "Extension node child not revealed in update_leaf, falling back to db",
648 );
649 if let Some(RevealedNode { node, tree_mask, hash_mask }) =
650 provider.trie_node(¤t)?
651 {
652 let decoded = TrieNode::decode(&mut &node[..])?;
653 trace!(
654 target: "trie::sparse",
655 ?current,
656 ?decoded,
657 ?tree_mask,
658 ?hash_mask,
659 "Revealing extension node child",
660 );
661 self.reveal_node(
662 current,
663 decoded,
664 TrieMasks { hash_mask, tree_mask },
665 )?;
666 }
667 }
668 }
669
670 self.nodes.reserve(3);
673 let branch = SparseNode::new_split_branch(
674 current.get_unchecked(common),
675 full_path.get_unchecked(common),
676 );
677 self.nodes.insert(current.slice(..common), branch);
678
679 let new_leaf = SparseNode::new_leaf(full_path.slice(common + 1..));
681 self.nodes.insert(full_path.slice(..=common), new_leaf);
682
683 let key = current.slice(common + 1..);
685 if !key.is_empty() {
686 self.nodes.insert(current.slice(..=common), SparseNode::new_ext(key));
687 }
688
689 break;
690 }
691 }
692 SparseNode::Branch { state_mask, .. } => {
693 let nibble = full_path.get_unchecked(current.len());
694 current.push_unchecked(nibble);
695 if !state_mask.is_bit_set(nibble) {
696 state_mask.set_bit(nibble);
697 let new_leaf = SparseNode::new_leaf(full_path.slice(current.len()..));
698 self.nodes.insert(current, new_leaf);
699 break;
700 }
701 }
702 };
703 }
704
705 Ok(())
706 }
707
708 fn remove_leaf<P: TrieNodeProvider>(
709 &mut self,
710 full_path: &Nibbles,
711 provider: P,
712 ) -> SparseTrieResult<()> {
713 trace!(target: "trie::sparse", ?full_path, "remove_leaf called");
714
715 if self.values.remove(full_path).is_none() {
716 if let Some(&SparseNode::Hash(hash)) = self.nodes.get(full_path) {
717 return Err(SparseTrieErrorKind::BlindedNode { path: *full_path, hash }.into())
719 }
720
721 trace!(target: "trie::sparse", ?full_path, "Leaf node is not present in the trie");
722 return Ok(())
724 }
725 self.prefix_set.insert(*full_path);
726
727 let mut removed_nodes = self.take_nodes_for_path(full_path)?;
732 let mut child = removed_nodes.pop().expect("leaf exists");
734 #[cfg(debug_assertions)]
735 {
736 let mut child_path = child.path;
737 let SparseNode::Leaf { key, .. } = &child.node else { panic!("expected leaf node") };
738 child_path.extend(key);
739 assert_eq!(&child_path, full_path);
740 }
741
742 if removed_nodes.is_empty() {
744 debug_assert!(self.nodes.is_empty());
745 self.nodes.insert(Nibbles::default(), SparseNode::Empty);
746
747 return Ok(())
748 }
749
750 while let Some(removed_node) = removed_nodes.pop() {
753 let removed_path = removed_node.path;
754
755 let new_node = match &removed_node.node {
756 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
757 &SparseNode::Hash(hash) => {
758 return Err(SparseTrieErrorKind::BlindedNode { path: removed_path, hash }.into())
759 }
760 SparseNode::Leaf { .. } => {
761 unreachable!("we already popped the leaf node")
762 }
763 SparseNode::Extension { key, .. } => {
764 match &child.node {
767 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
768 &SparseNode::Hash(hash) => {
769 return Err(
770 SparseTrieErrorKind::BlindedNode { path: child.path, hash }.into()
771 )
772 }
773 SparseNode::Leaf { key: leaf_key, .. } => {
779 self.nodes.remove(&child.path);
780
781 let mut new_key = *key;
782 new_key.extend(leaf_key);
783 SparseNode::new_leaf(new_key)
784 }
785 SparseNode::Extension { key: extension_key, .. } => {
788 self.nodes.remove(&child.path);
789
790 let mut new_key = *key;
791 new_key.extend(extension_key);
792 SparseNode::new_ext(new_key)
793 }
794 SparseNode::Branch { .. } => removed_node.node,
796 }
797 }
798 &SparseNode::Branch { mut state_mask, hash: _, store_in_db_trie: _ } => {
799 if let Some(removed_nibble) = removed_node.unset_branch_nibble {
803 state_mask.unset_bit(removed_nibble);
804 }
805
806 if state_mask.count_bits() == 1 {
808 let child_nibble =
809 state_mask.first_set_bit_index().expect("state mask is not empty");
810
811 let mut child_path = removed_path;
813 child_path.push_unchecked(child_nibble);
814
815 trace!(target: "trie::sparse", ?removed_path, ?child_path, "Branch node has only one child");
816
817 if self.nodes.get(&child_path).unwrap().is_hash() {
818 warn!(
819 target: "trie::sparse",
820 ?child_path,
821 leaf_full_path = ?full_path,
822 "Branch node child not revealed in remove_leaf, falling back to db",
823 );
824 if let Some(RevealedNode { node, tree_mask, hash_mask }) =
825 provider.trie_node(&child_path)?
826 {
827 let decoded = TrieNode::decode(&mut &node[..])?;
828 trace!(
829 target: "trie::sparse",
830 ?child_path,
831 ?decoded,
832 ?tree_mask,
833 ?hash_mask,
834 "Revealing remaining blinded branch child"
835 );
836 self.reveal_node(
837 child_path,
838 decoded,
839 TrieMasks { hash_mask, tree_mask },
840 )?;
841 }
842 }
843
844 let child = self.nodes.get(&child_path).unwrap();
846
847 let mut delete_child = false;
848 let new_node = match child {
849 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
850 &SparseNode::Hash(hash) => {
851 return Err(SparseTrieErrorKind::BlindedNode {
852 path: child_path,
853 hash,
854 }
855 .into())
856 }
857 SparseNode::Leaf { key, .. } => {
861 delete_child = true;
862
863 let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]);
864 new_key.extend(key);
865 SparseNode::new_leaf(new_key)
866 }
867 SparseNode::Extension { key, .. } => {
871 delete_child = true;
872
873 let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]);
874 new_key.extend(key);
875 SparseNode::new_ext(new_key)
876 }
877 SparseNode::Branch { .. } => {
880 SparseNode::new_ext(Nibbles::from_nibbles_unchecked([child_nibble]))
881 }
882 };
883
884 if delete_child {
885 self.nodes.remove(&child_path);
886 }
887
888 if let Some(updates) = self.updates.as_mut() {
889 updates.updated_nodes.remove(&removed_path);
890 updates.removed_nodes.insert(removed_path);
891 }
892
893 new_node
894 }
895 else {
897 SparseNode::new_branch(state_mask)
898 }
899 }
900 };
901
902 child = RemovedSparseNode {
903 path: removed_path,
904 node: new_node.clone(),
905 unset_branch_nibble: None,
906 };
907 trace!(target: "trie::sparse", ?removed_path, ?new_node, "Re-inserting the node");
908 self.nodes.insert(removed_path, new_node);
909 }
910
911 Ok(())
912 }
913
914 fn root(&mut self) -> B256 {
915 let mut prefix_set = core::mem::take(&mut self.prefix_set).freeze();
917 let rlp_node = self.rlp_node_allocate(&mut prefix_set);
918 if let Some(root_hash) = rlp_node.as_hash() {
919 root_hash
920 } else {
921 keccak256(rlp_node)
922 }
923 }
924
925 fn update_subtrie_hashes(&mut self) {
926 self.update_rlp_node_level(SPARSE_TRIE_SUBTRIE_HASHES_LEVEL);
927 }
928
929 fn get_leaf_value(&self, full_path: &Nibbles) -> Option<&Vec<u8>> {
930 self.values.get(full_path)
931 }
932
933 fn updates_ref(&self) -> Cow<'_, SparseTrieUpdates> {
934 self.updates.as_ref().map_or(Cow::Owned(SparseTrieUpdates::default()), Cow::Borrowed)
935 }
936
937 fn take_updates(&mut self) -> SparseTrieUpdates {
938 self.updates.take().unwrap_or_default()
939 }
940
941 fn wipe(&mut self) {
942 self.nodes = HashMap::from_iter([(Nibbles::default(), SparseNode::Empty)]);
943 self.values = HashMap::default();
944 self.prefix_set = PrefixSetMut::all();
945 self.updates = self.updates.is_some().then(SparseTrieUpdates::wiped);
946 }
947
948 fn clear(&mut self) {
949 self.nodes.clear();
950 self.nodes.insert(Nibbles::default(), SparseNode::Empty);
951
952 self.branch_node_tree_masks.clear();
953 self.branch_node_hash_masks.clear();
954 self.values.clear();
955 self.prefix_set.clear();
956 self.updates = None;
957 self.rlp_buf.clear();
958 }
959
960 fn find_leaf(
961 &self,
962 full_path: &Nibbles,
963 expected_value: Option<&Vec<u8>>,
964 ) -> Result<LeafLookup, LeafLookupError> {
965 fn check_value_match(
967 actual_value: &Vec<u8>,
968 expected_value: Option<&Vec<u8>>,
969 path: &Nibbles,
970 ) -> Result<(), LeafLookupError> {
971 if let Some(expected) = expected_value {
972 if actual_value != expected {
973 return Err(LeafLookupError::ValueMismatch {
974 path: *path,
975 expected: Some(expected.clone()),
976 actual: actual_value.clone(),
977 });
978 }
979 }
980 Ok(())
981 }
982
983 let mut current = Nibbles::default(); if let Some(actual_value) = self.values.get(full_path) {
991 check_value_match(actual_value, expected_value, full_path)?;
993 return Ok(LeafLookup::Exists);
994 }
995
996 while current.len() < full_path.len() {
1003 match self.nodes.get(¤t) {
1004 Some(SparseNode::Empty) | None => {
1005 return Ok(LeafLookup::NonExistent);
1008 }
1009 Some(&SparseNode::Hash(hash)) => {
1010 return Err(LeafLookupError::BlindedNode { path: current, hash });
1012 }
1013 Some(SparseNode::Leaf { key, .. }) => {
1014 current.extend(key);
1016 if ¤t == full_path {
1017 if let Some(value) = self.values.get(full_path) {
1019 check_value_match(value, expected_value, full_path)?;
1020 return Ok(LeafLookup::Exists);
1021 }
1022 }
1023
1024 return Ok(LeafLookup::NonExistent);
1027 }
1028 Some(SparseNode::Extension { key, .. }) => {
1029 let saved_len = current.len();
1031 current.extend(key);
1032
1033 if full_path.len() < current.len() || !full_path.starts_with(¤t) {
1034 current.truncate(saved_len); return Ok(LeafLookup::NonExistent);
1036 }
1037 }
1039 Some(SparseNode::Branch { state_mask, .. }) => {
1040 let nibble = full_path.get_unchecked(current.len());
1042 if !state_mask.is_bit_set(nibble) {
1043 return Ok(LeafLookup::NonExistent);
1045 }
1046
1047 current.push_unchecked(nibble);
1049 }
1050 }
1051 }
1052
1053 match self.nodes.get(full_path) {
1056 Some(SparseNode::Leaf { key, .. }) if key.is_empty() => {
1057 if let Some(value) = self.values.get(full_path) {
1060 check_value_match(value, expected_value, full_path)?;
1061 return Ok(LeafLookup::Exists);
1062 }
1063 }
1064 Some(&SparseNode::Hash(hash)) => {
1065 return Err(LeafLookupError::BlindedNode { path: *full_path, hash });
1066 }
1067 _ => {
1068 return Ok(LeafLookup::NonExistent);
1070 }
1071 }
1072
1073 Ok(LeafLookup::NonExistent)
1075 }
1076}
1077
1078impl SerialSparseTrie {
1079 pub fn from_root(
1094 root: TrieNode,
1095 masks: TrieMasks,
1096 retain_updates: bool,
1097 ) -> SparseTrieResult<Self> {
1098 Self::default().with_root(root, masks, retain_updates)
1099 }
1100
1101 pub fn updates_ref(&self) -> Cow<'_, SparseTrieUpdates> {
1105 self.updates.as_ref().map_or(Cow::Owned(SparseTrieUpdates::default()), Cow::Borrowed)
1106 }
1107
1108 pub const fn nodes_ref(&self) -> &HashMap<Nibbles, SparseNode> {
1110 &self.nodes
1111 }
1112
1113 fn reveal_node_or_hash(&mut self, path: Nibbles, child: &[u8]) -> SparseTrieResult<()> {
1132 if child.len() == B256::len_bytes() + 1 {
1133 let hash = B256::from_slice(&child[1..]);
1134 match self.nodes.entry(path) {
1135 Entry::Occupied(entry) => match entry.get() {
1136 SparseNode::Hash(previous_hash) if previous_hash != &hash => {
1138 return Err(SparseTrieErrorKind::Reveal {
1139 path: *entry.key(),
1140 node: Box::new(SparseNode::Hash(hash)),
1141 }
1142 .into())
1143 }
1144 _ => {}
1145 },
1146 Entry::Vacant(entry) => {
1147 entry.insert(SparseNode::Hash(hash));
1148 }
1149 }
1150 return Ok(())
1151 }
1152
1153 self.reveal_node(path, TrieNode::decode(&mut &child[..])?, TrieMasks::none())
1154 }
1155
1156 fn take_nodes_for_path(&mut self, path: &Nibbles) -> SparseTrieResult<Vec<RemovedSparseNode>> {
1173 let mut current = Nibbles::default(); let mut nodes = Vec::new(); while let Some(node) = self.nodes.remove(¤t) {
1177 match &node {
1178 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
1179 &SparseNode::Hash(hash) => {
1180 return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into())
1181 }
1182 SparseNode::Leaf { key: _key, .. } => {
1183 #[cfg(debug_assertions)]
1187 {
1188 let mut current = current;
1189 current.extend(_key);
1190 assert_eq!(¤t, path);
1191 }
1192
1193 nodes.push(RemovedSparseNode {
1194 path: current,
1195 node,
1196 unset_branch_nibble: None,
1197 });
1198 break
1199 }
1200 SparseNode::Extension { key, .. } => {
1201 #[cfg(debug_assertions)]
1202 {
1203 let mut current = current;
1204 current.extend(key);
1205 assert!(
1206 path.starts_with(¤t),
1207 "path: {path:?}, current: {current:?}, key: {key:?}",
1208 );
1209 }
1210
1211 let path = current;
1212 current.extend(key);
1213 nodes.push(RemovedSparseNode { path, node, unset_branch_nibble: None });
1214 }
1215 SparseNode::Branch { state_mask, .. } => {
1216 let nibble = path.get_unchecked(current.len());
1217 debug_assert!(
1218 state_mask.is_bit_set(nibble),
1219 "current: {current:?}, path: {path:?}, nibble: {nibble:?}, state_mask: {state_mask:?}",
1220 );
1221
1222 let mut child_path = current;
1228 child_path.push_unchecked(nibble);
1229 let unset_branch_nibble = self
1230 .nodes
1231 .get(&child_path)
1232 .is_some_and(move |node| match node {
1233 SparseNode::Leaf { key, .. } => {
1234 child_path.extend(key);
1236 &child_path == path
1237 }
1238 _ => false,
1239 })
1240 .then_some(nibble);
1241
1242 nodes.push(RemovedSparseNode { path: current, node, unset_branch_nibble });
1243
1244 current.push_unchecked(nibble);
1245 }
1246 }
1247 }
1248
1249 Ok(nodes)
1250 }
1251
1252 pub fn update_rlp_node_level(&mut self, depth: usize) {
1261 let mut prefix_set = core::mem::take(&mut self.prefix_set).freeze();
1263 let mut buffers = RlpNodeBuffers::default();
1264
1265 let (targets, new_prefix_set) = self.get_changed_nodes_at_depth(&mut prefix_set, depth);
1267 self.prefix_set = new_prefix_set;
1269
1270 trace!(target: "trie::sparse", ?depth, ?targets, "Updating nodes at depth");
1271
1272 let mut temp_rlp_buf = core::mem::take(&mut self.rlp_buf);
1273 for (level, path) in targets {
1274 buffers.path_stack.push(RlpNodePathStackItem {
1275 level,
1276 path,
1277 is_in_prefix_set: Some(true),
1278 });
1279 self.rlp_node(&mut prefix_set, &mut buffers, &mut temp_rlp_buf);
1280 }
1281 self.rlp_buf = temp_rlp_buf;
1282 }
1283
1284 fn get_changed_nodes_at_depth(
1306 &self,
1307 prefix_set: &mut PrefixSet,
1308 depth: usize,
1309 ) -> (Vec<(usize, Nibbles)>, PrefixSetMut) {
1310 let mut unchanged_prefix_set = PrefixSetMut::default();
1311 let mut paths = Vec::from([(Nibbles::default(), 0)]);
1312 let mut targets = Vec::new();
1313
1314 while let Some((mut path, level)) = paths.pop() {
1315 match self.nodes.get(&path).unwrap() {
1316 SparseNode::Empty | SparseNode::Hash(_) => {}
1317 SparseNode::Leaf { key: _, hash } => {
1318 if hash.is_some() && !prefix_set.contains(&path) {
1319 continue
1320 }
1321
1322 targets.push((level, path));
1323 }
1324 SparseNode::Extension { key, hash, store_in_db_trie: _ } => {
1325 if hash.is_some() && !prefix_set.contains(&path) {
1326 continue
1327 }
1328
1329 if level >= depth {
1330 targets.push((level, path));
1331 } else {
1332 unchanged_prefix_set.insert(path);
1333
1334 path.extend(key);
1335 paths.push((path, level + 1));
1336 }
1337 }
1338 SparseNode::Branch { state_mask, hash, store_in_db_trie: _ } => {
1339 if hash.is_some() && !prefix_set.contains(&path) {
1340 continue
1341 }
1342
1343 if level >= depth {
1344 targets.push((level, path));
1345 } else {
1346 unchanged_prefix_set.insert(path);
1347
1348 for bit in CHILD_INDEX_RANGE.rev() {
1349 if state_mask.is_bit_set(bit) {
1350 let mut child_path = path;
1351 child_path.push_unchecked(bit);
1352 paths.push((child_path, level + 1));
1353 }
1354 }
1355 }
1356 }
1357 }
1358 }
1359
1360 (targets, unchanged_prefix_set)
1361 }
1362
1363 pub fn rlp_node_allocate(&mut self, prefix_set: &mut PrefixSet) -> RlpNode {
1369 let mut buffers = RlpNodeBuffers::new_with_root_path();
1370 let mut temp_rlp_buf = core::mem::take(&mut self.rlp_buf);
1371 let result = self.rlp_node(prefix_set, &mut buffers, &mut temp_rlp_buf);
1372 self.rlp_buf = temp_rlp_buf;
1373
1374 result
1375 }
1376
1377 pub fn rlp_node(
1392 &mut self,
1393 prefix_set: &mut PrefixSet,
1394 buffers: &mut RlpNodeBuffers,
1395 rlp_buf: &mut Vec<u8>,
1396 ) -> RlpNode {
1397 let _starting_path = buffers.path_stack.last().map(|item| item.path);
1398
1399 'main: while let Some(RlpNodePathStackItem { level, path, mut is_in_prefix_set }) =
1400 buffers.path_stack.pop()
1401 {
1402 let node = self.nodes.get_mut(&path).unwrap();
1403 trace!(
1404 target: "trie::sparse",
1405 ?_starting_path,
1406 ?level,
1407 ?path,
1408 ?is_in_prefix_set,
1409 ?node,
1410 "Popped node from path stack"
1411 );
1412
1413 let mut prefix_set_contains =
1417 |path: &Nibbles| *is_in_prefix_set.get_or_insert_with(|| prefix_set.contains(path));
1418
1419 let (rlp_node, node_type) = match node {
1420 SparseNode::Empty => (RlpNode::word_rlp(&EMPTY_ROOT_HASH), SparseNodeType::Empty),
1421 SparseNode::Hash(hash) => (RlpNode::word_rlp(hash), SparseNodeType::Hash),
1422 SparseNode::Leaf { key, hash } => {
1423 let mut path = path;
1424 path.extend(key);
1425 if let Some(hash) = hash.filter(|_| !prefix_set_contains(&path)) {
1426 (RlpNode::word_rlp(&hash), SparseNodeType::Leaf)
1427 } else {
1428 let value = self.values.get(&path).unwrap();
1429 rlp_buf.clear();
1430 let rlp_node = LeafNodeRef { key, value }.rlp(rlp_buf);
1431 *hash = rlp_node.as_hash();
1432 (rlp_node, SparseNodeType::Leaf)
1433 }
1434 }
1435 SparseNode::Extension { key, hash, store_in_db_trie } => {
1436 let mut child_path = path;
1437 child_path.extend(key);
1438 if let Some((hash, store_in_db_trie)) =
1439 hash.zip(*store_in_db_trie).filter(|_| !prefix_set_contains(&path))
1440 {
1441 (
1442 RlpNode::word_rlp(&hash),
1443 SparseNodeType::Extension { store_in_db_trie: Some(store_in_db_trie) },
1444 )
1445 } else if buffers.rlp_node_stack.last().is_some_and(|e| e.path == child_path) {
1446 let RlpNodeStackItem {
1447 path: _,
1448 rlp_node: child,
1449 node_type: child_node_type,
1450 } = buffers.rlp_node_stack.pop().unwrap();
1451 rlp_buf.clear();
1452 let rlp_node = ExtensionNodeRef::new(key, &child).rlp(rlp_buf);
1453 *hash = rlp_node.as_hash();
1454
1455 let store_in_db_trie_value = child_node_type.store_in_db_trie();
1456
1457 trace!(
1458 target: "trie::sparse",
1459 ?path,
1460 ?child_path,
1461 ?child_node_type,
1462 "Extension node"
1463 );
1464
1465 *store_in_db_trie = store_in_db_trie_value;
1466
1467 (
1468 rlp_node,
1469 SparseNodeType::Extension {
1470 store_in_db_trie: store_in_db_trie_value,
1473 },
1474 )
1475 } else {
1476 buffers.path_stack.extend([
1478 RlpNodePathStackItem { level, path, is_in_prefix_set },
1479 RlpNodePathStackItem {
1480 level: level + 1,
1481 path: child_path,
1482 is_in_prefix_set: None,
1483 },
1484 ]);
1485 continue
1486 }
1487 }
1488 SparseNode::Branch { state_mask, hash, store_in_db_trie } => {
1489 if let Some((hash, store_in_db_trie)) =
1490 hash.zip(*store_in_db_trie).filter(|_| !prefix_set_contains(&path))
1491 {
1492 buffers.rlp_node_stack.push(RlpNodeStackItem {
1493 path,
1494 rlp_node: RlpNode::word_rlp(&hash),
1495 node_type: SparseNodeType::Branch {
1496 store_in_db_trie: Some(store_in_db_trie),
1497 },
1498 });
1499 continue
1500 }
1501 let retain_updates = self.updates.is_some() && prefix_set_contains(&path);
1502
1503 buffers.branch_child_buf.clear();
1504 for bit in CHILD_INDEX_RANGE.rev() {
1507 if state_mask.is_bit_set(bit) {
1508 let mut child = path;
1509 child.push_unchecked(bit);
1510 buffers.branch_child_buf.push(child);
1511 }
1512 }
1513
1514 buffers
1515 .branch_value_stack_buf
1516 .resize(buffers.branch_child_buf.len(), Default::default());
1517 let mut added_children = false;
1518
1519 let mut tree_mask = TrieMask::default();
1520 let mut hash_mask = TrieMask::default();
1521 let mut hashes = Vec::new();
1522 for (i, child_path) in buffers.branch_child_buf.iter().enumerate() {
1523 if buffers.rlp_node_stack.last().is_some_and(|e| &e.path == child_path) {
1524 let RlpNodeStackItem {
1525 path: _,
1526 rlp_node: child,
1527 node_type: child_node_type,
1528 } = buffers.rlp_node_stack.pop().unwrap();
1529
1530 if retain_updates {
1532 let last_child_nibble = child_path.last().unwrap();
1534
1535 let should_set_tree_mask_bit = if let Some(store_in_db_trie) =
1537 child_node_type.store_in_db_trie()
1538 {
1539 store_in_db_trie
1542 } else {
1543 child_node_type.is_hash() &&
1545 self.branch_node_tree_masks.get(&path).is_some_and(
1546 |mask| mask.is_bit_set(last_child_nibble),
1547 )
1548 };
1549 if should_set_tree_mask_bit {
1550 tree_mask.set_bit(last_child_nibble);
1551 }
1552
1553 let hash = child.as_hash().filter(|_| {
1557 child_node_type.is_branch() ||
1558 (child_node_type.is_hash() &&
1559 self.branch_node_hash_masks
1560 .get(&path)
1561 .is_some_and(|mask| {
1562 mask.is_bit_set(last_child_nibble)
1563 }))
1564 });
1565 if let Some(hash) = hash {
1566 hash_mask.set_bit(last_child_nibble);
1567 hashes.push(hash);
1568 }
1569 }
1570
1571 let original_idx = buffers.branch_child_buf.len() - i - 1;
1575 buffers.branch_value_stack_buf[original_idx] = child;
1576 added_children = true;
1577 } else {
1578 debug_assert!(!added_children);
1579 buffers.path_stack.push(RlpNodePathStackItem {
1580 level,
1581 path,
1582 is_in_prefix_set,
1583 });
1584 buffers.path_stack.extend(buffers.branch_child_buf.drain(..).map(
1585 |path| RlpNodePathStackItem {
1586 level: level + 1,
1587 path,
1588 is_in_prefix_set: None,
1589 },
1590 ));
1591 continue 'main
1592 }
1593 }
1594
1595 trace!(
1596 target: "trie::sparse",
1597 ?path,
1598 ?tree_mask,
1599 ?hash_mask,
1600 "Branch node masks"
1601 );
1602
1603 rlp_buf.clear();
1604 let branch_node_ref =
1605 BranchNodeRef::new(&buffers.branch_value_stack_buf, *state_mask);
1606 let rlp_node = branch_node_ref.rlp(rlp_buf);
1607 *hash = rlp_node.as_hash();
1608
1609 let store_in_db_trie_value = if let Some(updates) =
1612 self.updates.as_mut().filter(|_| retain_updates && !path.is_empty())
1613 {
1614 let store_in_db_trie = !tree_mask.is_empty() || !hash_mask.is_empty();
1615 if store_in_db_trie {
1616 hashes.reverse();
1619 let branch_node = BranchNodeCompact::new(
1620 *state_mask,
1621 tree_mask,
1622 hash_mask,
1623 hashes,
1624 hash.filter(|_| path.is_empty()),
1625 );
1626 updates.updated_nodes.insert(path, branch_node);
1627 } else if self
1628 .branch_node_tree_masks
1629 .get(&path)
1630 .is_some_and(|mask| !mask.is_empty()) ||
1631 self.branch_node_hash_masks
1632 .get(&path)
1633 .is_some_and(|mask| !mask.is_empty())
1634 {
1635 updates.updated_nodes.remove(&path);
1639 updates.removed_nodes.insert(path);
1640 } else if self
1641 .branch_node_tree_masks
1642 .get(&path)
1643 .is_none_or(|mask| mask.is_empty()) &&
1644 self.branch_node_hash_masks
1645 .get(&path)
1646 .is_none_or(|mask| mask.is_empty())
1647 {
1648 updates.updated_nodes.remove(&path);
1651 }
1652
1653 store_in_db_trie
1654 } else {
1655 false
1656 };
1657 *store_in_db_trie = Some(store_in_db_trie_value);
1658
1659 (
1660 rlp_node,
1661 SparseNodeType::Branch { store_in_db_trie: Some(store_in_db_trie_value) },
1662 )
1663 }
1664 };
1665
1666 trace!(
1667 target: "trie::sparse",
1668 ?_starting_path,
1669 ?level,
1670 ?path,
1671 ?node,
1672 ?node_type,
1673 ?is_in_prefix_set,
1674 "Added node to rlp node stack"
1675 );
1676
1677 buffers.rlp_node_stack.push(RlpNodeStackItem { path, rlp_node, node_type });
1678 }
1679
1680 debug_assert_eq!(buffers.rlp_node_stack.len(), 1);
1681 buffers.rlp_node_stack.pop().unwrap().rlp_node
1682 }
1683}
1684
1685#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1687pub enum SparseNodeType {
1688 Empty,
1690 Hash,
1692 Leaf,
1694 Extension {
1696 store_in_db_trie: Option<bool>,
1698 },
1699 Branch {
1701 store_in_db_trie: Option<bool>,
1703 },
1704}
1705
1706impl SparseNodeType {
1707 pub const fn is_hash(&self) -> bool {
1709 matches!(self, Self::Hash)
1710 }
1711
1712 pub const fn is_branch(&self) -> bool {
1714 matches!(self, Self::Branch { .. })
1715 }
1716
1717 pub const fn store_in_db_trie(&self) -> Option<bool> {
1719 match *self {
1720 Self::Extension { store_in_db_trie } | Self::Branch { store_in_db_trie } => {
1721 store_in_db_trie
1722 }
1723 _ => None,
1724 }
1725 }
1726}
1727
1728#[derive(Debug, Clone, PartialEq, Eq)]
1730pub enum SparseNode {
1731 Empty,
1733 Hash(B256),
1735 Leaf {
1737 key: Nibbles,
1739 hash: Option<B256>,
1742 },
1743 Extension {
1745 key: Nibbles,
1747 hash: Option<B256>,
1752 store_in_db_trie: Option<bool>,
1757 },
1758 Branch {
1760 state_mask: TrieMask,
1762 hash: Option<B256>,
1767 store_in_db_trie: Option<bool>,
1772 },
1773}
1774
1775impl SparseNode {
1776 pub fn from_node(node: TrieNode) -> Self {
1778 match node {
1779 TrieNode::EmptyRoot => Self::Empty,
1780 TrieNode::Leaf(leaf) => Self::new_leaf(leaf.key),
1781 TrieNode::Extension(ext) => Self::new_ext(ext.key),
1782 TrieNode::Branch(branch) => Self::new_branch(branch.state_mask),
1783 }
1784 }
1785
1786 pub const fn new_branch(state_mask: TrieMask) -> Self {
1788 Self::Branch { state_mask, hash: None, store_in_db_trie: None }
1789 }
1790
1791 pub const fn new_split_branch(bit_a: u8, bit_b: u8) -> Self {
1793 let state_mask = TrieMask::new(
1794 (1u16 << bit_a) | (1u16 << bit_b),
1796 );
1797 Self::Branch { state_mask, hash: None, store_in_db_trie: None }
1798 }
1799
1800 pub const fn new_ext(key: Nibbles) -> Self {
1802 Self::Extension { key, hash: None, store_in_db_trie: None }
1803 }
1804
1805 pub const fn new_leaf(key: Nibbles) -> Self {
1807 Self::Leaf { key, hash: None }
1808 }
1809
1810 pub const fn is_hash(&self) -> bool {
1812 matches!(self, Self::Hash(_))
1813 }
1814
1815 pub const fn hash(&self) -> Option<B256> {
1817 match self {
1818 Self::Empty => None,
1819 Self::Hash(hash) => Some(*hash),
1820 Self::Leaf { hash, .. } | Self::Extension { hash, .. } | Self::Branch { hash, .. } => {
1821 *hash
1822 }
1823 }
1824 }
1825
1826 #[cfg(any(test, feature = "test-utils"))]
1830 pub const fn set_hash(&mut self, new_hash: Option<B256>) {
1831 match self {
1832 Self::Empty | Self::Hash(_) => {
1833 }
1835 Self::Leaf { hash, .. } | Self::Extension { hash, .. } | Self::Branch { hash, .. } => {
1836 *hash = new_hash;
1837 }
1838 }
1839 }
1840}
1841
1842#[derive(Debug)]
1845struct RemovedSparseNode {
1846 path: Nibbles,
1848 node: SparseNode,
1850 unset_branch_nibble: Option<u8>,
1859}
1860
1861#[derive(Debug, Default)]
1865pub struct RlpNodeBuffers {
1866 path_stack: Vec<RlpNodePathStackItem>,
1868 rlp_node_stack: Vec<RlpNodeStackItem>,
1870 branch_child_buf: SmallVec<[Nibbles; 16]>,
1872 branch_value_stack_buf: SmallVec<[RlpNode; 16]>,
1874}
1875
1876impl RlpNodeBuffers {
1877 fn new_with_root_path() -> Self {
1879 Self {
1880 path_stack: vec![RlpNodePathStackItem {
1881 level: 0,
1882 path: Nibbles::default(),
1883 is_in_prefix_set: None,
1884 }],
1885 rlp_node_stack: Vec::new(),
1886 branch_child_buf: SmallVec::<[Nibbles; 16]>::new_const(),
1887 branch_value_stack_buf: SmallVec::<[RlpNode; 16]>::new_const(),
1888 }
1889 }
1890}
1891
1892#[derive(Clone, PartialEq, Eq, Debug)]
1894pub struct RlpNodePathStackItem {
1895 pub level: usize,
1897 pub path: Nibbles,
1899 pub is_in_prefix_set: Option<bool>,
1901}
1902
1903#[derive(Clone, PartialEq, Eq, Debug)]
1905pub struct RlpNodeStackItem {
1906 pub path: Nibbles,
1908 pub rlp_node: RlpNode,
1910 pub node_type: SparseNodeType,
1912}
1913
1914impl SparseTrieUpdates {
1915 pub fn wiped() -> Self {
1917 Self { wiped: true, ..Default::default() }
1918 }
1919
1920 pub fn clear(&mut self) {
1924 self.updated_nodes.clear();
1925 self.removed_nodes.clear();
1926 self.wiped = false;
1927 }
1928
1929 pub fn extend(&mut self, other: Self) {
1931 self.updated_nodes.extend(other.updated_nodes);
1932 self.removed_nodes.extend(other.removed_nodes);
1933 self.wiped |= other.wiped;
1934 }
1935}
1936
1937#[cfg(test)]
1938mod find_leaf_tests {
1939 use super::*;
1940 use crate::provider::DefaultTrieNodeProvider;
1941 use alloy_rlp::Encodable;
1942 use assert_matches::assert_matches;
1943 use reth_primitives_traits::Account;
1944 use reth_trie_common::LeafNode;
1945
1946 fn encode_value(nonce: u64) -> Vec<u8> {
1948 let account = Account { nonce, ..Default::default() };
1949 let trie_account = account.into_trie_account(EMPTY_ROOT_HASH);
1950 let mut buf = Vec::new();
1951 trie_account.encode(&mut buf);
1952 buf
1953 }
1954
1955 const VALUE_A: fn() -> Vec<u8> = || encode_value(1);
1956 const VALUE_B: fn() -> Vec<u8> = || encode_value(2);
1957
1958 #[test]
1959 fn find_leaf_existing_leaf() {
1960 let provider = DefaultTrieNodeProvider;
1962 let mut sparse = SerialSparseTrie::default();
1963 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
1964 let value = b"test_value".to_vec();
1965
1966 sparse.update_leaf(path, value.clone(), &provider).unwrap();
1967
1968 let result = sparse.find_leaf(&path, None);
1970 assert_matches!(result, Ok(LeafLookup::Exists));
1971
1972 let result = sparse.find_leaf(&path, Some(&value));
1974 assert_matches!(result, Ok(LeafLookup::Exists));
1975 }
1976
1977 #[test]
1978 fn find_leaf_value_mismatch() {
1979 let provider = DefaultTrieNodeProvider;
1981 let mut sparse = SerialSparseTrie::default();
1982 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
1983 let value = b"test_value".to_vec();
1984 let wrong_value = b"wrong_value".to_vec();
1985
1986 sparse.update_leaf(path, value, &provider).unwrap();
1987
1988 let result = sparse.find_leaf(&path, Some(&wrong_value));
1990 assert_matches!(
1991 result,
1992 Err(LeafLookupError::ValueMismatch { path: p, expected: Some(e), actual: _a }) if p == path && e == wrong_value
1993 );
1994 }
1995
1996 #[test]
1997 fn find_leaf_not_found_empty_trie() {
1998 let sparse = SerialSparseTrie::default();
2000 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
2001
2002 let result = sparse.find_leaf(&path, None);
2004 assert_matches!(result, Ok(LeafLookup::NonExistent));
2005 }
2006
2007 #[test]
2008 fn find_leaf_empty_trie() {
2009 let sparse = SerialSparseTrie::default();
2010 let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2011
2012 let result = sparse.find_leaf(&path, None);
2013 assert_matches!(result, Ok(LeafLookup::NonExistent));
2014 }
2015
2016 #[test]
2017 fn find_leaf_exists_no_value_check() {
2018 let provider = DefaultTrieNodeProvider;
2019 let mut sparse = SerialSparseTrie::default();
2020 let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2021 sparse.update_leaf(path, VALUE_A(), &provider).unwrap();
2022
2023 let result = sparse.find_leaf(&path, None);
2024 assert_matches!(result, Ok(LeafLookup::Exists));
2025 }
2026
2027 #[test]
2028 fn find_leaf_exists_with_value_check_ok() {
2029 let provider = DefaultTrieNodeProvider;
2030 let mut sparse = SerialSparseTrie::default();
2031 let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2032 let value = VALUE_A();
2033 sparse.update_leaf(path, value.clone(), &provider).unwrap();
2034
2035 let result = sparse.find_leaf(&path, Some(&value));
2036 assert_matches!(result, Ok(LeafLookup::Exists));
2037 }
2038
2039 #[test]
2040 fn find_leaf_exclusion_branch_divergence() {
2041 let provider = DefaultTrieNodeProvider;
2042 let mut sparse = SerialSparseTrie::default();
2043 let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); let path2 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x5, 0x6]); let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x7, 0x8]); sparse.update_leaf(path1, VALUE_A(), &provider).unwrap();
2048 sparse.update_leaf(path2, VALUE_B(), &provider).unwrap();
2049
2050 let result = sparse.find_leaf(&search_path, None);
2051 assert_matches!(result, Ok(LeafLookup::NonExistent));
2052 }
2053
2054 #[test]
2055 fn find_leaf_exclusion_extension_divergence() {
2056 let provider = DefaultTrieNodeProvider;
2057 let mut sparse = SerialSparseTrie::default();
2058 let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]);
2060 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x7, 0x8]);
2062
2063 sparse.update_leaf(path1, VALUE_A(), &provider).unwrap();
2064
2065 let result = sparse.find_leaf(&search_path, None);
2066 assert_matches!(result, Ok(LeafLookup::NonExistent));
2067 }
2068
2069 #[test]
2070 fn find_leaf_exclusion_leaf_divergence() {
2071 let provider = DefaultTrieNodeProvider;
2072 let mut sparse = SerialSparseTrie::default();
2073 let existing_leaf_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2074 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]);
2075
2076 sparse.update_leaf(existing_leaf_path, VALUE_A(), &provider).unwrap();
2077
2078 let result = sparse.find_leaf(&search_path, None);
2079 assert_matches!(result, Ok(LeafLookup::NonExistent));
2080 }
2081
2082 #[test]
2083 fn find_leaf_exclusion_path_ends_at_branch() {
2084 let provider = DefaultTrieNodeProvider;
2085 let mut sparse = SerialSparseTrie::default();
2086 let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); let path2 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x5, 0x6]);
2088 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2]); sparse.update_leaf(path1, VALUE_A(), &provider).unwrap();
2091 sparse.update_leaf(path2, VALUE_B(), &provider).unwrap();
2092
2093 let result = sparse.find_leaf(&search_path, None);
2094 assert_matches!(result, Ok(LeafLookup::NonExistent));
2095 }
2096
2097 #[test]
2098 fn find_leaf_error_trie_node_at_leaf_path() {
2099 let blinded_hash = B256::repeat_byte(0xBB);
2101 let leaf_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2102
2103 let mut nodes = alloy_primitives::map::HashMap::default();
2104 nodes.insert(
2106 Nibbles::default(),
2107 SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x1, 0x2])),
2108 ); nodes.insert(
2110 Nibbles::from_nibbles_unchecked([0x1, 0x2]),
2111 SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x3])),
2112 ); nodes.insert(
2114 Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3]),
2115 SparseNode::new_branch(TrieMask::new(0b10000)),
2116 ); nodes.insert(leaf_path, SparseNode::Hash(blinded_hash)); let sparse = SerialSparseTrie {
2120 nodes,
2121 branch_node_tree_masks: Default::default(),
2122 branch_node_hash_masks: Default::default(),
2123 values: Default::default(),
2125 prefix_set: Default::default(),
2126 updates: None,
2127 rlp_buf: Vec::new(),
2128 };
2129
2130 let result = sparse.find_leaf(&leaf_path, None);
2131
2132 assert_matches!(result, Err(LeafLookupError::BlindedNode { path, hash })
2134 if path == leaf_path && hash == blinded_hash
2135 );
2136 }
2137
2138 #[test]
2139 fn find_leaf_error_trie_node() {
2140 let blinded_hash = B256::repeat_byte(0xAA);
2141 let path_to_blind = Nibbles::from_nibbles_unchecked([0x1]);
2142 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2143
2144 let mut nodes = HashMap::default();
2145
2146 let state_mask = TrieMask::new(0b100010);
2149 nodes.insert(Nibbles::default(), SparseNode::new_branch(state_mask));
2150
2151 nodes.insert(path_to_blind, SparseNode::Hash(blinded_hash));
2152 let path_revealed = Nibbles::from_nibbles_unchecked([0x5]);
2153 let path_revealed_leaf = Nibbles::from_nibbles_unchecked([0x5, 0x6, 0x7, 0x8]);
2154 nodes.insert(
2155 path_revealed,
2156 SparseNode::new_leaf(Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8])),
2157 );
2158
2159 let mut values = HashMap::default();
2160 values.insert(path_revealed_leaf, VALUE_A());
2161
2162 let sparse = SerialSparseTrie {
2163 nodes,
2164 branch_node_tree_masks: Default::default(),
2165 branch_node_hash_masks: Default::default(),
2166 values,
2167 prefix_set: Default::default(),
2168 updates: None,
2169 rlp_buf: Vec::new(),
2170 };
2171
2172 let result = sparse.find_leaf(&search_path, None);
2173
2174 assert_matches!(result, Err(LeafLookupError::BlindedNode { path, hash })
2176 if path == path_to_blind && hash == blinded_hash
2177 );
2178 }
2179
2180 #[test]
2181 fn find_leaf_error_trie_node_via_reveal() {
2182 let blinded_hash = B256::repeat_byte(0xAA);
2183 let path_to_blind = Nibbles::from_nibbles_unchecked([0x1]); let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); let revealed_leaf_prefix = Nibbles::from_nibbles_unchecked([0x5]);
2187 let revealed_leaf_suffix = Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8]);
2188 let revealed_leaf_full_path = Nibbles::from_nibbles_unchecked([0x5, 0x6, 0x7, 0x8]);
2189 let revealed_value = VALUE_A();
2190
2191 let rlp_node_child1 = RlpNode::word_rlp(&blinded_hash); let leaf_node_child5 = LeafNode::new(revealed_leaf_suffix, revealed_value.clone());
2195 let leaf_node_child5_rlp_buf = alloy_rlp::encode(&leaf_node_child5);
2196 let hash_of_child5 = keccak256(&leaf_node_child5_rlp_buf);
2197 let rlp_node_child5 = RlpNode::word_rlp(&hash_of_child5);
2198
2199 let root_branch_node = reth_trie_common::BranchNode::new(
2202 vec![rlp_node_child1, rlp_node_child5], TrieMask::new(0b100010), );
2205 let root_trie_node = TrieNode::Branch(root_branch_node);
2206
2207 let mut sparse = SerialSparseTrie::from_root(root_trie_node, TrieMasks::none(), false)
2210 .expect("Failed to create trie from root");
2211
2212 assert_matches!(sparse.nodes.get(&Nibbles::default()), Some(SparseNode::Branch { state_mask, .. }) if *state_mask == TrieMask::new(0b100010)); assert_matches!(sparse.nodes.get(&path_to_blind), Some(SparseNode::Hash(h)) if *h == blinded_hash );
2215 assert!(sparse.nodes.get(&revealed_leaf_prefix).unwrap().is_hash()); assert!(sparse.values.is_empty());
2217
2218 sparse
2220 .reveal_node(revealed_leaf_prefix, TrieNode::Leaf(leaf_node_child5), TrieMasks::none())
2221 .expect("Failed to reveal leaf node");
2222
2223 assert_matches!(sparse.nodes.get(&Nibbles::default()), Some(SparseNode::Branch { state_mask, .. }) if *state_mask == TrieMask::new(0b100010));
2225 assert_matches!(sparse.nodes.get(&path_to_blind), Some(SparseNode::Hash(h)) if *h == blinded_hash );
2226 assert_matches!(sparse.nodes.get(&revealed_leaf_prefix), Some(SparseNode::Leaf { key, .. }) if *key == revealed_leaf_suffix);
2227 assert_eq!(sparse.values.get(&revealed_leaf_full_path), Some(&revealed_value));
2228
2229 let result = sparse.find_leaf(&search_path, None);
2230
2231 assert_matches!(result, Err(LeafLookupError::BlindedNode { path, hash })
2234 if path == path_to_blind && hash == blinded_hash
2235 );
2236 }
2237}
2238
2239#[cfg(test)]
2240mod tests {
2241 use super::*;
2242 use crate::provider::DefaultTrieNodeProvider;
2243 use alloy_primitives::{map::B256Set, U256};
2244 use alloy_rlp::Encodable;
2245 use assert_matches::assert_matches;
2246 use itertools::Itertools;
2247 use prop::sample::SizeRange;
2248 use proptest::prelude::*;
2249 use proptest_arbitrary_interop::arb;
2250 use reth_primitives_traits::Account;
2251 use reth_provider::{test_utils::create_test_provider_factory, TrieWriter};
2252 use reth_trie::{
2253 hashed_cursor::{noop::NoopHashedAccountCursor, HashedPostStateAccountCursor},
2254 node_iter::{TrieElement, TrieNodeIter},
2255 trie_cursor::{noop::NoopAccountTrieCursor, TrieCursor, TrieCursorFactory},
2256 walker::TrieWalker,
2257 BranchNode, ExtensionNode, HashedPostState, LeafNode,
2258 };
2259 use reth_trie_common::{
2260 proof::{ProofNodes, ProofRetainer},
2261 updates::TrieUpdates,
2262 HashBuilder,
2263 };
2264 use reth_trie_db::DatabaseTrieCursorFactory;
2265 use std::collections::{BTreeMap, BTreeSet};
2266
2267 fn pad_nibbles_left(nibbles: Nibbles) -> Nibbles {
2269 let mut base =
2270 Nibbles::from_nibbles_unchecked(vec![0; B256::len_bytes() * 2 - nibbles.len()]);
2271 base.extend(&nibbles);
2272 base
2273 }
2274
2275 fn pad_nibbles_right(mut nibbles: Nibbles) -> Nibbles {
2277 nibbles.extend(&Nibbles::from_nibbles_unchecked(vec![
2278 0;
2279 B256::len_bytes() * 2 - nibbles.len()
2280 ]));
2281 nibbles
2282 }
2283
2284 fn run_hash_builder(
2289 state: impl IntoIterator<Item = (Nibbles, Account)> + Clone,
2290 trie_cursor: impl TrieCursor,
2291 destroyed_accounts: B256Set,
2292 proof_targets: impl IntoIterator<Item = Nibbles>,
2293 ) -> (B256, TrieUpdates, ProofNodes, HashMap<Nibbles, TrieMask>, HashMap<Nibbles, TrieMask>)
2294 {
2295 let mut account_rlp = Vec::new();
2296
2297 let mut hash_builder = HashBuilder::default()
2298 .with_updates(true)
2299 .with_proof_retainer(ProofRetainer::from_iter(proof_targets));
2300
2301 let mut prefix_set = PrefixSetMut::default();
2302 prefix_set.extend_keys(state.clone().into_iter().map(|(nibbles, _)| nibbles));
2303 prefix_set.extend_keys(destroyed_accounts.iter().map(Nibbles::unpack));
2304 let walker = TrieWalker::<_>::state_trie(trie_cursor, prefix_set.freeze())
2305 .with_deletions_retained(true);
2306 let hashed_post_state = HashedPostState::default()
2307 .with_accounts(state.into_iter().map(|(nibbles, account)| {
2308 (nibbles.pack().into_inner().unwrap().into(), Some(account))
2309 }))
2310 .into_sorted();
2311 let mut node_iter = TrieNodeIter::state_trie(
2312 walker,
2313 HashedPostStateAccountCursor::new(
2314 NoopHashedAccountCursor::default(),
2315 hashed_post_state.accounts(),
2316 ),
2317 );
2318
2319 while let Some(node) = node_iter.try_next().unwrap() {
2320 match node {
2321 TrieElement::Branch(branch) => {
2322 hash_builder.add_branch(branch.key, branch.value, branch.children_are_in_trie);
2323 }
2324 TrieElement::Leaf(key, account) => {
2325 let account = account.into_trie_account(EMPTY_ROOT_HASH);
2326 account.encode(&mut account_rlp);
2327
2328 hash_builder.add_leaf(Nibbles::unpack(key), &account_rlp);
2329 account_rlp.clear();
2330 }
2331 }
2332 }
2333 let root = hash_builder.root();
2334 let proof_nodes = hash_builder.take_proof_nodes();
2335 let branch_node_hash_masks = hash_builder
2336 .updated_branch_nodes
2337 .clone()
2338 .unwrap_or_default()
2339 .iter()
2340 .map(|(path, node)| (*path, node.hash_mask))
2341 .collect();
2342 let branch_node_tree_masks = hash_builder
2343 .updated_branch_nodes
2344 .clone()
2345 .unwrap_or_default()
2346 .iter()
2347 .map(|(path, node)| (*path, node.tree_mask))
2348 .collect();
2349
2350 let mut trie_updates = TrieUpdates::default();
2351 let removed_keys = node_iter.walker.take_removed_keys();
2352 trie_updates.finalize(hash_builder, removed_keys, destroyed_accounts);
2353
2354 (root, trie_updates, proof_nodes, branch_node_hash_masks, branch_node_tree_masks)
2355 }
2356
2357 fn assert_eq_sparse_trie_proof_nodes(sparse_trie: &SerialSparseTrie, proof_nodes: ProofNodes) {
2359 let proof_nodes = proof_nodes
2360 .into_nodes_sorted()
2361 .into_iter()
2362 .map(|(path, node)| (path, TrieNode::decode(&mut node.as_ref()).unwrap()));
2363
2364 let sparse_nodes = sparse_trie.nodes.iter().sorted_by_key(|(path, _)| *path);
2365
2366 for ((proof_node_path, proof_node), (sparse_node_path, sparse_node)) in
2367 proof_nodes.zip(sparse_nodes)
2368 {
2369 assert_eq!(&proof_node_path, sparse_node_path);
2370
2371 let equals = match (&proof_node, &sparse_node) {
2372 (TrieNode::EmptyRoot, SparseNode::Empty) => true,
2374 (
2376 TrieNode::Branch(BranchNode { state_mask: proof_state_mask, .. }),
2377 SparseNode::Branch { state_mask: sparse_state_mask, .. },
2378 ) => proof_state_mask == sparse_state_mask,
2379 (
2381 TrieNode::Extension(ExtensionNode { key: proof_key, .. }),
2382 SparseNode::Extension { key: sparse_key, .. },
2383 ) |
2384 (
2386 TrieNode::Leaf(LeafNode { key: proof_key, .. }),
2387 SparseNode::Leaf { key: sparse_key, .. },
2388 ) => proof_key == sparse_key,
2389 (_, SparseNode::Empty | SparseNode::Hash(_)) => continue,
2391 _ => false,
2392 };
2393 assert!(
2394 equals,
2395 "path: {proof_node_path:?}\nproof node: {proof_node:?}\nsparse node: {sparse_node:?}"
2396 );
2397 }
2398 }
2399
2400 #[test]
2401 fn sparse_trie_is_blind() {
2402 assert!(SparseTrie::<SerialSparseTrie>::blind().is_blind());
2403 assert!(!SparseTrie::<SerialSparseTrie>::revealed_empty().is_blind());
2404 }
2405
2406 #[test]
2407 fn sparse_trie_empty_update_one() {
2408 let key = Nibbles::unpack(B256::with_last_byte(42));
2409 let value = || Account::default();
2410 let value_encoded = || {
2411 let mut account_rlp = Vec::new();
2412 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2413 account_rlp
2414 };
2415
2416 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2417 run_hash_builder(
2418 [(key, value())],
2419 NoopAccountTrieCursor::default(),
2420 Default::default(),
2421 [key],
2422 );
2423
2424 let provider = DefaultTrieNodeProvider;
2425 let mut sparse = SerialSparseTrie::default().with_updates(true);
2426 sparse.update_leaf(key, value_encoded(), &provider).unwrap();
2427 let sparse_root = sparse.root();
2428 let sparse_updates = sparse.take_updates();
2429
2430 assert_eq!(sparse_root, hash_builder_root);
2431 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2432 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2433 }
2434
2435 #[test]
2436 fn sparse_trie_empty_update_multiple_lower_nibbles() {
2437 reth_tracing::init_test_tracing();
2438
2439 let paths = (0..=16).map(|b| Nibbles::unpack(B256::with_last_byte(b))).collect::<Vec<_>>();
2440 let value = || Account::default();
2441 let value_encoded = || {
2442 let mut account_rlp = Vec::new();
2443 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2444 account_rlp
2445 };
2446
2447 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2448 run_hash_builder(
2449 paths.iter().copied().zip(std::iter::repeat_with(value)),
2450 NoopAccountTrieCursor::default(),
2451 Default::default(),
2452 paths.clone(),
2453 );
2454
2455 let provider = DefaultTrieNodeProvider;
2456 let mut sparse = SerialSparseTrie::default().with_updates(true);
2457 for path in &paths {
2458 sparse.update_leaf(*path, value_encoded(), &provider).unwrap();
2459 }
2460 let sparse_root = sparse.root();
2461 let sparse_updates = sparse.take_updates();
2462
2463 assert_eq!(sparse_root, hash_builder_root);
2464 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2465 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2466 }
2467
2468 #[test]
2469 fn sparse_trie_empty_update_multiple_upper_nibbles() {
2470 let paths = (239..=255).map(|b| Nibbles::unpack(B256::repeat_byte(b))).collect::<Vec<_>>();
2471 let value = || Account::default();
2472 let value_encoded = || {
2473 let mut account_rlp = Vec::new();
2474 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2475 account_rlp
2476 };
2477
2478 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2479 run_hash_builder(
2480 paths.iter().copied().zip(std::iter::repeat_with(value)),
2481 NoopAccountTrieCursor::default(),
2482 Default::default(),
2483 paths.clone(),
2484 );
2485
2486 let provider = DefaultTrieNodeProvider;
2487 let mut sparse = SerialSparseTrie::default().with_updates(true);
2488 for path in &paths {
2489 sparse.update_leaf(*path, value_encoded(), &provider).unwrap();
2490 }
2491 let sparse_root = sparse.root();
2492 let sparse_updates = sparse.take_updates();
2493
2494 assert_eq!(sparse_root, hash_builder_root);
2495 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2496 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2497 }
2498
2499 #[test]
2500 fn sparse_trie_empty_update_multiple() {
2501 let paths = (0..=255)
2502 .map(|b| {
2503 Nibbles::unpack(if b % 2 == 0 {
2504 B256::repeat_byte(b)
2505 } else {
2506 B256::with_last_byte(b)
2507 })
2508 })
2509 .collect::<Vec<_>>();
2510 let value = || Account::default();
2511 let value_encoded = || {
2512 let mut account_rlp = Vec::new();
2513 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2514 account_rlp
2515 };
2516
2517 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2518 run_hash_builder(
2519 paths.iter().sorted_unstable().copied().zip(std::iter::repeat_with(value)),
2520 NoopAccountTrieCursor::default(),
2521 Default::default(),
2522 paths.clone(),
2523 );
2524
2525 let provider = DefaultTrieNodeProvider;
2526 let mut sparse = SerialSparseTrie::default().with_updates(true);
2527 for path in &paths {
2528 sparse.update_leaf(*path, value_encoded(), &provider).unwrap();
2529 }
2530 let sparse_root = sparse.root();
2531 let sparse_updates = sparse.take_updates();
2532
2533 assert_eq!(sparse_root, hash_builder_root);
2534 pretty_assertions::assert_eq!(
2535 BTreeMap::from_iter(sparse_updates.updated_nodes),
2536 BTreeMap::from_iter(hash_builder_updates.account_nodes)
2537 );
2538 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2539 }
2540
2541 #[test]
2542 fn sparse_trie_empty_update_repeated() {
2543 let paths = (0..=255).map(|b| Nibbles::unpack(B256::repeat_byte(b))).collect::<Vec<_>>();
2544 let old_value = Account { nonce: 1, ..Default::default() };
2545 let old_value_encoded = {
2546 let mut account_rlp = Vec::new();
2547 old_value.into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2548 account_rlp
2549 };
2550 let new_value = Account { nonce: 2, ..Default::default() };
2551 let new_value_encoded = {
2552 let mut account_rlp = Vec::new();
2553 new_value.into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2554 account_rlp
2555 };
2556
2557 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2558 run_hash_builder(
2559 paths.iter().copied().zip(std::iter::repeat_with(|| old_value)),
2560 NoopAccountTrieCursor::default(),
2561 Default::default(),
2562 paths.clone(),
2563 );
2564
2565 let provider = DefaultTrieNodeProvider;
2566 let mut sparse = SerialSparseTrie::default().with_updates(true);
2567 for path in &paths {
2568 sparse.update_leaf(*path, old_value_encoded.clone(), &provider).unwrap();
2569 }
2570 let sparse_root = sparse.root();
2571 let sparse_updates = sparse.updates_ref();
2572
2573 assert_eq!(sparse_root, hash_builder_root);
2574 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2575 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2576
2577 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2578 run_hash_builder(
2579 paths.iter().copied().zip(std::iter::repeat_with(|| new_value)),
2580 NoopAccountTrieCursor::default(),
2581 Default::default(),
2582 paths.clone(),
2583 );
2584
2585 for path in &paths {
2586 sparse.update_leaf(*path, new_value_encoded.clone(), &provider).unwrap();
2587 }
2588 let sparse_root = sparse.root();
2589 let sparse_updates = sparse.take_updates();
2590
2591 assert_eq!(sparse_root, hash_builder_root);
2592 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2593 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2594 }
2595
2596 #[test]
2597 fn sparse_trie_remove_leaf() {
2598 reth_tracing::init_test_tracing();
2599
2600 let provider = DefaultTrieNodeProvider;
2601 let mut sparse = SerialSparseTrie::default();
2602
2603 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
2604
2605 sparse
2606 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
2607 .unwrap();
2608 sparse
2609 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
2610 .unwrap();
2611 sparse
2612 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
2613 .unwrap();
2614 sparse
2615 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
2616 .unwrap();
2617 sparse
2618 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
2619 .unwrap();
2620 sparse
2621 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
2622 .unwrap();
2623
2624 pretty_assertions::assert_eq!(
2637 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2638 BTreeMap::from_iter([
2639 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2640 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1101.into())),
2641 (
2642 Nibbles::from_nibbles([0x5, 0x0]),
2643 SparseNode::new_ext(Nibbles::from_nibbles([0x2, 0x3]))
2644 ),
2645 (
2646 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3]),
2647 SparseNode::new_branch(0b1010.into())
2648 ),
2649 (
2650 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]),
2651 SparseNode::new_leaf(Nibbles::default())
2652 ),
2653 (
2654 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]),
2655 SparseNode::new_leaf(Nibbles::default())
2656 ),
2657 (
2658 Nibbles::from_nibbles([0x5, 0x2]),
2659 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x1, 0x3]))
2660 ),
2661 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
2662 (
2663 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
2664 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
2665 ),
2666 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2667 (
2668 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2669 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2670 ),
2671 (
2672 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2673 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2674 )
2675 ])
2676 );
2677
2678 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), &provider).unwrap();
2679
2680 pretty_assertions::assert_eq!(
2692 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2693 BTreeMap::from_iter([
2694 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2695 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2696 (
2697 Nibbles::from_nibbles([0x5, 0x0]),
2698 SparseNode::new_ext(Nibbles::from_nibbles([0x2, 0x3]))
2699 ),
2700 (
2701 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3]),
2702 SparseNode::new_branch(0b1010.into())
2703 ),
2704 (
2705 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]),
2706 SparseNode::new_leaf(Nibbles::default())
2707 ),
2708 (
2709 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]),
2710 SparseNode::new_leaf(Nibbles::default())
2711 ),
2712 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
2713 (
2714 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
2715 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
2716 ),
2717 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2718 (
2719 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2720 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2721 ),
2722 (
2723 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2724 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2725 )
2726 ])
2727 );
2728
2729 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), &provider).unwrap();
2730
2731 pretty_assertions::assert_eq!(
2740 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2741 BTreeMap::from_iter([
2742 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2743 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2744 (
2745 Nibbles::from_nibbles([0x5, 0x0]),
2746 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
2747 ),
2748 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
2749 (
2750 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
2751 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
2752 ),
2753 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2754 (
2755 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2756 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2757 ),
2758 (
2759 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2760 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2761 )
2762 ])
2763 );
2764
2765 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), &provider).unwrap();
2766
2767 pretty_assertions::assert_eq!(
2774 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2775 BTreeMap::from_iter([
2776 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2777 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2778 (
2779 Nibbles::from_nibbles([0x5, 0x0]),
2780 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
2781 ),
2782 (
2783 Nibbles::from_nibbles([0x5, 0x3]),
2784 SparseNode::new_ext(Nibbles::from_nibbles([0x3]))
2785 ),
2786 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2787 (
2788 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2789 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2790 ),
2791 (
2792 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2793 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2794 )
2795 ])
2796 );
2797
2798 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), &provider).unwrap();
2799
2800 pretty_assertions::assert_eq!(
2805 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2806 BTreeMap::from_iter([
2807 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2808 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2809 (
2810 Nibbles::from_nibbles([0x5, 0x0]),
2811 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
2812 ),
2813 (
2814 Nibbles::from_nibbles([0x5, 0x3]),
2815 SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x0, 0x2]))
2816 ),
2817 ])
2818 );
2819
2820 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), &provider).unwrap();
2821
2822 pretty_assertions::assert_eq!(
2824 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2825 BTreeMap::from_iter([(
2826 Nibbles::default(),
2827 SparseNode::new_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]))
2828 ),])
2829 );
2830
2831 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), &provider).unwrap();
2832
2833 pretty_assertions::assert_eq!(
2835 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2836 BTreeMap::from_iter([(Nibbles::default(), SparseNode::Empty)])
2837 );
2838 }
2839
2840 #[test]
2841 fn sparse_trie_remove_leaf_blinded() {
2842 let leaf = LeafNode::new(
2843 Nibbles::default(),
2844 alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(),
2845 );
2846 let branch = TrieNode::Branch(BranchNode::new(
2847 vec![
2848 RlpNode::word_rlp(&B256::repeat_byte(1)),
2849 RlpNode::from_raw_rlp(&alloy_rlp::encode(leaf.clone())).unwrap(),
2850 ],
2851 TrieMask::new(0b11),
2852 ));
2853
2854 let provider = DefaultTrieNodeProvider;
2855 let mut sparse = SerialSparseTrie::from_root(
2856 branch.clone(),
2857 TrieMasks { hash_mask: Some(TrieMask::new(0b01)), tree_mask: None },
2858 false,
2859 )
2860 .unwrap();
2861
2862 sparse
2868 .reveal_node(
2869 Nibbles::default(),
2870 branch,
2871 TrieMasks { hash_mask: None, tree_mask: Some(TrieMask::new(0b01)) },
2872 )
2873 .unwrap();
2874 sparse
2875 .reveal_node(Nibbles::from_nibbles([0x1]), TrieNode::Leaf(leaf), TrieMasks::none())
2876 .unwrap();
2877
2878 assert_matches!(
2880 sparse.remove_leaf(&Nibbles::from_nibbles([0x0]), &provider).map_err(|e| e.into_kind()),
2881 Err(SparseTrieErrorKind::BlindedNode { path, hash }) if path == Nibbles::from_nibbles([0x0]) && hash == B256::repeat_byte(1)
2882 );
2883 }
2884
2885 #[test]
2886 fn sparse_trie_remove_leaf_non_existent() {
2887 let leaf = LeafNode::new(
2888 Nibbles::default(),
2889 alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(),
2890 );
2891 let branch = TrieNode::Branch(BranchNode::new(
2892 vec![
2893 RlpNode::word_rlp(&B256::repeat_byte(1)),
2894 RlpNode::from_raw_rlp(&alloy_rlp::encode(leaf.clone())).unwrap(),
2895 ],
2896 TrieMask::new(0b11),
2897 ));
2898
2899 let provider = DefaultTrieNodeProvider;
2900 let mut sparse = SerialSparseTrie::from_root(
2901 branch.clone(),
2902 TrieMasks { hash_mask: Some(TrieMask::new(0b01)), tree_mask: None },
2903 false,
2904 )
2905 .unwrap();
2906
2907 sparse
2913 .reveal_node(
2914 Nibbles::default(),
2915 branch,
2916 TrieMasks { hash_mask: None, tree_mask: Some(TrieMask::new(0b01)) },
2917 )
2918 .unwrap();
2919 sparse
2920 .reveal_node(Nibbles::from_nibbles([0x1]), TrieNode::Leaf(leaf), TrieMasks::none())
2921 .unwrap();
2922
2923 let sparse_old = sparse.clone();
2925 assert_matches!(sparse.remove_leaf(&Nibbles::from_nibbles([0x2]), &provider), Ok(()));
2926 assert_eq!(sparse, sparse_old);
2927 }
2928
2929 #[test]
2930 fn sparse_trie_fuzz() {
2931 const KEY_NIBBLES_LEN: usize = 3;
2935
2936 fn test(updates: Vec<(BTreeMap<Nibbles, Account>, BTreeSet<Nibbles>)>) {
2937 {
2938 let mut state = BTreeMap::default();
2939 let default_provider = DefaultTrieNodeProvider;
2940 let provider_factory = create_test_provider_factory();
2941 let mut sparse = SerialSparseTrie::default().with_updates(true);
2942
2943 for (update, keys_to_delete) in updates {
2944 for (key, account) in update.clone() {
2946 let account = account.into_trie_account(EMPTY_ROOT_HASH);
2947 let mut account_rlp = Vec::new();
2948 account.encode(&mut account_rlp);
2949 sparse.update_leaf(key, account_rlp, &default_provider).unwrap();
2950 }
2951 let mut updated_sparse = sparse.clone();
2955 let sparse_root = updated_sparse.root();
2956 let sparse_updates = updated_sparse.take_updates();
2957
2958 state.extend(update);
2960 let provider = provider_factory.provider().unwrap();
2961 let trie_cursor = DatabaseTrieCursorFactory::new(provider.tx_ref());
2962 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2963 run_hash_builder(
2964 state.clone(),
2965 trie_cursor.account_trie_cursor().unwrap(),
2966 Default::default(),
2967 state.keys().copied().collect::<Vec<_>>(),
2968 );
2969
2970 let provider_rw = provider_factory.provider_rw().unwrap();
2972 provider_rw.write_trie_updates(&hash_builder_updates).unwrap();
2973 provider_rw.commit().unwrap();
2974
2975 assert_eq!(sparse_root, hash_builder_root);
2977 pretty_assertions::assert_eq!(
2979 BTreeMap::from_iter(sparse_updates.updated_nodes),
2980 BTreeMap::from_iter(hash_builder_updates.account_nodes)
2981 );
2982 assert_eq_sparse_trie_proof_nodes(&updated_sparse, hash_builder_proof_nodes);
2984
2985 for key in &keys_to_delete {
2988 state.remove(key).unwrap();
2989 sparse.remove_leaf(key, &default_provider).unwrap();
2990 }
2991
2992 let mut updated_sparse = sparse.clone();
2996 let sparse_root = updated_sparse.root();
2997 let sparse_updates = updated_sparse.take_updates();
2998
2999 let provider = provider_factory.provider().unwrap();
3000 let trie_cursor = DatabaseTrieCursorFactory::new(provider.tx_ref());
3001 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
3002 run_hash_builder(
3003 state.clone(),
3004 trie_cursor.account_trie_cursor().unwrap(),
3005 keys_to_delete
3006 .iter()
3007 .map(|nibbles| B256::from_slice(&nibbles.pack()))
3008 .collect(),
3009 state.keys().copied().collect::<Vec<_>>(),
3010 );
3011
3012 let provider_rw = provider_factory.provider_rw().unwrap();
3014 provider_rw.write_trie_updates(&hash_builder_updates).unwrap();
3015 provider_rw.commit().unwrap();
3016
3017 assert_eq!(sparse_root, hash_builder_root);
3019 pretty_assertions::assert_eq!(
3021 BTreeMap::from_iter(sparse_updates.updated_nodes),
3022 BTreeMap::from_iter(hash_builder_updates.account_nodes)
3023 );
3024 assert_eq_sparse_trie_proof_nodes(&updated_sparse, hash_builder_proof_nodes);
3026 }
3027 }
3028 }
3029
3030 fn transform_updates(
3031 updates: Vec<BTreeMap<Nibbles, Account>>,
3032 mut rng: impl rand::Rng,
3033 ) -> Vec<(BTreeMap<Nibbles, Account>, BTreeSet<Nibbles>)> {
3034 let mut keys = BTreeSet::new();
3035 updates
3036 .into_iter()
3037 .map(|update| {
3038 keys.extend(update.keys().copied());
3039
3040 let keys_to_delete_len = update.len() / 2;
3041 let keys_to_delete = (0..keys_to_delete_len)
3042 .map(|_| {
3043 let key =
3044 *rand::seq::IteratorRandom::choose(keys.iter(), &mut rng).unwrap();
3045 keys.take(&key).unwrap()
3046 })
3047 .collect();
3048
3049 (update, keys_to_delete)
3050 })
3051 .collect::<Vec<_>>()
3052 }
3053
3054 proptest!(ProptestConfig::with_cases(10), |(
3055 updates in proptest::collection::vec(
3056 proptest::collection::btree_map(
3057 any_with::<Nibbles>(SizeRange::new(KEY_NIBBLES_LEN..=KEY_NIBBLES_LEN)).prop_map(pad_nibbles_right),
3058 arb::<Account>(),
3059 1..50,
3060 ),
3061 1..50,
3062 ).prop_perturb(transform_updates)
3063 )| {
3064 test(updates)
3065 });
3066 }
3067
3068 #[test]
3080 fn sparse_trie_reveal_node_1() {
3081 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00]));
3082 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01]));
3083 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x02]));
3084 let value = || Account::default();
3085 let value_encoded = || {
3086 let mut account_rlp = Vec::new();
3087 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
3088 account_rlp
3089 };
3090
3091 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3093 run_hash_builder(
3094 [(key1(), value()), (key3(), value())],
3095 NoopAccountTrieCursor::default(),
3096 Default::default(),
3097 [Nibbles::default()],
3098 );
3099
3100 let provider = DefaultTrieNodeProvider;
3101 let mut sparse = SerialSparseTrie::from_root(
3102 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
3103 TrieMasks {
3104 hash_mask: branch_node_hash_masks.get(&Nibbles::default()).copied(),
3105 tree_mask: branch_node_tree_masks.get(&Nibbles::default()).copied(),
3106 },
3107 false,
3108 )
3109 .unwrap();
3110
3111 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3113 run_hash_builder(
3114 [(key1(), value()), (key3(), value())],
3115 NoopAccountTrieCursor::default(),
3116 Default::default(),
3117 [key1()],
3118 );
3119 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3120 let hash_mask = branch_node_hash_masks.get(&path).copied();
3121 let tree_mask = branch_node_tree_masks.get(&path).copied();
3122 sparse
3123 .reveal_node(
3124 path,
3125 TrieNode::decode(&mut &node[..]).unwrap(),
3126 TrieMasks { hash_mask, tree_mask },
3127 )
3128 .unwrap();
3129 }
3130
3131 assert_eq!(
3133 sparse.nodes.get(&Nibbles::default()),
3134 Some(&SparseNode::new_branch(0b101.into()))
3135 );
3136
3137 sparse.update_leaf(key2(), value_encoded(), &provider).unwrap();
3139
3140 assert_eq!(
3142 sparse.nodes.get(&Nibbles::default()),
3143 Some(&SparseNode::new_branch(0b111.into()))
3144 );
3145
3146 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3148 run_hash_builder(
3149 [(key1(), value()), (key3(), value())],
3150 NoopAccountTrieCursor::default(),
3151 Default::default(),
3152 [key3()],
3153 );
3154 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3155 let hash_mask = branch_node_hash_masks.get(&path).copied();
3156 let tree_mask = branch_node_tree_masks.get(&path).copied();
3157 sparse
3158 .reveal_node(
3159 path,
3160 TrieNode::decode(&mut &node[..]).unwrap(),
3161 TrieMasks { hash_mask, tree_mask },
3162 )
3163 .unwrap();
3164 }
3165
3166 assert_eq!(
3168 sparse.nodes.get(&Nibbles::default()),
3169 Some(&SparseNode::new_branch(0b111.into()))
3170 );
3171
3172 let (_, _, hash_builder_proof_nodes, _, _) = run_hash_builder(
3175 [(key1(), value()), (key2(), value()), (key3(), value())],
3176 NoopAccountTrieCursor::default(),
3177 Default::default(),
3178 [key1(), key2(), key3()],
3179 );
3180
3181 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
3182 }
3183
3184 #[test]
3195 fn sparse_trie_reveal_node_2() {
3196 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x00]));
3197 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x01]));
3198 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x02]));
3199 let value = || Account::default();
3200
3201 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3203 run_hash_builder(
3204 [(key1(), value()), (key2(), value()), (key3(), value())],
3205 NoopAccountTrieCursor::default(),
3206 Default::default(),
3207 [Nibbles::default()],
3208 );
3209
3210 let provider = DefaultTrieNodeProvider;
3211 let mut sparse = SerialSparseTrie::from_root(
3212 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
3213 TrieMasks {
3214 hash_mask: branch_node_hash_masks.get(&Nibbles::default()).copied(),
3215 tree_mask: branch_node_tree_masks.get(&Nibbles::default()).copied(),
3216 },
3217 false,
3218 )
3219 .unwrap();
3220
3221 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3224 run_hash_builder(
3225 [(key1(), value()), (key2(), value()), (key3(), value())],
3226 NoopAccountTrieCursor::default(),
3227 Default::default(),
3228 [key1(), Nibbles::from_nibbles_unchecked([0x01])],
3229 );
3230 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3231 let hash_mask = branch_node_hash_masks.get(&path).copied();
3232 let tree_mask = branch_node_tree_masks.get(&path).copied();
3233 sparse
3234 .reveal_node(
3235 path,
3236 TrieNode::decode(&mut &node[..]).unwrap(),
3237 TrieMasks { hash_mask, tree_mask },
3238 )
3239 .unwrap();
3240 }
3241
3242 assert_eq!(
3244 sparse.nodes.get(&Nibbles::default()),
3245 Some(&SparseNode::new_branch(0b11.into()))
3246 );
3247
3248 sparse.remove_leaf(&key1(), &provider).unwrap();
3250
3251 assert_eq!(
3253 sparse.nodes.get(&Nibbles::default()),
3254 Some(&SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x01])))
3255 );
3256
3257 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3259 run_hash_builder(
3260 [(key1(), value()), (key2(), value()), (key3(), value())],
3261 NoopAccountTrieCursor::default(),
3262 Default::default(),
3263 [key2()],
3264 );
3265 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3266 let hash_mask = branch_node_hash_masks.get(&path).copied();
3267 let tree_mask = branch_node_tree_masks.get(&path).copied();
3268 sparse
3269 .reveal_node(
3270 path,
3271 TrieNode::decode(&mut &node[..]).unwrap(),
3272 TrieMasks { hash_mask, tree_mask },
3273 )
3274 .unwrap();
3275 }
3276
3277 assert_eq!(
3279 sparse.nodes.get(&Nibbles::default()),
3280 Some(&SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x01])))
3281 );
3282 }
3283
3284 #[test]
3293 fn sparse_trie_reveal_node_3() {
3294 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x01]));
3295 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x02]));
3296 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x00]));
3297 let value = || Account::default();
3298 let value_encoded = || {
3299 let mut account_rlp = Vec::new();
3300 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
3301 account_rlp
3302 };
3303
3304 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3306 run_hash_builder(
3307 [(key1(), value()), (key2(), value())],
3308 NoopAccountTrieCursor::default(),
3309 Default::default(),
3310 [Nibbles::default()],
3311 );
3312
3313 let provider = DefaultTrieNodeProvider;
3314 let mut sparse = SerialSparseTrie::from_root(
3315 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
3316 TrieMasks {
3317 hash_mask: branch_node_hash_masks.get(&Nibbles::default()).copied(),
3318 tree_mask: branch_node_tree_masks.get(&Nibbles::default()).copied(),
3319 },
3320 false,
3321 )
3322 .unwrap();
3323
3324 assert_matches!(
3326 sparse.nodes.get(&Nibbles::default()),
3327 Some(SparseNode::Extension { key, hash: None, store_in_db_trie: None }) if *key == Nibbles::from_nibbles([0x00])
3328 );
3329
3330 sparse.update_leaf(key3(), value_encoded(), &provider).unwrap();
3332
3333 assert_matches!(
3335 sparse.nodes.get(&Nibbles::default()),
3336 Some(SparseNode::Branch { state_mask, hash: None, store_in_db_trie: None }) if *state_mask == TrieMask::new(0b11)
3337 );
3338
3339 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3341 run_hash_builder(
3342 [(key1(), value()), (key2(), value())],
3343 NoopAccountTrieCursor::default(),
3344 Default::default(),
3345 [key1()],
3346 );
3347 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3348 let hash_mask = branch_node_hash_masks.get(&path).copied();
3349 let tree_mask = branch_node_tree_masks.get(&path).copied();
3350 sparse
3351 .reveal_node(
3352 path,
3353 TrieNode::decode(&mut &node[..]).unwrap(),
3354 TrieMasks { hash_mask, tree_mask },
3355 )
3356 .unwrap();
3357 }
3358
3359 assert_matches!(
3361 sparse.nodes.get(&Nibbles::default()),
3362 Some(SparseNode::Branch { state_mask, hash: None, store_in_db_trie: None }) if *state_mask == TrieMask::new(0b11)
3363 );
3364 }
3365
3366 #[test]
3367 fn sparse_trie_get_changed_nodes_at_depth() {
3368 let provider = DefaultTrieNodeProvider;
3369 let mut sparse = SerialSparseTrie::default();
3370
3371 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3372
3373 sparse
3386 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3387 .unwrap();
3388 sparse
3389 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3390 .unwrap();
3391 sparse
3392 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3393 .unwrap();
3394 sparse
3395 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
3396 .unwrap();
3397 sparse
3398 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
3399 .unwrap();
3400 sparse
3401 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
3402 .unwrap();
3403
3404 assert_eq!(
3405 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 0),
3406 (vec![(0, Nibbles::default())], PrefixSetMut::default())
3407 );
3408 assert_eq!(
3409 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 1),
3410 (vec![(1, Nibbles::from_nibbles_unchecked([0x5]))], [Nibbles::default()].into())
3411 );
3412 assert_eq!(
3413 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 2),
3414 (
3415 vec![
3416 (2, Nibbles::from_nibbles_unchecked([0x5, 0x0])),
3417 (2, Nibbles::from_nibbles_unchecked([0x5, 0x2])),
3418 (2, Nibbles::from_nibbles_unchecked([0x5, 0x3]))
3419 ],
3420 [Nibbles::default(), Nibbles::from_nibbles_unchecked([0x5])].into()
3421 )
3422 );
3423 assert_eq!(
3424 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 3),
3425 (
3426 vec![
3427 (3, Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3])),
3428 (2, Nibbles::from_nibbles_unchecked([0x5, 0x2])),
3429 (3, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x1])),
3430 (3, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3]))
3431 ],
3432 [
3433 Nibbles::default(),
3434 Nibbles::from_nibbles_unchecked([0x5]),
3435 Nibbles::from_nibbles_unchecked([0x5, 0x0]),
3436 Nibbles::from_nibbles_unchecked([0x5, 0x3])
3437 ]
3438 .into()
3439 )
3440 );
3441 assert_eq!(
3442 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 4),
3443 (
3444 vec![
3445 (4, Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3, 0x1])),
3446 (4, Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3, 0x3])),
3447 (2, Nibbles::from_nibbles_unchecked([0x5, 0x2])),
3448 (3, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x1])),
3449 (4, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3, 0x0])),
3450 (4, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3, 0x2]))
3451 ],
3452 [
3453 Nibbles::default(),
3454 Nibbles::from_nibbles_unchecked([0x5]),
3455 Nibbles::from_nibbles_unchecked([0x5, 0x0]),
3456 Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3]),
3457 Nibbles::from_nibbles_unchecked([0x5, 0x3]),
3458 Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3])
3459 ]
3460 .into()
3461 )
3462 );
3463 }
3464
3465 #[test]
3466 fn hash_builder_branch_hash_mask() {
3467 let key1 = || pad_nibbles_left(Nibbles::from_nibbles_unchecked([0x00]));
3468 let key2 = || pad_nibbles_left(Nibbles::from_nibbles_unchecked([0x01]));
3469 let value = || Account { bytecode_hash: Some(B256::repeat_byte(1)), ..Default::default() };
3470 let value_encoded = || {
3471 let mut account_rlp = Vec::new();
3472 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
3473 account_rlp
3474 };
3475
3476 let (hash_builder_root, hash_builder_updates, _, _, _) = run_hash_builder(
3477 [(key1(), value()), (key2(), value())],
3478 NoopAccountTrieCursor::default(),
3479 Default::default(),
3480 [Nibbles::default()],
3481 );
3482
3483 let provider = DefaultTrieNodeProvider;
3484 let mut sparse = SerialSparseTrie::default();
3485 sparse.update_leaf(key1(), value_encoded(), &provider).unwrap();
3486 sparse.update_leaf(key2(), value_encoded(), &provider).unwrap();
3487 let sparse_root = sparse.root();
3488 let sparse_updates = sparse.take_updates();
3489
3490 assert_eq!(sparse_root, hash_builder_root);
3491 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
3492 }
3493
3494 #[test]
3495 fn sparse_trie_wipe() {
3496 let provider = DefaultTrieNodeProvider;
3497 let mut sparse = SerialSparseTrie::default().with_updates(true);
3498
3499 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3500
3501 sparse
3514 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3515 .unwrap();
3516 sparse
3517 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3518 .unwrap();
3519 sparse
3520 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3521 .unwrap();
3522 sparse
3523 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
3524 .unwrap();
3525 sparse
3526 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
3527 .unwrap();
3528 sparse
3529 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
3530 .unwrap();
3531
3532 sparse.wipe();
3533
3534 assert_matches!(
3535 &sparse.updates,
3536 Some(SparseTrieUpdates{ updated_nodes, removed_nodes, wiped })
3537 if updated_nodes.is_empty() && removed_nodes.is_empty() && *wiped
3538 );
3539 assert_eq!(sparse.root(), EMPTY_ROOT_HASH);
3540 }
3541
3542 #[test]
3543 fn sparse_trie_clear() {
3544 let provider = DefaultTrieNodeProvider;
3547 let mut sparse = SerialSparseTrie::default();
3548 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3549 sparse
3550 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3551 .unwrap();
3552 sparse
3553 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3554 .unwrap();
3555 sparse
3556 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3557 .unwrap();
3558 sparse
3559 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value, &provider)
3560 .unwrap();
3561
3562 sparse.clear();
3563
3564 let empty_trie = SerialSparseTrie::default();
3565 assert_eq!(empty_trie, sparse);
3566 }
3567
3568 #[test]
3569 fn sparse_trie_display() {
3570 let provider = DefaultTrieNodeProvider;
3571 let mut sparse = SerialSparseTrie::default();
3572
3573 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3574
3575 sparse
3588 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3589 .unwrap();
3590 sparse
3591 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3592 .unwrap();
3593 sparse
3594 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3595 .unwrap();
3596 sparse
3597 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
3598 .unwrap();
3599 sparse
3600 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
3601 .unwrap();
3602 sparse
3603 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
3604 .unwrap();
3605
3606 let normal_printed = format!("{sparse}");
3607 let expected = "\
3608Root -> Extension { key: Nibbles(0x5), hash: None, store_in_db_trie: None }
36095 -> Branch { state_mask: TrieMask(0000000000001101), hash: None, store_in_db_trie: None }
361050 -> Extension { key: Nibbles(0x23), hash: None, store_in_db_trie: None }
36115023 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
361250231 -> Leaf { key: Nibbles(0x), hash: None }
361350233 -> Leaf { key: Nibbles(0x), hash: None }
361452013 -> Leaf { key: Nibbles(0x013), hash: None }
361553 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
361653102 -> Leaf { key: Nibbles(0x02), hash: None }
3617533 -> Branch { state_mask: TrieMask(0000000000000101), hash: None, store_in_db_trie: None }
361853302 -> Leaf { key: Nibbles(0x2), hash: None }
361953320 -> Leaf { key: Nibbles(0x0), hash: None }
3620";
3621 assert_eq!(normal_printed, expected);
3622
3623 let alternate_printed = format!("{sparse:#}");
3624 let expected = "\
3625Root -> Extension { key: Nibbles(0x5), hash: None, store_in_db_trie: None }
3626 5 -> Branch { state_mask: TrieMask(0000000000001101), hash: None, store_in_db_trie: None }
3627 50 -> Extension { key: Nibbles(0x23), hash: None, store_in_db_trie: None }
3628 5023 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
3629 50231 -> Leaf { key: Nibbles(0x), hash: None }
3630 50233 -> Leaf { key: Nibbles(0x), hash: None }
3631 52013 -> Leaf { key: Nibbles(0x013), hash: None }
3632 53 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
3633 53102 -> Leaf { key: Nibbles(0x02), hash: None }
3634 533 -> Branch { state_mask: TrieMask(0000000000000101), hash: None, store_in_db_trie: None }
3635 53302 -> Leaf { key: Nibbles(0x2), hash: None }
3636 53320 -> Leaf { key: Nibbles(0x0), hash: None }
3637";
3638
3639 assert_eq!(alternate_printed, expected);
3640 }
3641}