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::{debug, trace};
28
29const SPARSE_TRIE_SUBTRIE_HASHES_LEVEL: usize = 2;
32
33#[derive(PartialEq, Eq, Debug, Clone)]
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 fn blind_from(mut trie: T) -> Self {
138 trie.clear();
139 Self::Blind(Some(Box::new(trie)))
140 }
141
142 pub const fn is_blind(&self) -> bool {
144 matches!(self, Self::Blind(_))
145 }
146
147 pub const fn is_revealed(&self) -> bool {
149 matches!(self, Self::Revealed(_))
150 }
151
152 pub const fn as_revealed_ref(&self) -> Option<&T> {
156 if let Self::Revealed(revealed) = self {
157 Some(revealed)
158 } else {
159 None
160 }
161 }
162
163 pub fn as_revealed_mut(&mut self) -> Option<&mut T> {
167 if let Self::Revealed(revealed) = self {
168 Some(revealed)
169 } else {
170 None
171 }
172 }
173
174 pub fn wipe(&mut self) -> SparseTrieResult<()> {
179 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
180 revealed.wipe();
181 Ok(())
182 }
183
184 pub fn root(&mut self) -> Option<B256> {
195 Some(self.as_revealed_mut()?.root())
196 }
197
198 pub fn root_with_updates(&mut self) -> Option<(B256, SparseTrieUpdates)> {
211 let revealed = self.as_revealed_mut()?;
212 Some((revealed.root(), revealed.take_updates()))
213 }
214
215 pub fn clear(self) -> Self {
219 match self {
220 Self::Blind(_) => self,
221 Self::Revealed(mut trie) => {
222 trie.clear();
223 Self::Blind(Some(trie))
224 }
225 }
226 }
227
228 pub fn update_leaf(
234 &mut self,
235 path: Nibbles,
236 value: Vec<u8>,
237 provider: impl TrieNodeProvider,
238 ) -> SparseTrieResult<()> {
239 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
240 revealed.update_leaf(path, value, provider)?;
241 Ok(())
242 }
243
244 pub fn remove_leaf(
250 &mut self,
251 path: &Nibbles,
252 provider: impl TrieNodeProvider,
253 ) -> SparseTrieResult<()> {
254 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
255 revealed.remove_leaf(path, provider)?;
256 Ok(())
257 }
258}
259
260#[derive(Clone, PartialEq, Eq)]
274pub struct SerialSparseTrie {
275 nodes: HashMap<Nibbles, SparseNode>,
278 branch_node_tree_masks: HashMap<Nibbles, TrieMask>,
280 branch_node_hash_masks: HashMap<Nibbles, TrieMask>,
282 values: HashMap<Nibbles, Vec<u8>>,
285 prefix_set: PrefixSetMut,
288 updates: Option<SparseTrieUpdates>,
290 rlp_buf: Vec<u8>,
292}
293
294impl fmt::Debug for SerialSparseTrie {
295 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
296 f.debug_struct("SerialSparseTrie")
297 .field("nodes", &self.nodes)
298 .field("branch_tree_masks", &self.branch_node_tree_masks)
299 .field("branch_hash_masks", &self.branch_node_hash_masks)
300 .field("values", &self.values)
301 .field("prefix_set", &self.prefix_set)
302 .field("updates", &self.updates)
303 .field("rlp_buf", &hex::encode(&self.rlp_buf))
304 .finish_non_exhaustive()
305 }
306}
307
308fn encode_nibbles(nibbles: &Nibbles) -> String {
310 let encoded = hex::encode(nibbles.pack());
311 encoded[..nibbles.len()].to_string()
312}
313
314impl fmt::Display for SerialSparseTrie {
315 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316 let mut stack = Vec::new();
318 let mut visited = HashSet::new();
319
320 const INDENT: &str = " ";
322
323 stack.push((Nibbles::default(), self.nodes_ref().get(&Nibbles::default()).unwrap(), 0));
325
326 while let Some((path, node, depth)) = stack.pop() {
327 if !visited.insert(path) {
328 continue;
329 }
330
331 if f.alternate() {
333 write!(f, "{}", INDENT.repeat(depth))?;
334 }
335
336 let packed_path = if depth == 0 { String::from("Root") } else { encode_nibbles(&path) };
337
338 match node {
339 SparseNode::Empty | SparseNode::Hash(_) => {
340 writeln!(f, "{packed_path} -> {node:?}")?;
341 }
342 SparseNode::Leaf { key, .. } => {
343 let mut full_path = path;
345 full_path.extend(key);
346 let packed_path = encode_nibbles(&full_path);
347
348 writeln!(f, "{packed_path} -> {node:?}")?;
349 }
350 SparseNode::Extension { key, .. } => {
351 writeln!(f, "{packed_path} -> {node:?}")?;
352
353 let mut child_path = path;
355 child_path.extend(key);
356 if let Some(child_node) = self.nodes_ref().get(&child_path) {
357 stack.push((child_path, child_node, depth + 1));
358 }
359 }
360 SparseNode::Branch { state_mask, .. } => {
361 writeln!(f, "{packed_path} -> {node:?}")?;
362
363 for i in CHILD_INDEX_RANGE.rev() {
364 if state_mask.is_bit_set(i) {
365 let mut child_path = path;
366 child_path.push_unchecked(i);
367 if let Some(child_node) = self.nodes_ref().get(&child_path) {
368 stack.push((child_path, child_node, depth + 1));
369 }
370 }
371 }
372 }
373 }
374 }
375
376 Ok(())
377 }
378}
379
380impl Default for SerialSparseTrie {
381 fn default() -> Self {
382 Self {
383 nodes: HashMap::from_iter([(Nibbles::default(), SparseNode::Empty)]),
384 branch_node_tree_masks: HashMap::default(),
385 branch_node_hash_masks: HashMap::default(),
386 values: HashMap::default(),
387 prefix_set: PrefixSetMut::default(),
388 updates: None,
389 rlp_buf: Vec::new(),
390 }
391 }
392}
393
394impl SparseTrieInterface for SerialSparseTrie {
395 fn with_root(
396 mut self,
397 root: TrieNode,
398 masks: TrieMasks,
399 retain_updates: bool,
400 ) -> SparseTrieResult<Self> {
401 self = self.with_updates(retain_updates);
402
403 let path = Nibbles::default();
406 let _removed_root = self.nodes.remove(&path).expect("root node should exist");
407 debug_assert_eq!(_removed_root, SparseNode::Empty);
408
409 self.reveal_node(path, root, masks)?;
410 Ok(self)
411 }
412
413 fn with_updates(mut self, retain_updates: bool) -> Self {
414 if retain_updates {
415 self.updates = Some(SparseTrieUpdates::default());
416 }
417 self
418 }
419
420 fn reserve_nodes(&mut self, additional: usize) {
421 self.nodes.reserve(additional);
422 }
423 fn reveal_node(
424 &mut self,
425 path: Nibbles,
426 node: TrieNode,
427 masks: TrieMasks,
428 ) -> SparseTrieResult<()> {
429 trace!(target: "trie::sparse", ?path, ?node, ?masks, "reveal_node called");
430
431 if self.nodes.get(&path).is_some_and(|node| !node.is_hash()) {
433 return Ok(())
434 }
435
436 if let Some(tree_mask) = masks.tree_mask {
437 self.branch_node_tree_masks.insert(path, tree_mask);
438 }
439 if let Some(hash_mask) = masks.hash_mask {
440 self.branch_node_hash_masks.insert(path, hash_mask);
441 }
442
443 match node {
444 TrieNode::EmptyRoot => {
445 debug_assert!(path.is_empty());
447 self.nodes.insert(path, SparseNode::Empty);
448 }
449 TrieNode::Branch(branch) => {
450 let mut stack_ptr = branch.as_ref().first_child_index();
452 for idx in CHILD_INDEX_RANGE {
453 if branch.state_mask.is_bit_set(idx) {
454 let mut child_path = path;
455 child_path.push_unchecked(idx);
456 self.reveal_node_or_hash(child_path, &branch.stack[stack_ptr])?;
458 stack_ptr += 1;
459 }
460 }
461 match self.nodes.entry(path) {
464 Entry::Occupied(mut entry) => match entry.get() {
465 SparseNode::Hash(hash) => {
467 entry.insert(SparseNode::Branch {
468 state_mask: branch.state_mask,
469 hash: Some(*hash),
472 store_in_db_trie: Some(
473 masks.hash_mask.is_some_and(|mask| !mask.is_empty()) ||
474 masks.tree_mask.is_some_and(|mask| !mask.is_empty()),
475 ),
476 });
477 }
478 SparseNode::Branch { .. } | SparseNode::Extension { .. } => {}
481 node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => {
483 return Err(SparseTrieErrorKind::Reveal {
484 path: *entry.key(),
485 node: Box::new(node.clone()),
486 }
487 .into())
488 }
489 },
490 Entry::Vacant(entry) => {
491 entry.insert(SparseNode::new_branch(branch.state_mask));
492 }
493 }
494 }
495 TrieNode::Extension(ext) => match self.nodes.entry(path) {
496 Entry::Occupied(mut entry) => match entry.get() {
497 SparseNode::Hash(hash) => {
499 let mut child_path = *entry.key();
500 child_path.extend(&ext.key);
501 entry.insert(SparseNode::Extension {
502 key: ext.key,
503 hash: Some(*hash),
506 store_in_db_trie: None,
507 });
508 self.reveal_node_or_hash(child_path, &ext.child)?;
509 }
510 SparseNode::Extension { .. } | SparseNode::Branch { .. } => {}
513 node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => {
515 return Err(SparseTrieErrorKind::Reveal {
516 path: *entry.key(),
517 node: Box::new(node.clone()),
518 }
519 .into())
520 }
521 },
522 Entry::Vacant(entry) => {
523 let mut child_path = *entry.key();
524 child_path.extend(&ext.key);
525 entry.insert(SparseNode::new_ext(ext.key));
526 self.reveal_node_or_hash(child_path, &ext.child)?;
527 }
528 },
529 TrieNode::Leaf(leaf) => match self.nodes.entry(path) {
530 Entry::Occupied(mut entry) => match entry.get() {
531 SparseNode::Hash(hash) => {
533 let mut full = *entry.key();
534 full.extend(&leaf.key);
535 self.values.insert(full, leaf.value.clone());
536 entry.insert(SparseNode::Leaf {
537 key: leaf.key,
538 hash: Some(*hash),
541 });
542 }
543 SparseNode::Leaf { .. } => {}
545 node @ (SparseNode::Empty |
547 SparseNode::Extension { .. } |
548 SparseNode::Branch { .. }) => {
549 return Err(SparseTrieErrorKind::Reveal {
550 path: *entry.key(),
551 node: Box::new(node.clone()),
552 }
553 .into())
554 }
555 },
556 Entry::Vacant(entry) => {
557 let mut full = *entry.key();
558 full.extend(&leaf.key);
559 entry.insert(SparseNode::new_leaf(leaf.key));
560 self.values.insert(full, leaf.value.clone());
561 }
562 },
563 }
564
565 Ok(())
566 }
567
568 fn reveal_nodes(&mut self, mut nodes: Vec<RevealedSparseNode>) -> SparseTrieResult<()> {
569 nodes.sort_unstable_by_key(|node| node.path);
570 for node in nodes {
571 self.reveal_node(node.path, node.node, node.masks)?;
572 }
573 Ok(())
574 }
575
576 fn update_leaf<P: TrieNodeProvider>(
577 &mut self,
578 full_path: Nibbles,
579 value: Vec<u8>,
580 provider: P,
581 ) -> SparseTrieResult<()> {
582 trace!(target: "trie::sparse", ?full_path, ?value, "update_leaf called");
583
584 self.prefix_set.insert(full_path);
585 let existing = self.values.insert(full_path, value);
586 if existing.is_some() {
587 return Ok(())
589 }
590
591 let mut current = Nibbles::default();
592 while let Some(node) = self.nodes.get_mut(¤t) {
593 match node {
594 SparseNode::Empty => {
595 *node = SparseNode::new_leaf(full_path);
596 break
597 }
598 &mut SparseNode::Hash(hash) => {
599 return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into())
600 }
601 SparseNode::Leaf { key: current_key, .. } => {
602 current.extend(current_key);
603
604 if current == full_path {
606 unreachable!("we already checked leaf presence in the beginning");
607 }
608
609 let common = current.common_prefix_length(&full_path);
611
612 let new_ext_key = current.slice(current.len() - current_key.len()..common);
614 *node = SparseNode::new_ext(new_ext_key);
615
616 self.nodes.reserve(3);
618 self.nodes.insert(
619 current.slice(..common),
620 SparseNode::new_split_branch(
621 current.get_unchecked(common),
622 full_path.get_unchecked(common),
623 ),
624 );
625 self.nodes.insert(
626 full_path.slice(..=common),
627 SparseNode::new_leaf(full_path.slice(common + 1..)),
628 );
629 self.nodes.insert(
630 current.slice(..=common),
631 SparseNode::new_leaf(current.slice(common + 1..)),
632 );
633
634 break;
635 }
636 SparseNode::Extension { key, .. } => {
637 current.extend(key);
638
639 if !full_path.starts_with(¤t) {
640 let common = current.common_prefix_length(&full_path);
642 *key = current.slice(current.len() - key.len()..common);
643
644 if self.updates.is_some() {
648 if self.nodes.get(¤t).unwrap().is_hash() {
650 debug!(
651 target: "trie::sparse",
652 leaf_full_path = ?full_path,
653 child_path = ?current,
654 "Extension node child not revealed in update_leaf, falling back to db",
655 );
656 if let Some(RevealedNode { node, tree_mask, hash_mask }) =
657 provider.trie_node(¤t)?
658 {
659 let decoded = TrieNode::decode(&mut &node[..])?;
660 trace!(
661 target: "trie::sparse",
662 ?current,
663 ?decoded,
664 ?tree_mask,
665 ?hash_mask,
666 "Revealing extension node child",
667 );
668 self.reveal_node(
669 current,
670 decoded,
671 TrieMasks { hash_mask, tree_mask },
672 )?;
673 }
674 }
675 }
676
677 self.nodes.reserve(3);
680 let branch = SparseNode::new_split_branch(
681 current.get_unchecked(common),
682 full_path.get_unchecked(common),
683 );
684 self.nodes.insert(current.slice(..common), branch);
685
686 let new_leaf = SparseNode::new_leaf(full_path.slice(common + 1..));
688 self.nodes.insert(full_path.slice(..=common), new_leaf);
689
690 let key = current.slice(common + 1..);
692 if !key.is_empty() {
693 self.nodes.insert(current.slice(..=common), SparseNode::new_ext(key));
694 }
695
696 break;
697 }
698 }
699 SparseNode::Branch { state_mask, .. } => {
700 let nibble = full_path.get_unchecked(current.len());
701 current.push_unchecked(nibble);
702 if !state_mask.is_bit_set(nibble) {
703 state_mask.set_bit(nibble);
704 let new_leaf = SparseNode::new_leaf(full_path.slice(current.len()..));
705 self.nodes.insert(current, new_leaf);
706 break;
707 }
708 }
709 };
710 }
711
712 Ok(())
713 }
714
715 fn remove_leaf<P: TrieNodeProvider>(
716 &mut self,
717 full_path: &Nibbles,
718 provider: P,
719 ) -> SparseTrieResult<()> {
720 trace!(target: "trie::sparse", ?full_path, "remove_leaf called");
721
722 if self.values.remove(full_path).is_none() {
723 if let Some(&SparseNode::Hash(hash)) = self.nodes.get(full_path) {
724 return Err(SparseTrieErrorKind::BlindedNode { path: *full_path, hash }.into())
726 }
727
728 trace!(target: "trie::sparse", ?full_path, "Leaf node is not present in the trie");
729 return Ok(())
731 }
732 self.prefix_set.insert(*full_path);
733
734 let mut removed_nodes = self.take_nodes_for_path(full_path)?;
739 let mut child = removed_nodes.pop().expect("leaf exists");
741 #[cfg(debug_assertions)]
742 {
743 let mut child_path = child.path;
744 let SparseNode::Leaf { key, .. } = &child.node else { panic!("expected leaf node") };
745 child_path.extend(key);
746 assert_eq!(&child_path, full_path);
747 }
748
749 if removed_nodes.is_empty() {
751 debug_assert!(self.nodes.is_empty());
752 self.nodes.insert(Nibbles::default(), SparseNode::Empty);
753
754 return Ok(())
755 }
756
757 while let Some(removed_node) = removed_nodes.pop() {
760 let removed_path = removed_node.path;
761
762 let new_node = match &removed_node.node {
763 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
764 &SparseNode::Hash(hash) => {
765 return Err(SparseTrieErrorKind::BlindedNode { path: removed_path, hash }.into())
766 }
767 SparseNode::Leaf { .. } => {
768 unreachable!("we already popped the leaf node")
769 }
770 SparseNode::Extension { key, .. } => {
771 match &child.node {
774 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
775 &SparseNode::Hash(hash) => {
776 return Err(
777 SparseTrieErrorKind::BlindedNode { path: child.path, hash }.into()
778 )
779 }
780 SparseNode::Leaf { key: leaf_key, .. } => {
786 self.nodes.remove(&child.path);
787
788 let mut new_key = *key;
789 new_key.extend(leaf_key);
790 SparseNode::new_leaf(new_key)
791 }
792 SparseNode::Extension { key: extension_key, .. } => {
795 self.nodes.remove(&child.path);
796
797 let mut new_key = *key;
798 new_key.extend(extension_key);
799 SparseNode::new_ext(new_key)
800 }
801 SparseNode::Branch { .. } => removed_node.node,
803 }
804 }
805 &SparseNode::Branch { mut state_mask, hash: _, store_in_db_trie: _ } => {
806 if let Some(removed_nibble) = removed_node.unset_branch_nibble {
810 state_mask.unset_bit(removed_nibble);
811 }
812
813 if state_mask.count_bits() == 1 {
815 let child_nibble =
816 state_mask.first_set_bit_index().expect("state mask is not empty");
817
818 let mut child_path = removed_path;
820 child_path.push_unchecked(child_nibble);
821
822 trace!(target: "trie::sparse", ?removed_path, ?child_path, "Branch node has only one child");
823
824 let child = self.reveal_remaining_child_on_leaf_removal(
827 &provider,
828 full_path,
829 &child_path,
830 true, )?;
832
833 let mut delete_child = false;
834 let new_node = match &child {
835 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
836 &SparseNode::Hash(hash) => {
837 return Err(SparseTrieErrorKind::BlindedNode {
838 path: child_path,
839 hash,
840 }
841 .into())
842 }
843 SparseNode::Leaf { key, .. } => {
847 delete_child = true;
848
849 let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]);
850 new_key.extend(key);
851 SparseNode::new_leaf(new_key)
852 }
853 SparseNode::Extension { key, .. } => {
857 delete_child = true;
858
859 let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]);
860 new_key.extend(key);
861 SparseNode::new_ext(new_key)
862 }
863 SparseNode::Branch { .. } => {
866 SparseNode::new_ext(Nibbles::from_nibbles_unchecked([child_nibble]))
867 }
868 };
869
870 if delete_child {
871 self.nodes.remove(&child_path);
872 }
873
874 if let Some(updates) = self.updates.as_mut() {
875 updates.updated_nodes.remove(&removed_path);
876 updates.removed_nodes.insert(removed_path);
877 }
878
879 new_node
880 }
881 else {
883 SparseNode::new_branch(state_mask)
884 }
885 }
886 };
887
888 child = RemovedSparseNode {
889 path: removed_path,
890 node: new_node.clone(),
891 unset_branch_nibble: None,
892 };
893 trace!(target: "trie::sparse", ?removed_path, ?new_node, "Re-inserting the node");
894 self.nodes.insert(removed_path, new_node);
895 }
896
897 Ok(())
898 }
899
900 fn root(&mut self) -> B256 {
901 let mut prefix_set = core::mem::take(&mut self.prefix_set).freeze();
903 let rlp_node = self.rlp_node_allocate(&mut prefix_set);
904 if let Some(root_hash) = rlp_node.as_hash() {
905 root_hash
906 } else {
907 keccak256(rlp_node)
908 }
909 }
910
911 fn update_subtrie_hashes(&mut self) {
912 self.update_rlp_node_level(SPARSE_TRIE_SUBTRIE_HASHES_LEVEL);
913 }
914
915 fn get_leaf_value(&self, full_path: &Nibbles) -> Option<&Vec<u8>> {
916 self.values.get(full_path)
917 }
918
919 fn updates_ref(&self) -> Cow<'_, SparseTrieUpdates> {
920 self.updates.as_ref().map_or(Cow::Owned(SparseTrieUpdates::default()), Cow::Borrowed)
921 }
922
923 fn take_updates(&mut self) -> SparseTrieUpdates {
924 self.updates.take().unwrap_or_default()
925 }
926
927 fn wipe(&mut self) {
928 self.nodes = HashMap::from_iter([(Nibbles::default(), SparseNode::Empty)]);
929 self.values = HashMap::default();
930 self.prefix_set = PrefixSetMut::all();
931 self.updates = self.updates.is_some().then(SparseTrieUpdates::wiped);
932 }
933
934 fn clear(&mut self) {
935 self.nodes.clear();
936 self.nodes.insert(Nibbles::default(), SparseNode::Empty);
937
938 self.branch_node_tree_masks.clear();
939 self.branch_node_hash_masks.clear();
940 self.values.clear();
941 self.prefix_set.clear();
942 self.updates = None;
943 self.rlp_buf.clear();
944 }
945
946 fn find_leaf(
947 &self,
948 full_path: &Nibbles,
949 expected_value: Option<&Vec<u8>>,
950 ) -> Result<LeafLookup, LeafLookupError> {
951 fn check_value_match(
953 actual_value: &Vec<u8>,
954 expected_value: Option<&Vec<u8>>,
955 path: &Nibbles,
956 ) -> Result<(), LeafLookupError> {
957 if let Some(expected) = expected_value &&
958 actual_value != expected
959 {
960 return Err(LeafLookupError::ValueMismatch {
961 path: *path,
962 expected: Some(expected.clone()),
963 actual: actual_value.clone(),
964 });
965 }
966 Ok(())
967 }
968
969 let mut current = Nibbles::default(); if let Some(actual_value) = self.values.get(full_path) {
977 check_value_match(actual_value, expected_value, full_path)?;
979 return Ok(LeafLookup::Exists);
980 }
981
982 while current.len() < full_path.len() {
989 match self.nodes.get(¤t) {
990 Some(SparseNode::Empty) | None => {
991 return Ok(LeafLookup::NonExistent);
994 }
995 Some(&SparseNode::Hash(hash)) => {
996 return Err(LeafLookupError::BlindedNode { path: current, hash });
998 }
999 Some(SparseNode::Leaf { key, .. }) => {
1000 current.extend(key);
1002 if ¤t == full_path {
1003 if let Some(value) = self.values.get(full_path) {
1005 check_value_match(value, expected_value, full_path)?;
1006 return Ok(LeafLookup::Exists);
1007 }
1008 }
1009
1010 return Ok(LeafLookup::NonExistent);
1013 }
1014 Some(SparseNode::Extension { key, .. }) => {
1015 let saved_len = current.len();
1017 current.extend(key);
1018
1019 if full_path.len() < current.len() || !full_path.starts_with(¤t) {
1020 current.truncate(saved_len); return Ok(LeafLookup::NonExistent);
1022 }
1023 }
1025 Some(SparseNode::Branch { state_mask, .. }) => {
1026 let nibble = full_path.get_unchecked(current.len());
1028 if !state_mask.is_bit_set(nibble) {
1029 return Ok(LeafLookup::NonExistent);
1031 }
1032
1033 current.push_unchecked(nibble);
1035 }
1036 }
1037 }
1038
1039 match self.nodes.get(full_path) {
1042 Some(SparseNode::Leaf { key, .. }) if key.is_empty() => {
1043 if let Some(value) = self.values.get(full_path) {
1046 check_value_match(value, expected_value, full_path)?;
1047 return Ok(LeafLookup::Exists);
1048 }
1049 }
1050 Some(&SparseNode::Hash(hash)) => {
1051 return Err(LeafLookupError::BlindedNode { path: *full_path, hash });
1052 }
1053 _ => {
1054 return Ok(LeafLookup::NonExistent);
1056 }
1057 }
1058
1059 Ok(LeafLookup::NonExistent)
1061 }
1062}
1063
1064impl SerialSparseTrie {
1065 pub fn from_root(
1080 root: TrieNode,
1081 masks: TrieMasks,
1082 retain_updates: bool,
1083 ) -> SparseTrieResult<Self> {
1084 Self::default().with_root(root, masks, retain_updates)
1085 }
1086
1087 pub fn updates_ref(&self) -> Cow<'_, SparseTrieUpdates> {
1091 self.updates.as_ref().map_or(Cow::Owned(SparseTrieUpdates::default()), Cow::Borrowed)
1092 }
1093
1094 pub const fn nodes_ref(&self) -> &HashMap<Nibbles, SparseNode> {
1096 &self.nodes
1097 }
1098
1099 fn reveal_node_or_hash(&mut self, path: Nibbles, child: &[u8]) -> SparseTrieResult<()> {
1118 if child.len() == B256::len_bytes() + 1 {
1119 let hash = B256::from_slice(&child[1..]);
1120 match self.nodes.entry(path) {
1121 Entry::Occupied(entry) => match entry.get() {
1122 SparseNode::Hash(previous_hash) if previous_hash != &hash => {
1124 return Err(SparseTrieErrorKind::Reveal {
1125 path: *entry.key(),
1126 node: Box::new(SparseNode::Hash(hash)),
1127 }
1128 .into())
1129 }
1130 _ => {}
1131 },
1132 Entry::Vacant(entry) => {
1133 entry.insert(SparseNode::Hash(hash));
1134 }
1135 }
1136 return Ok(())
1137 }
1138
1139 self.reveal_node(path, TrieNode::decode(&mut &child[..])?, TrieMasks::none())
1140 }
1141
1142 fn take_nodes_for_path(&mut self, path: &Nibbles) -> SparseTrieResult<Vec<RemovedSparseNode>> {
1159 let mut current = Nibbles::default(); let mut nodes = Vec::new(); while let Some(node) = self.nodes.remove(¤t) {
1163 match &node {
1164 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
1165 &SparseNode::Hash(hash) => {
1166 return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into())
1167 }
1168 SparseNode::Leaf { key: _key, .. } => {
1169 #[cfg(debug_assertions)]
1173 {
1174 let mut current = current;
1175 current.extend(_key);
1176 assert_eq!(¤t, path);
1177 }
1178
1179 nodes.push(RemovedSparseNode {
1180 path: current,
1181 node,
1182 unset_branch_nibble: None,
1183 });
1184 break
1185 }
1186 SparseNode::Extension { key, .. } => {
1187 #[cfg(debug_assertions)]
1188 {
1189 let mut current = current;
1190 current.extend(key);
1191 assert!(
1192 path.starts_with(¤t),
1193 "path: {path:?}, current: {current:?}, key: {key:?}",
1194 );
1195 }
1196
1197 let path = current;
1198 current.extend(key);
1199 nodes.push(RemovedSparseNode { path, node, unset_branch_nibble: None });
1200 }
1201 SparseNode::Branch { state_mask, .. } => {
1202 let nibble = path.get_unchecked(current.len());
1203 debug_assert!(
1204 state_mask.is_bit_set(nibble),
1205 "current: {current:?}, path: {path:?}, nibble: {nibble:?}, state_mask: {state_mask:?}",
1206 );
1207
1208 let mut child_path = current;
1214 child_path.push_unchecked(nibble);
1215 let unset_branch_nibble = self
1216 .nodes
1217 .get(&child_path)
1218 .is_some_and(move |node| match node {
1219 SparseNode::Leaf { key, .. } => {
1220 child_path.extend(key);
1222 &child_path == path
1223 }
1224 _ => false,
1225 })
1226 .then_some(nibble);
1227
1228 nodes.push(RemovedSparseNode { path: current, node, unset_branch_nibble });
1229
1230 current.push_unchecked(nibble);
1231 }
1232 }
1233 }
1234
1235 Ok(nodes)
1236 }
1237
1238 fn reveal_remaining_child_on_leaf_removal<P: TrieNodeProvider>(
1248 &mut self,
1249 provider: P,
1250 full_path: &Nibbles, remaining_child_path: &Nibbles,
1252 recurse_into_extension: bool,
1253 ) -> SparseTrieResult<SparseNode> {
1254 let remaining_child_node = match self.nodes.get(remaining_child_path).unwrap() {
1255 SparseNode::Hash(_) => {
1256 debug!(
1257 target: "trie::parallel_sparse",
1258 child_path = ?remaining_child_path,
1259 leaf_full_path = ?full_path,
1260 "Node child not revealed in remove_leaf, falling back to db",
1261 );
1262 if let Some(RevealedNode { node, tree_mask, hash_mask }) =
1263 provider.trie_node(remaining_child_path)?
1264 {
1265 let decoded = TrieNode::decode(&mut &node[..])?;
1266 trace!(
1267 target: "trie::parallel_sparse",
1268 ?remaining_child_path,
1269 ?decoded,
1270 ?tree_mask,
1271 ?hash_mask,
1272 "Revealing remaining blinded branch child"
1273 );
1274 self.reveal_node(
1275 *remaining_child_path,
1276 decoded,
1277 TrieMasks { hash_mask, tree_mask },
1278 )?;
1279 self.nodes.get(remaining_child_path).unwrap().clone()
1280 } else {
1281 return Err(SparseTrieErrorKind::NodeNotFoundInProvider {
1282 path: *remaining_child_path,
1283 }
1284 .into())
1285 }
1286 }
1287 node => node.clone(),
1288 };
1289
1290 if let SparseNode::Extension { key, .. } = &remaining_child_node &&
1295 recurse_into_extension
1296 {
1297 let mut remaining_grandchild_path = *remaining_child_path;
1298 remaining_grandchild_path.extend(key);
1299
1300 trace!(
1301 target: "trie::parallel_sparse",
1302 remaining_grandchild_path = ?remaining_grandchild_path,
1303 child_path = ?remaining_child_path,
1304 leaf_full_path = ?full_path,
1305 "Revealing child of extension node, which is the last remaining child of the branch"
1306 );
1307
1308 self.reveal_remaining_child_on_leaf_removal(
1309 provider,
1310 full_path,
1311 &remaining_grandchild_path,
1312 false, )?;
1314 }
1315
1316 Ok(remaining_child_node)
1317 }
1318
1319 pub fn update_rlp_node_level(&mut self, depth: usize) {
1328 let mut prefix_set = core::mem::take(&mut self.prefix_set).freeze();
1330 let mut buffers = RlpNodeBuffers::default();
1331
1332 let (targets, new_prefix_set) = self.get_changed_nodes_at_depth(&mut prefix_set, depth);
1334 self.prefix_set = new_prefix_set;
1336
1337 trace!(target: "trie::sparse", ?depth, ?targets, "Updating nodes at depth");
1338
1339 let mut temp_rlp_buf = core::mem::take(&mut self.rlp_buf);
1340 for (level, path) in targets {
1341 buffers.path_stack.push(RlpNodePathStackItem {
1342 level,
1343 path,
1344 is_in_prefix_set: Some(true),
1345 });
1346 self.rlp_node(&mut prefix_set, &mut buffers, &mut temp_rlp_buf);
1347 }
1348 self.rlp_buf = temp_rlp_buf;
1349 }
1350
1351 fn get_changed_nodes_at_depth(
1373 &self,
1374 prefix_set: &mut PrefixSet,
1375 depth: usize,
1376 ) -> (Vec<(usize, Nibbles)>, PrefixSetMut) {
1377 let mut unchanged_prefix_set = PrefixSetMut::default();
1378 let mut paths = Vec::from([(Nibbles::default(), 0)]);
1379 let mut targets = Vec::new();
1380
1381 while let Some((mut path, level)) = paths.pop() {
1382 match self.nodes.get(&path).unwrap() {
1383 SparseNode::Empty | SparseNode::Hash(_) => {}
1384 SparseNode::Leaf { key: _, hash } => {
1385 if hash.is_some() && !prefix_set.contains(&path) {
1386 continue
1387 }
1388
1389 targets.push((level, path));
1390 }
1391 SparseNode::Extension { key, hash, store_in_db_trie: _ } => {
1392 if hash.is_some() && !prefix_set.contains(&path) {
1393 continue
1394 }
1395
1396 if level >= depth {
1397 targets.push((level, path));
1398 } else {
1399 unchanged_prefix_set.insert(path);
1400
1401 path.extend(key);
1402 paths.push((path, level + 1));
1403 }
1404 }
1405 SparseNode::Branch { state_mask, hash, store_in_db_trie: _ } => {
1406 if hash.is_some() && !prefix_set.contains(&path) {
1407 continue
1408 }
1409
1410 if level >= depth {
1411 targets.push((level, path));
1412 } else {
1413 unchanged_prefix_set.insert(path);
1414
1415 for bit in CHILD_INDEX_RANGE.rev() {
1416 if state_mask.is_bit_set(bit) {
1417 let mut child_path = path;
1418 child_path.push_unchecked(bit);
1419 paths.push((child_path, level + 1));
1420 }
1421 }
1422 }
1423 }
1424 }
1425 }
1426
1427 (targets, unchanged_prefix_set)
1428 }
1429
1430 pub fn rlp_node_allocate(&mut self, prefix_set: &mut PrefixSet) -> RlpNode {
1436 let mut buffers = RlpNodeBuffers::new_with_root_path();
1437 let mut temp_rlp_buf = core::mem::take(&mut self.rlp_buf);
1438 let result = self.rlp_node(prefix_set, &mut buffers, &mut temp_rlp_buf);
1439 self.rlp_buf = temp_rlp_buf;
1440
1441 result
1442 }
1443
1444 pub fn rlp_node(
1459 &mut self,
1460 prefix_set: &mut PrefixSet,
1461 buffers: &mut RlpNodeBuffers,
1462 rlp_buf: &mut Vec<u8>,
1463 ) -> RlpNode {
1464 let _starting_path = buffers.path_stack.last().map(|item| item.path);
1465
1466 'main: while let Some(RlpNodePathStackItem { level, path, mut is_in_prefix_set }) =
1467 buffers.path_stack.pop()
1468 {
1469 let node = self.nodes.get_mut(&path).unwrap();
1470 trace!(
1471 target: "trie::sparse",
1472 ?_starting_path,
1473 ?level,
1474 ?path,
1475 ?is_in_prefix_set,
1476 ?node,
1477 "Popped node from path stack"
1478 );
1479
1480 let mut prefix_set_contains =
1484 |path: &Nibbles| *is_in_prefix_set.get_or_insert_with(|| prefix_set.contains(path));
1485
1486 let (rlp_node, node_type) = match node {
1487 SparseNode::Empty => (RlpNode::word_rlp(&EMPTY_ROOT_HASH), SparseNodeType::Empty),
1488 SparseNode::Hash(hash) => (RlpNode::word_rlp(hash), SparseNodeType::Hash),
1489 SparseNode::Leaf { key, hash } => {
1490 let mut path = path;
1491 path.extend(key);
1492 if let Some(hash) = hash.filter(|_| !prefix_set_contains(&path)) {
1493 (RlpNode::word_rlp(&hash), SparseNodeType::Leaf)
1494 } else {
1495 let value = self.values.get(&path).unwrap();
1496 rlp_buf.clear();
1497 let rlp_node = LeafNodeRef { key, value }.rlp(rlp_buf);
1498 *hash = rlp_node.as_hash();
1499 (rlp_node, SparseNodeType::Leaf)
1500 }
1501 }
1502 SparseNode::Extension { key, hash, store_in_db_trie } => {
1503 let mut child_path = path;
1504 child_path.extend(key);
1505 if let Some((hash, store_in_db_trie)) =
1506 hash.zip(*store_in_db_trie).filter(|_| !prefix_set_contains(&path))
1507 {
1508 (
1509 RlpNode::word_rlp(&hash),
1510 SparseNodeType::Extension { store_in_db_trie: Some(store_in_db_trie) },
1511 )
1512 } else if buffers.rlp_node_stack.last().is_some_and(|e| e.path == child_path) {
1513 let RlpNodeStackItem {
1514 path: _,
1515 rlp_node: child,
1516 node_type: child_node_type,
1517 } = buffers.rlp_node_stack.pop().unwrap();
1518 rlp_buf.clear();
1519 let rlp_node = ExtensionNodeRef::new(key, &child).rlp(rlp_buf);
1520 *hash = rlp_node.as_hash();
1521
1522 let store_in_db_trie_value = child_node_type.store_in_db_trie();
1523
1524 trace!(
1525 target: "trie::sparse",
1526 ?path,
1527 ?child_path,
1528 ?child_node_type,
1529 "Extension node"
1530 );
1531
1532 *store_in_db_trie = store_in_db_trie_value;
1533
1534 (
1535 rlp_node,
1536 SparseNodeType::Extension {
1537 store_in_db_trie: store_in_db_trie_value,
1540 },
1541 )
1542 } else {
1543 buffers.path_stack.extend([
1545 RlpNodePathStackItem { level, path, is_in_prefix_set },
1546 RlpNodePathStackItem {
1547 level: level + 1,
1548 path: child_path,
1549 is_in_prefix_set: None,
1550 },
1551 ]);
1552 continue
1553 }
1554 }
1555 SparseNode::Branch { state_mask, hash, store_in_db_trie } => {
1556 if let Some((hash, store_in_db_trie)) =
1557 hash.zip(*store_in_db_trie).filter(|_| !prefix_set_contains(&path))
1558 {
1559 buffers.rlp_node_stack.push(RlpNodeStackItem {
1560 path,
1561 rlp_node: RlpNode::word_rlp(&hash),
1562 node_type: SparseNodeType::Branch {
1563 store_in_db_trie: Some(store_in_db_trie),
1564 },
1565 });
1566 continue
1567 }
1568 let retain_updates = self.updates.is_some() && prefix_set_contains(&path);
1569
1570 buffers.branch_child_buf.clear();
1571 for bit in CHILD_INDEX_RANGE.rev() {
1574 if state_mask.is_bit_set(bit) {
1575 let mut child = path;
1576 child.push_unchecked(bit);
1577 buffers.branch_child_buf.push(child);
1578 }
1579 }
1580
1581 buffers
1582 .branch_value_stack_buf
1583 .resize(buffers.branch_child_buf.len(), Default::default());
1584 let mut added_children = false;
1585
1586 let mut tree_mask = TrieMask::default();
1587 let mut hash_mask = TrieMask::default();
1588 let mut hashes = Vec::new();
1589 for (i, child_path) in buffers.branch_child_buf.iter().enumerate() {
1590 if buffers.rlp_node_stack.last().is_some_and(|e| &e.path == child_path) {
1591 let RlpNodeStackItem {
1592 path: _,
1593 rlp_node: child,
1594 node_type: child_node_type,
1595 } = buffers.rlp_node_stack.pop().unwrap();
1596
1597 if retain_updates {
1599 let last_child_nibble = child_path.last().unwrap();
1601
1602 let should_set_tree_mask_bit = if let Some(store_in_db_trie) =
1604 child_node_type.store_in_db_trie()
1605 {
1606 store_in_db_trie
1609 } else {
1610 child_node_type.is_hash() &&
1612 self.branch_node_tree_masks.get(&path).is_some_and(
1613 |mask| mask.is_bit_set(last_child_nibble),
1614 )
1615 };
1616 if should_set_tree_mask_bit {
1617 tree_mask.set_bit(last_child_nibble);
1618 }
1619
1620 let hash = child.as_hash().filter(|_| {
1624 child_node_type.is_branch() ||
1625 (child_node_type.is_hash() &&
1626 self.branch_node_hash_masks
1627 .get(&path)
1628 .is_some_and(|mask| {
1629 mask.is_bit_set(last_child_nibble)
1630 }))
1631 });
1632 if let Some(hash) = hash {
1633 hash_mask.set_bit(last_child_nibble);
1634 hashes.push(hash);
1635 }
1636 }
1637
1638 let original_idx = buffers.branch_child_buf.len() - i - 1;
1642 buffers.branch_value_stack_buf[original_idx] = child;
1643 added_children = true;
1644 } else {
1645 debug_assert!(!added_children);
1646 buffers.path_stack.push(RlpNodePathStackItem {
1647 level,
1648 path,
1649 is_in_prefix_set,
1650 });
1651 buffers.path_stack.extend(buffers.branch_child_buf.drain(..).map(
1652 |path| RlpNodePathStackItem {
1653 level: level + 1,
1654 path,
1655 is_in_prefix_set: None,
1656 },
1657 ));
1658 continue 'main
1659 }
1660 }
1661
1662 trace!(
1663 target: "trie::sparse",
1664 ?path,
1665 ?tree_mask,
1666 ?hash_mask,
1667 "Branch node masks"
1668 );
1669
1670 rlp_buf.clear();
1671 let branch_node_ref =
1672 BranchNodeRef::new(&buffers.branch_value_stack_buf, *state_mask);
1673 let rlp_node = branch_node_ref.rlp(rlp_buf);
1674 *hash = rlp_node.as_hash();
1675
1676 let store_in_db_trie_value = if let Some(updates) =
1679 self.updates.as_mut().filter(|_| retain_updates && !path.is_empty())
1680 {
1681 let store_in_db_trie = !tree_mask.is_empty() || !hash_mask.is_empty();
1682 if store_in_db_trie {
1683 hashes.reverse();
1686 let branch_node = BranchNodeCompact::new(
1687 *state_mask,
1688 tree_mask,
1689 hash_mask,
1690 hashes,
1691 hash.filter(|_| path.is_empty()),
1692 );
1693 updates.updated_nodes.insert(path, branch_node);
1694 } else if self
1695 .branch_node_tree_masks
1696 .get(&path)
1697 .is_some_and(|mask| !mask.is_empty()) ||
1698 self.branch_node_hash_masks
1699 .get(&path)
1700 .is_some_and(|mask| !mask.is_empty())
1701 {
1702 updates.updated_nodes.remove(&path);
1706 updates.removed_nodes.insert(path);
1707 } else if self
1708 .branch_node_tree_masks
1709 .get(&path)
1710 .is_none_or(|mask| mask.is_empty()) &&
1711 self.branch_node_hash_masks
1712 .get(&path)
1713 .is_none_or(|mask| mask.is_empty())
1714 {
1715 updates.updated_nodes.remove(&path);
1718 }
1719
1720 store_in_db_trie
1721 } else {
1722 false
1723 };
1724 *store_in_db_trie = Some(store_in_db_trie_value);
1725
1726 (
1727 rlp_node,
1728 SparseNodeType::Branch { store_in_db_trie: Some(store_in_db_trie_value) },
1729 )
1730 }
1731 };
1732
1733 trace!(
1734 target: "trie::sparse",
1735 ?_starting_path,
1736 ?level,
1737 ?path,
1738 ?node,
1739 ?node_type,
1740 ?is_in_prefix_set,
1741 "Added node to rlp node stack"
1742 );
1743
1744 buffers.rlp_node_stack.push(RlpNodeStackItem { path, rlp_node, node_type });
1745 }
1746
1747 debug_assert_eq!(buffers.rlp_node_stack.len(), 1);
1748 buffers.rlp_node_stack.pop().unwrap().rlp_node
1749 }
1750}
1751
1752#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1754pub enum SparseNodeType {
1755 Empty,
1757 Hash,
1759 Leaf,
1761 Extension {
1763 store_in_db_trie: Option<bool>,
1765 },
1766 Branch {
1768 store_in_db_trie: Option<bool>,
1770 },
1771}
1772
1773impl SparseNodeType {
1774 pub const fn is_hash(&self) -> bool {
1776 matches!(self, Self::Hash)
1777 }
1778
1779 pub const fn is_branch(&self) -> bool {
1781 matches!(self, Self::Branch { .. })
1782 }
1783
1784 pub const fn store_in_db_trie(&self) -> Option<bool> {
1786 match *self {
1787 Self::Extension { store_in_db_trie } | Self::Branch { store_in_db_trie } => {
1788 store_in_db_trie
1789 }
1790 _ => None,
1791 }
1792 }
1793}
1794
1795#[derive(Debug, Clone, PartialEq, Eq)]
1797pub enum SparseNode {
1798 Empty,
1800 Hash(B256),
1802 Leaf {
1804 key: Nibbles,
1806 hash: Option<B256>,
1809 },
1810 Extension {
1812 key: Nibbles,
1814 hash: Option<B256>,
1819 store_in_db_trie: Option<bool>,
1824 },
1825 Branch {
1827 state_mask: TrieMask,
1829 hash: Option<B256>,
1834 store_in_db_trie: Option<bool>,
1839 },
1840}
1841
1842impl SparseNode {
1843 pub fn from_node(node: TrieNode) -> Self {
1845 match node {
1846 TrieNode::EmptyRoot => Self::Empty,
1847 TrieNode::Leaf(leaf) => Self::new_leaf(leaf.key),
1848 TrieNode::Extension(ext) => Self::new_ext(ext.key),
1849 TrieNode::Branch(branch) => Self::new_branch(branch.state_mask),
1850 }
1851 }
1852
1853 pub const fn new_branch(state_mask: TrieMask) -> Self {
1855 Self::Branch { state_mask, hash: None, store_in_db_trie: None }
1856 }
1857
1858 pub const fn new_split_branch(bit_a: u8, bit_b: u8) -> Self {
1860 let state_mask = TrieMask::new(
1861 (1u16 << bit_a) | (1u16 << bit_b),
1863 );
1864 Self::Branch { state_mask, hash: None, store_in_db_trie: None }
1865 }
1866
1867 pub const fn new_ext(key: Nibbles) -> Self {
1869 Self::Extension { key, hash: None, store_in_db_trie: None }
1870 }
1871
1872 pub const fn new_leaf(key: Nibbles) -> Self {
1874 Self::Leaf { key, hash: None }
1875 }
1876
1877 pub const fn is_hash(&self) -> bool {
1879 matches!(self, Self::Hash(_))
1880 }
1881
1882 pub const fn hash(&self) -> Option<B256> {
1884 match self {
1885 Self::Empty => None,
1886 Self::Hash(hash) => Some(*hash),
1887 Self::Leaf { hash, .. } | Self::Extension { hash, .. } | Self::Branch { hash, .. } => {
1888 *hash
1889 }
1890 }
1891 }
1892
1893 #[cfg(any(test, feature = "test-utils"))]
1897 pub const fn set_hash(&mut self, new_hash: Option<B256>) {
1898 match self {
1899 Self::Empty | Self::Hash(_) => {
1900 }
1902 Self::Leaf { hash, .. } | Self::Extension { hash, .. } | Self::Branch { hash, .. } => {
1903 *hash = new_hash;
1904 }
1905 }
1906 }
1907}
1908
1909#[derive(Debug)]
1912struct RemovedSparseNode {
1913 path: Nibbles,
1915 node: SparseNode,
1917 unset_branch_nibble: Option<u8>,
1926}
1927
1928#[derive(Debug, Default)]
1932pub struct RlpNodeBuffers {
1933 path_stack: Vec<RlpNodePathStackItem>,
1935 rlp_node_stack: Vec<RlpNodeStackItem>,
1937 branch_child_buf: SmallVec<[Nibbles; 16]>,
1939 branch_value_stack_buf: SmallVec<[RlpNode; 16]>,
1941}
1942
1943impl RlpNodeBuffers {
1944 fn new_with_root_path() -> Self {
1946 Self {
1947 path_stack: vec![RlpNodePathStackItem {
1948 level: 0,
1949 path: Nibbles::default(),
1950 is_in_prefix_set: None,
1951 }],
1952 rlp_node_stack: Vec::new(),
1953 branch_child_buf: SmallVec::<[Nibbles; 16]>::new_const(),
1954 branch_value_stack_buf: SmallVec::<[RlpNode; 16]>::new_const(),
1955 }
1956 }
1957}
1958
1959#[derive(Clone, PartialEq, Eq, Debug)]
1961pub struct RlpNodePathStackItem {
1962 pub level: usize,
1964 pub path: Nibbles,
1966 pub is_in_prefix_set: Option<bool>,
1968}
1969
1970#[derive(Clone, PartialEq, Eq, Debug)]
1972pub struct RlpNodeStackItem {
1973 pub path: Nibbles,
1975 pub rlp_node: RlpNode,
1977 pub node_type: SparseNodeType,
1979}
1980
1981impl SparseTrieUpdates {
1982 pub fn wiped() -> Self {
1984 Self { wiped: true, ..Default::default() }
1985 }
1986
1987 pub fn clear(&mut self) {
1991 self.updated_nodes.clear();
1992 self.removed_nodes.clear();
1993 self.wiped = false;
1994 }
1995
1996 pub fn extend(&mut self, other: Self) {
1998 self.updated_nodes.extend(other.updated_nodes);
1999 self.removed_nodes.extend(other.removed_nodes);
2000 self.wiped |= other.wiped;
2001 }
2002}
2003
2004#[cfg(test)]
2005mod find_leaf_tests {
2006 use super::*;
2007 use crate::provider::DefaultTrieNodeProvider;
2008 use alloy_rlp::Encodable;
2009 use assert_matches::assert_matches;
2010 use reth_primitives_traits::Account;
2011 use reth_trie_common::LeafNode;
2012
2013 fn encode_value(nonce: u64) -> Vec<u8> {
2015 let account = Account { nonce, ..Default::default() };
2016 let trie_account = account.into_trie_account(EMPTY_ROOT_HASH);
2017 let mut buf = Vec::new();
2018 trie_account.encode(&mut buf);
2019 buf
2020 }
2021
2022 const VALUE_A: fn() -> Vec<u8> = || encode_value(1);
2023 const VALUE_B: fn() -> Vec<u8> = || encode_value(2);
2024
2025 #[test]
2026 fn find_leaf_existing_leaf() {
2027 let provider = DefaultTrieNodeProvider;
2029 let mut sparse = SerialSparseTrie::default();
2030 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
2031 let value = b"test_value".to_vec();
2032
2033 sparse.update_leaf(path, value.clone(), &provider).unwrap();
2034
2035 let result = sparse.find_leaf(&path, None);
2037 assert_matches!(result, Ok(LeafLookup::Exists));
2038
2039 let result = sparse.find_leaf(&path, Some(&value));
2041 assert_matches!(result, Ok(LeafLookup::Exists));
2042 }
2043
2044 #[test]
2045 fn find_leaf_value_mismatch() {
2046 let provider = DefaultTrieNodeProvider;
2048 let mut sparse = SerialSparseTrie::default();
2049 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
2050 let value = b"test_value".to_vec();
2051 let wrong_value = b"wrong_value".to_vec();
2052
2053 sparse.update_leaf(path, value, &provider).unwrap();
2054
2055 let result = sparse.find_leaf(&path, Some(&wrong_value));
2057 assert_matches!(
2058 result,
2059 Err(LeafLookupError::ValueMismatch { path: p, expected: Some(e), actual: _a }) if p == path && e == wrong_value
2060 );
2061 }
2062
2063 #[test]
2064 fn find_leaf_not_found_empty_trie() {
2065 let sparse = SerialSparseTrie::default();
2067 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
2068
2069 let result = sparse.find_leaf(&path, None);
2071 assert_matches!(result, Ok(LeafLookup::NonExistent));
2072 }
2073
2074 #[test]
2075 fn find_leaf_empty_trie() {
2076 let sparse = SerialSparseTrie::default();
2077 let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2078
2079 let result = sparse.find_leaf(&path, None);
2080 assert_matches!(result, Ok(LeafLookup::NonExistent));
2081 }
2082
2083 #[test]
2084 fn find_leaf_exists_no_value_check() {
2085 let provider = DefaultTrieNodeProvider;
2086 let mut sparse = SerialSparseTrie::default();
2087 let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2088 sparse.update_leaf(path, VALUE_A(), &provider).unwrap();
2089
2090 let result = sparse.find_leaf(&path, None);
2091 assert_matches!(result, Ok(LeafLookup::Exists));
2092 }
2093
2094 #[test]
2095 fn find_leaf_exists_with_value_check_ok() {
2096 let provider = DefaultTrieNodeProvider;
2097 let mut sparse = SerialSparseTrie::default();
2098 let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2099 let value = VALUE_A();
2100 sparse.update_leaf(path, value.clone(), &provider).unwrap();
2101
2102 let result = sparse.find_leaf(&path, Some(&value));
2103 assert_matches!(result, Ok(LeafLookup::Exists));
2104 }
2105
2106 #[test]
2107 fn find_leaf_exclusion_branch_divergence() {
2108 let provider = DefaultTrieNodeProvider;
2109 let mut sparse = SerialSparseTrie::default();
2110 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();
2115 sparse.update_leaf(path2, VALUE_B(), &provider).unwrap();
2116
2117 let result = sparse.find_leaf(&search_path, None);
2118 assert_matches!(result, Ok(LeafLookup::NonExistent));
2119 }
2120
2121 #[test]
2122 fn find_leaf_exclusion_extension_divergence() {
2123 let provider = DefaultTrieNodeProvider;
2124 let mut sparse = SerialSparseTrie::default();
2125 let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]);
2127 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x7, 0x8]);
2129
2130 sparse.update_leaf(path1, VALUE_A(), &provider).unwrap();
2131
2132 let result = sparse.find_leaf(&search_path, None);
2133 assert_matches!(result, Ok(LeafLookup::NonExistent));
2134 }
2135
2136 #[test]
2137 fn find_leaf_exclusion_leaf_divergence() {
2138 let provider = DefaultTrieNodeProvider;
2139 let mut sparse = SerialSparseTrie::default();
2140 let existing_leaf_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2141 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]);
2142
2143 sparse.update_leaf(existing_leaf_path, VALUE_A(), &provider).unwrap();
2144
2145 let result = sparse.find_leaf(&search_path, None);
2146 assert_matches!(result, Ok(LeafLookup::NonExistent));
2147 }
2148
2149 #[test]
2150 fn find_leaf_exclusion_path_ends_at_branch() {
2151 let provider = DefaultTrieNodeProvider;
2152 let mut sparse = SerialSparseTrie::default();
2153 let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); let path2 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x5, 0x6]);
2155 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2]); sparse.update_leaf(path1, VALUE_A(), &provider).unwrap();
2158 sparse.update_leaf(path2, VALUE_B(), &provider).unwrap();
2159
2160 let result = sparse.find_leaf(&search_path, None);
2161 assert_matches!(result, Ok(LeafLookup::NonExistent));
2162 }
2163
2164 #[test]
2165 fn find_leaf_error_trie_node_at_leaf_path() {
2166 let blinded_hash = B256::repeat_byte(0xBB);
2168 let leaf_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2169
2170 let mut nodes = alloy_primitives::map::HashMap::default();
2171 nodes.insert(
2173 Nibbles::default(),
2174 SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x1, 0x2])),
2175 ); nodes.insert(
2177 Nibbles::from_nibbles_unchecked([0x1, 0x2]),
2178 SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x3])),
2179 ); nodes.insert(
2181 Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3]),
2182 SparseNode::new_branch(TrieMask::new(0b10000)),
2183 ); nodes.insert(leaf_path, SparseNode::Hash(blinded_hash)); let sparse = SerialSparseTrie {
2187 nodes,
2188 branch_node_tree_masks: Default::default(),
2189 branch_node_hash_masks: Default::default(),
2190 values: Default::default(),
2192 prefix_set: Default::default(),
2193 updates: None,
2194 rlp_buf: Vec::new(),
2195 };
2196
2197 let result = sparse.find_leaf(&leaf_path, None);
2198
2199 assert_matches!(result, Err(LeafLookupError::BlindedNode { path, hash })
2201 if path == leaf_path && hash == blinded_hash
2202 );
2203 }
2204
2205 #[test]
2206 fn find_leaf_error_trie_node() {
2207 let blinded_hash = B256::repeat_byte(0xAA);
2208 let path_to_blind = Nibbles::from_nibbles_unchecked([0x1]);
2209 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2210
2211 let mut nodes = HashMap::default();
2212
2213 let state_mask = TrieMask::new(0b100010);
2216 nodes.insert(Nibbles::default(), SparseNode::new_branch(state_mask));
2217
2218 nodes.insert(path_to_blind, SparseNode::Hash(blinded_hash));
2219 let path_revealed = Nibbles::from_nibbles_unchecked([0x5]);
2220 let path_revealed_leaf = Nibbles::from_nibbles_unchecked([0x5, 0x6, 0x7, 0x8]);
2221 nodes.insert(
2222 path_revealed,
2223 SparseNode::new_leaf(Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8])),
2224 );
2225
2226 let mut values = HashMap::default();
2227 values.insert(path_revealed_leaf, VALUE_A());
2228
2229 let sparse = SerialSparseTrie {
2230 nodes,
2231 branch_node_tree_masks: Default::default(),
2232 branch_node_hash_masks: Default::default(),
2233 values,
2234 prefix_set: Default::default(),
2235 updates: None,
2236 rlp_buf: Vec::new(),
2237 };
2238
2239 let result = sparse.find_leaf(&search_path, None);
2240
2241 assert_matches!(result, Err(LeafLookupError::BlindedNode { path, hash })
2243 if path == path_to_blind && hash == blinded_hash
2244 );
2245 }
2246
2247 #[test]
2248 fn find_leaf_error_trie_node_via_reveal() {
2249 let blinded_hash = B256::repeat_byte(0xAA);
2250 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]);
2254 let revealed_leaf_suffix = Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8]);
2255 let revealed_leaf_full_path = Nibbles::from_nibbles_unchecked([0x5, 0x6, 0x7, 0x8]);
2256 let revealed_value = VALUE_A();
2257
2258 let rlp_node_child1 = RlpNode::word_rlp(&blinded_hash); let leaf_node_child5 = LeafNode::new(revealed_leaf_suffix, revealed_value.clone());
2262 let leaf_node_child5_rlp_buf = alloy_rlp::encode(&leaf_node_child5);
2263 let hash_of_child5 = keccak256(&leaf_node_child5_rlp_buf);
2264 let rlp_node_child5 = RlpNode::word_rlp(&hash_of_child5);
2265
2266 let root_branch_node = reth_trie_common::BranchNode::new(
2269 vec![rlp_node_child1, rlp_node_child5], TrieMask::new(0b100010), );
2272 let root_trie_node = TrieNode::Branch(root_branch_node);
2273
2274 let mut sparse = SerialSparseTrie::from_root(root_trie_node, TrieMasks::none(), false)
2277 .expect("Failed to create trie from root");
2278
2279 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 );
2282 assert!(sparse.nodes.get(&revealed_leaf_prefix).unwrap().is_hash()); assert!(sparse.values.is_empty());
2284
2285 sparse
2287 .reveal_node(revealed_leaf_prefix, TrieNode::Leaf(leaf_node_child5), TrieMasks::none())
2288 .expect("Failed to reveal leaf node");
2289
2290 assert_matches!(sparse.nodes.get(&Nibbles::default()), Some(SparseNode::Branch { state_mask, .. }) if *state_mask == TrieMask::new(0b100010));
2292 assert_matches!(sparse.nodes.get(&path_to_blind), Some(SparseNode::Hash(h)) if *h == blinded_hash );
2293 assert_matches!(sparse.nodes.get(&revealed_leaf_prefix), Some(SparseNode::Leaf { key, .. }) if *key == revealed_leaf_suffix);
2294 assert_eq!(sparse.values.get(&revealed_leaf_full_path), Some(&revealed_value));
2295
2296 let result = sparse.find_leaf(&search_path, None);
2297
2298 assert_matches!(result, Err(LeafLookupError::BlindedNode { path, hash })
2301 if path == path_to_blind && hash == blinded_hash
2302 );
2303 }
2304}
2305
2306#[cfg(test)]
2307mod tests {
2308 use super::*;
2309 use crate::provider::DefaultTrieNodeProvider;
2310 use alloy_primitives::{map::B256Set, U256};
2311 use alloy_rlp::Encodable;
2312 use assert_matches::assert_matches;
2313 use itertools::Itertools;
2314 use prop::sample::SizeRange;
2315 use proptest::prelude::*;
2316 use proptest_arbitrary_interop::arb;
2317 use reth_primitives_traits::Account;
2318 use reth_provider::{test_utils::create_test_provider_factory, TrieWriter};
2319 use reth_trie::{
2320 hashed_cursor::{noop::NoopHashedAccountCursor, HashedPostStateAccountCursor},
2321 node_iter::{TrieElement, TrieNodeIter},
2322 trie_cursor::{noop::NoopAccountTrieCursor, TrieCursor, TrieCursorFactory},
2323 walker::TrieWalker,
2324 BranchNode, ExtensionNode, HashedPostState, LeafNode,
2325 };
2326 use reth_trie_common::{
2327 proof::{ProofNodes, ProofRetainer},
2328 updates::TrieUpdates,
2329 HashBuilder,
2330 };
2331 use reth_trie_db::DatabaseTrieCursorFactory;
2332 use std::collections::{BTreeMap, BTreeSet};
2333
2334 fn pad_nibbles_left(nibbles: Nibbles) -> Nibbles {
2336 let mut base =
2337 Nibbles::from_nibbles_unchecked(vec![0; B256::len_bytes() * 2 - nibbles.len()]);
2338 base.extend(&nibbles);
2339 base
2340 }
2341
2342 fn pad_nibbles_right(mut nibbles: Nibbles) -> Nibbles {
2344 nibbles.extend(&Nibbles::from_nibbles_unchecked(vec![
2345 0;
2346 B256::len_bytes() * 2 - nibbles.len()
2347 ]));
2348 nibbles
2349 }
2350
2351 fn run_hash_builder(
2356 state: impl IntoIterator<Item = (Nibbles, Account)> + Clone,
2357 trie_cursor: impl TrieCursor,
2358 destroyed_accounts: B256Set,
2359 proof_targets: impl IntoIterator<Item = Nibbles>,
2360 ) -> (B256, TrieUpdates, ProofNodes, HashMap<Nibbles, TrieMask>, HashMap<Nibbles, TrieMask>)
2361 {
2362 let mut account_rlp = Vec::new();
2363
2364 let mut hash_builder = HashBuilder::default()
2365 .with_updates(true)
2366 .with_proof_retainer(ProofRetainer::from_iter(proof_targets));
2367
2368 let mut prefix_set = PrefixSetMut::default();
2369 prefix_set.extend_keys(state.clone().into_iter().map(|(nibbles, _)| nibbles));
2370 prefix_set.extend_keys(destroyed_accounts.iter().map(Nibbles::unpack));
2371 let walker = TrieWalker::<_>::state_trie(trie_cursor, prefix_set.freeze())
2372 .with_deletions_retained(true);
2373 let hashed_post_state = HashedPostState::default()
2374 .with_accounts(state.into_iter().map(|(nibbles, account)| {
2375 (nibbles.pack().into_inner().unwrap().into(), Some(account))
2376 }))
2377 .into_sorted();
2378 let mut node_iter = TrieNodeIter::state_trie(
2379 walker,
2380 HashedPostStateAccountCursor::new(
2381 NoopHashedAccountCursor::default(),
2382 hashed_post_state.accounts(),
2383 ),
2384 );
2385
2386 while let Some(node) = node_iter.try_next().unwrap() {
2387 match node {
2388 TrieElement::Branch(branch) => {
2389 hash_builder.add_branch(branch.key, branch.value, branch.children_are_in_trie);
2390 }
2391 TrieElement::Leaf(key, account) => {
2392 let account = account.into_trie_account(EMPTY_ROOT_HASH);
2393 account.encode(&mut account_rlp);
2394
2395 hash_builder.add_leaf(Nibbles::unpack(key), &account_rlp);
2396 account_rlp.clear();
2397 }
2398 }
2399 }
2400 let root = hash_builder.root();
2401 let proof_nodes = hash_builder.take_proof_nodes();
2402 let branch_node_hash_masks = hash_builder
2403 .updated_branch_nodes
2404 .clone()
2405 .unwrap_or_default()
2406 .iter()
2407 .map(|(path, node)| (*path, node.hash_mask))
2408 .collect();
2409 let branch_node_tree_masks = hash_builder
2410 .updated_branch_nodes
2411 .clone()
2412 .unwrap_or_default()
2413 .iter()
2414 .map(|(path, node)| (*path, node.tree_mask))
2415 .collect();
2416
2417 let mut trie_updates = TrieUpdates::default();
2418 let removed_keys = node_iter.walker.take_removed_keys();
2419 trie_updates.finalize(hash_builder, removed_keys, destroyed_accounts);
2420
2421 (root, trie_updates, proof_nodes, branch_node_hash_masks, branch_node_tree_masks)
2422 }
2423
2424 fn assert_eq_sparse_trie_proof_nodes(sparse_trie: &SerialSparseTrie, proof_nodes: ProofNodes) {
2426 let proof_nodes = proof_nodes
2427 .into_nodes_sorted()
2428 .into_iter()
2429 .map(|(path, node)| (path, TrieNode::decode(&mut node.as_ref()).unwrap()));
2430
2431 let sparse_nodes = sparse_trie.nodes.iter().sorted_by_key(|(path, _)| *path);
2432
2433 for ((proof_node_path, proof_node), (sparse_node_path, sparse_node)) in
2434 proof_nodes.zip(sparse_nodes)
2435 {
2436 assert_eq!(&proof_node_path, sparse_node_path);
2437
2438 let equals = match (&proof_node, &sparse_node) {
2439 (TrieNode::EmptyRoot, SparseNode::Empty) => true,
2441 (
2443 TrieNode::Branch(BranchNode { state_mask: proof_state_mask, .. }),
2444 SparseNode::Branch { state_mask: sparse_state_mask, .. },
2445 ) => proof_state_mask == sparse_state_mask,
2446 (
2448 TrieNode::Extension(ExtensionNode { key: proof_key, .. }),
2449 SparseNode::Extension { key: sparse_key, .. },
2450 ) |
2451 (
2453 TrieNode::Leaf(LeafNode { key: proof_key, .. }),
2454 SparseNode::Leaf { key: sparse_key, .. },
2455 ) => proof_key == sparse_key,
2456 (_, SparseNode::Empty | SparseNode::Hash(_)) => continue,
2458 _ => false,
2459 };
2460 assert!(
2461 equals,
2462 "path: {proof_node_path:?}\nproof node: {proof_node:?}\nsparse node: {sparse_node:?}"
2463 );
2464 }
2465 }
2466
2467 #[test]
2468 fn sparse_trie_is_blind() {
2469 assert!(SparseTrie::<SerialSparseTrie>::blind().is_blind());
2470 assert!(!SparseTrie::<SerialSparseTrie>::revealed_empty().is_blind());
2471 }
2472
2473 #[test]
2474 fn sparse_trie_empty_update_one() {
2475 let key = Nibbles::unpack(B256::with_last_byte(42));
2476 let value = || Account::default();
2477 let value_encoded = || {
2478 let mut account_rlp = Vec::new();
2479 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2480 account_rlp
2481 };
2482
2483 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2484 run_hash_builder(
2485 [(key, value())],
2486 NoopAccountTrieCursor::default(),
2487 Default::default(),
2488 [key],
2489 );
2490
2491 let provider = DefaultTrieNodeProvider;
2492 let mut sparse = SerialSparseTrie::default().with_updates(true);
2493 sparse.update_leaf(key, value_encoded(), &provider).unwrap();
2494 let sparse_root = sparse.root();
2495 let sparse_updates = sparse.take_updates();
2496
2497 assert_eq!(sparse_root, hash_builder_root);
2498 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2499 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2500 }
2501
2502 #[test]
2503 fn sparse_trie_empty_update_multiple_lower_nibbles() {
2504 reth_tracing::init_test_tracing();
2505
2506 let paths = (0..=16).map(|b| Nibbles::unpack(B256::with_last_byte(b))).collect::<Vec<_>>();
2507 let value = || Account::default();
2508 let value_encoded = || {
2509 let mut account_rlp = Vec::new();
2510 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2511 account_rlp
2512 };
2513
2514 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2515 run_hash_builder(
2516 paths.iter().copied().zip(std::iter::repeat_with(value)),
2517 NoopAccountTrieCursor::default(),
2518 Default::default(),
2519 paths.clone(),
2520 );
2521
2522 let provider = DefaultTrieNodeProvider;
2523 let mut sparse = SerialSparseTrie::default().with_updates(true);
2524 for path in &paths {
2525 sparse.update_leaf(*path, value_encoded(), &provider).unwrap();
2526 }
2527 let sparse_root = sparse.root();
2528 let sparse_updates = sparse.take_updates();
2529
2530 assert_eq!(sparse_root, hash_builder_root);
2531 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2532 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2533 }
2534
2535 #[test]
2536 fn sparse_trie_empty_update_multiple_upper_nibbles() {
2537 let paths = (239..=255).map(|b| Nibbles::unpack(B256::repeat_byte(b))).collect::<Vec<_>>();
2538 let value = || Account::default();
2539 let value_encoded = || {
2540 let mut account_rlp = Vec::new();
2541 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2542 account_rlp
2543 };
2544
2545 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2546 run_hash_builder(
2547 paths.iter().copied().zip(std::iter::repeat_with(value)),
2548 NoopAccountTrieCursor::default(),
2549 Default::default(),
2550 paths.clone(),
2551 );
2552
2553 let provider = DefaultTrieNodeProvider;
2554 let mut sparse = SerialSparseTrie::default().with_updates(true);
2555 for path in &paths {
2556 sparse.update_leaf(*path, value_encoded(), &provider).unwrap();
2557 }
2558 let sparse_root = sparse.root();
2559 let sparse_updates = sparse.take_updates();
2560
2561 assert_eq!(sparse_root, hash_builder_root);
2562 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2563 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2564 }
2565
2566 #[test]
2567 fn sparse_trie_empty_update_multiple() {
2568 let paths = (0..=255)
2569 .map(|b| {
2570 Nibbles::unpack(if b % 2 == 0 {
2571 B256::repeat_byte(b)
2572 } else {
2573 B256::with_last_byte(b)
2574 })
2575 })
2576 .collect::<Vec<_>>();
2577 let value = || Account::default();
2578 let value_encoded = || {
2579 let mut account_rlp = Vec::new();
2580 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2581 account_rlp
2582 };
2583
2584 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2585 run_hash_builder(
2586 paths.iter().sorted_unstable().copied().zip(std::iter::repeat_with(value)),
2587 NoopAccountTrieCursor::default(),
2588 Default::default(),
2589 paths.clone(),
2590 );
2591
2592 let provider = DefaultTrieNodeProvider;
2593 let mut sparse = SerialSparseTrie::default().with_updates(true);
2594 for path in &paths {
2595 sparse.update_leaf(*path, value_encoded(), &provider).unwrap();
2596 }
2597 let sparse_root = sparse.root();
2598 let sparse_updates = sparse.take_updates();
2599
2600 assert_eq!(sparse_root, hash_builder_root);
2601 pretty_assertions::assert_eq!(
2602 BTreeMap::from_iter(sparse_updates.updated_nodes),
2603 BTreeMap::from_iter(hash_builder_updates.account_nodes)
2604 );
2605 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2606 }
2607
2608 #[test]
2609 fn sparse_trie_empty_update_repeated() {
2610 let paths = (0..=255).map(|b| Nibbles::unpack(B256::repeat_byte(b))).collect::<Vec<_>>();
2611 let old_value = Account { nonce: 1, ..Default::default() };
2612 let old_value_encoded = {
2613 let mut account_rlp = Vec::new();
2614 old_value.into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2615 account_rlp
2616 };
2617 let new_value = Account { nonce: 2, ..Default::default() };
2618 let new_value_encoded = {
2619 let mut account_rlp = Vec::new();
2620 new_value.into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2621 account_rlp
2622 };
2623
2624 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2625 run_hash_builder(
2626 paths.iter().copied().zip(std::iter::repeat_with(|| old_value)),
2627 NoopAccountTrieCursor::default(),
2628 Default::default(),
2629 paths.clone(),
2630 );
2631
2632 let provider = DefaultTrieNodeProvider;
2633 let mut sparse = SerialSparseTrie::default().with_updates(true);
2634 for path in &paths {
2635 sparse.update_leaf(*path, old_value_encoded.clone(), &provider).unwrap();
2636 }
2637 let sparse_root = sparse.root();
2638 let sparse_updates = sparse.updates_ref();
2639
2640 assert_eq!(sparse_root, hash_builder_root);
2641 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2642 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2643
2644 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2645 run_hash_builder(
2646 paths.iter().copied().zip(std::iter::repeat_with(|| new_value)),
2647 NoopAccountTrieCursor::default(),
2648 Default::default(),
2649 paths.clone(),
2650 );
2651
2652 for path in &paths {
2653 sparse.update_leaf(*path, new_value_encoded.clone(), &provider).unwrap();
2654 }
2655 let sparse_root = sparse.root();
2656 let sparse_updates = sparse.take_updates();
2657
2658 assert_eq!(sparse_root, hash_builder_root);
2659 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2660 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2661 }
2662
2663 #[test]
2664 fn sparse_trie_remove_leaf() {
2665 reth_tracing::init_test_tracing();
2666
2667 let provider = DefaultTrieNodeProvider;
2668 let mut sparse = SerialSparseTrie::default();
2669
2670 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
2671
2672 sparse
2673 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
2674 .unwrap();
2675 sparse
2676 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
2677 .unwrap();
2678 sparse
2679 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
2680 .unwrap();
2681 sparse
2682 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
2683 .unwrap();
2684 sparse
2685 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
2686 .unwrap();
2687 sparse
2688 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
2689 .unwrap();
2690
2691 pretty_assertions::assert_eq!(
2704 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2705 BTreeMap::from_iter([
2706 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2707 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1101.into())),
2708 (
2709 Nibbles::from_nibbles([0x5, 0x0]),
2710 SparseNode::new_ext(Nibbles::from_nibbles([0x2, 0x3]))
2711 ),
2712 (
2713 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3]),
2714 SparseNode::new_branch(0b1010.into())
2715 ),
2716 (
2717 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]),
2718 SparseNode::new_leaf(Nibbles::default())
2719 ),
2720 (
2721 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]),
2722 SparseNode::new_leaf(Nibbles::default())
2723 ),
2724 (
2725 Nibbles::from_nibbles([0x5, 0x2]),
2726 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x1, 0x3]))
2727 ),
2728 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
2729 (
2730 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
2731 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
2732 ),
2733 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2734 (
2735 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2736 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2737 ),
2738 (
2739 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2740 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2741 )
2742 ])
2743 );
2744
2745 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), &provider).unwrap();
2746
2747 pretty_assertions::assert_eq!(
2759 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2760 BTreeMap::from_iter([
2761 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2762 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2763 (
2764 Nibbles::from_nibbles([0x5, 0x0]),
2765 SparseNode::new_ext(Nibbles::from_nibbles([0x2, 0x3]))
2766 ),
2767 (
2768 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3]),
2769 SparseNode::new_branch(0b1010.into())
2770 ),
2771 (
2772 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]),
2773 SparseNode::new_leaf(Nibbles::default())
2774 ),
2775 (
2776 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]),
2777 SparseNode::new_leaf(Nibbles::default())
2778 ),
2779 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
2780 (
2781 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
2782 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
2783 ),
2784 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2785 (
2786 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2787 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2788 ),
2789 (
2790 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2791 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2792 )
2793 ])
2794 );
2795
2796 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), &provider).unwrap();
2797
2798 pretty_assertions::assert_eq!(
2807 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2808 BTreeMap::from_iter([
2809 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2810 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2811 (
2812 Nibbles::from_nibbles([0x5, 0x0]),
2813 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
2814 ),
2815 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
2816 (
2817 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
2818 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
2819 ),
2820 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2821 (
2822 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2823 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2824 ),
2825 (
2826 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2827 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2828 )
2829 ])
2830 );
2831
2832 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), &provider).unwrap();
2833
2834 pretty_assertions::assert_eq!(
2841 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2842 BTreeMap::from_iter([
2843 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2844 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2845 (
2846 Nibbles::from_nibbles([0x5, 0x0]),
2847 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
2848 ),
2849 (
2850 Nibbles::from_nibbles([0x5, 0x3]),
2851 SparseNode::new_ext(Nibbles::from_nibbles([0x3]))
2852 ),
2853 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2854 (
2855 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2856 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2857 ),
2858 (
2859 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2860 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2861 )
2862 ])
2863 );
2864
2865 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), &provider).unwrap();
2866
2867 pretty_assertions::assert_eq!(
2872 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2873 BTreeMap::from_iter([
2874 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2875 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2876 (
2877 Nibbles::from_nibbles([0x5, 0x0]),
2878 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
2879 ),
2880 (
2881 Nibbles::from_nibbles([0x5, 0x3]),
2882 SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x0, 0x2]))
2883 ),
2884 ])
2885 );
2886
2887 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), &provider).unwrap();
2888
2889 pretty_assertions::assert_eq!(
2891 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2892 BTreeMap::from_iter([(
2893 Nibbles::default(),
2894 SparseNode::new_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]))
2895 ),])
2896 );
2897
2898 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), &provider).unwrap();
2899
2900 pretty_assertions::assert_eq!(
2902 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2903 BTreeMap::from_iter([(Nibbles::default(), SparseNode::Empty)])
2904 );
2905 }
2906
2907 #[test]
2908 fn sparse_trie_remove_leaf_blinded() {
2909 let leaf = LeafNode::new(
2910 Nibbles::default(),
2911 alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(),
2912 );
2913 let branch = TrieNode::Branch(BranchNode::new(
2914 vec![
2915 RlpNode::word_rlp(&B256::repeat_byte(1)),
2916 RlpNode::from_raw_rlp(&alloy_rlp::encode(leaf.clone())).unwrap(),
2917 ],
2918 TrieMask::new(0b11),
2919 ));
2920
2921 let provider = DefaultTrieNodeProvider;
2922 let mut sparse = SerialSparseTrie::from_root(
2923 branch.clone(),
2924 TrieMasks { hash_mask: Some(TrieMask::new(0b01)), tree_mask: None },
2925 false,
2926 )
2927 .unwrap();
2928
2929 sparse
2935 .reveal_node(
2936 Nibbles::default(),
2937 branch,
2938 TrieMasks { hash_mask: None, tree_mask: Some(TrieMask::new(0b01)) },
2939 )
2940 .unwrap();
2941 sparse
2942 .reveal_node(Nibbles::from_nibbles([0x1]), TrieNode::Leaf(leaf), TrieMasks::none())
2943 .unwrap();
2944
2945 assert_matches!(
2947 sparse.remove_leaf(&Nibbles::from_nibbles([0x0]), &provider).map_err(|e| e.into_kind()),
2948 Err(SparseTrieErrorKind::BlindedNode { path, hash }) if path == Nibbles::from_nibbles([0x0]) && hash == B256::repeat_byte(1)
2949 );
2950 }
2951
2952 #[test]
2953 fn sparse_trie_remove_leaf_non_existent() {
2954 let leaf = LeafNode::new(
2955 Nibbles::default(),
2956 alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(),
2957 );
2958 let branch = TrieNode::Branch(BranchNode::new(
2959 vec![
2960 RlpNode::word_rlp(&B256::repeat_byte(1)),
2961 RlpNode::from_raw_rlp(&alloy_rlp::encode(leaf.clone())).unwrap(),
2962 ],
2963 TrieMask::new(0b11),
2964 ));
2965
2966 let provider = DefaultTrieNodeProvider;
2967 let mut sparse = SerialSparseTrie::from_root(
2968 branch.clone(),
2969 TrieMasks { hash_mask: Some(TrieMask::new(0b01)), tree_mask: None },
2970 false,
2971 )
2972 .unwrap();
2973
2974 sparse
2980 .reveal_node(
2981 Nibbles::default(),
2982 branch,
2983 TrieMasks { hash_mask: None, tree_mask: Some(TrieMask::new(0b01)) },
2984 )
2985 .unwrap();
2986 sparse
2987 .reveal_node(Nibbles::from_nibbles([0x1]), TrieNode::Leaf(leaf), TrieMasks::none())
2988 .unwrap();
2989
2990 let sparse_old = sparse.clone();
2992 assert_matches!(sparse.remove_leaf(&Nibbles::from_nibbles([0x2]), &provider), Ok(()));
2993 assert_eq!(sparse, sparse_old);
2994 }
2995
2996 #[test]
2997 fn sparse_trie_fuzz() {
2998 const KEY_NIBBLES_LEN: usize = 3;
3002
3003 fn test(updates: Vec<(BTreeMap<Nibbles, Account>, BTreeSet<Nibbles>)>) {
3004 {
3005 let mut state = BTreeMap::default();
3006 let default_provider = DefaultTrieNodeProvider;
3007 let provider_factory = create_test_provider_factory();
3008 let mut sparse = SerialSparseTrie::default().with_updates(true);
3009
3010 for (update, keys_to_delete) in updates {
3011 for (key, account) in update.clone() {
3013 let account = account.into_trie_account(EMPTY_ROOT_HASH);
3014 let mut account_rlp = Vec::new();
3015 account.encode(&mut account_rlp);
3016 sparse.update_leaf(key, account_rlp, &default_provider).unwrap();
3017 }
3018 let mut updated_sparse = sparse.clone();
3022 let sparse_root = updated_sparse.root();
3023 let sparse_updates = updated_sparse.take_updates();
3024
3025 state.extend(update);
3027 let provider = provider_factory.provider().unwrap();
3028 let trie_cursor = DatabaseTrieCursorFactory::new(provider.tx_ref());
3029 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
3030 run_hash_builder(
3031 state.clone(),
3032 trie_cursor.account_trie_cursor().unwrap(),
3033 Default::default(),
3034 state.keys().copied(),
3035 );
3036
3037 let provider_rw = provider_factory.provider_rw().unwrap();
3039 provider_rw.write_trie_updates(&hash_builder_updates).unwrap();
3040 provider_rw.commit().unwrap();
3041
3042 assert_eq!(sparse_root, hash_builder_root);
3044 pretty_assertions::assert_eq!(
3046 BTreeMap::from_iter(sparse_updates.updated_nodes),
3047 BTreeMap::from_iter(hash_builder_updates.account_nodes)
3048 );
3049 assert_eq_sparse_trie_proof_nodes(&updated_sparse, hash_builder_proof_nodes);
3051
3052 for key in &keys_to_delete {
3055 state.remove(key).unwrap();
3056 sparse.remove_leaf(key, &default_provider).unwrap();
3057 }
3058
3059 let mut updated_sparse = sparse.clone();
3063 let sparse_root = updated_sparse.root();
3064 let sparse_updates = updated_sparse.take_updates();
3065
3066 let provider = provider_factory.provider().unwrap();
3067 let trie_cursor = DatabaseTrieCursorFactory::new(provider.tx_ref());
3068 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
3069 run_hash_builder(
3070 state.clone(),
3071 trie_cursor.account_trie_cursor().unwrap(),
3072 keys_to_delete
3073 .iter()
3074 .map(|nibbles| B256::from_slice(&nibbles.pack()))
3075 .collect(),
3076 state.keys().copied(),
3077 );
3078
3079 let provider_rw = provider_factory.provider_rw().unwrap();
3081 provider_rw.write_trie_updates(&hash_builder_updates).unwrap();
3082 provider_rw.commit().unwrap();
3083
3084 assert_eq!(sparse_root, hash_builder_root);
3086 pretty_assertions::assert_eq!(
3088 BTreeMap::from_iter(sparse_updates.updated_nodes),
3089 BTreeMap::from_iter(hash_builder_updates.account_nodes)
3090 );
3091 assert_eq_sparse_trie_proof_nodes(&updated_sparse, hash_builder_proof_nodes);
3093 }
3094 }
3095 }
3096
3097 fn transform_updates(
3098 updates: Vec<BTreeMap<Nibbles, Account>>,
3099 mut rng: impl rand::Rng,
3100 ) -> Vec<(BTreeMap<Nibbles, Account>, BTreeSet<Nibbles>)> {
3101 let mut keys = BTreeSet::new();
3102 updates
3103 .into_iter()
3104 .map(|update| {
3105 keys.extend(update.keys().copied());
3106
3107 let keys_to_delete_len = update.len() / 2;
3108 let keys_to_delete = (0..keys_to_delete_len)
3109 .map(|_| {
3110 let key =
3111 *rand::seq::IteratorRandom::choose(keys.iter(), &mut rng).unwrap();
3112 keys.take(&key).unwrap()
3113 })
3114 .collect();
3115
3116 (update, keys_to_delete)
3117 })
3118 .collect::<Vec<_>>()
3119 }
3120
3121 proptest!(ProptestConfig::with_cases(10), |(
3122 updates in proptest::collection::vec(
3123 proptest::collection::btree_map(
3124 any_with::<Nibbles>(SizeRange::new(KEY_NIBBLES_LEN..=KEY_NIBBLES_LEN)).prop_map(pad_nibbles_right),
3125 arb::<Account>(),
3126 1..50,
3127 ),
3128 1..50,
3129 ).prop_perturb(transform_updates)
3130 )| {
3131 test(updates)
3132 });
3133 }
3134
3135 #[test]
3147 fn sparse_trie_reveal_node_1() {
3148 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00]));
3149 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01]));
3150 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x02]));
3151 let value = || Account::default();
3152 let value_encoded = || {
3153 let mut account_rlp = Vec::new();
3154 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
3155 account_rlp
3156 };
3157
3158 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3160 run_hash_builder(
3161 [(key1(), value()), (key3(), value())],
3162 NoopAccountTrieCursor::default(),
3163 Default::default(),
3164 [Nibbles::default()],
3165 );
3166
3167 let provider = DefaultTrieNodeProvider;
3168 let mut sparse = SerialSparseTrie::from_root(
3169 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
3170 TrieMasks {
3171 hash_mask: branch_node_hash_masks.get(&Nibbles::default()).copied(),
3172 tree_mask: branch_node_tree_masks.get(&Nibbles::default()).copied(),
3173 },
3174 false,
3175 )
3176 .unwrap();
3177
3178 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3180 run_hash_builder(
3181 [(key1(), value()), (key3(), value())],
3182 NoopAccountTrieCursor::default(),
3183 Default::default(),
3184 [key1()],
3185 );
3186 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3187 let hash_mask = branch_node_hash_masks.get(&path).copied();
3188 let tree_mask = branch_node_tree_masks.get(&path).copied();
3189 sparse
3190 .reveal_node(
3191 path,
3192 TrieNode::decode(&mut &node[..]).unwrap(),
3193 TrieMasks { hash_mask, tree_mask },
3194 )
3195 .unwrap();
3196 }
3197
3198 assert_eq!(
3200 sparse.nodes.get(&Nibbles::default()),
3201 Some(&SparseNode::new_branch(0b101.into()))
3202 );
3203
3204 sparse.update_leaf(key2(), value_encoded(), &provider).unwrap();
3206
3207 assert_eq!(
3209 sparse.nodes.get(&Nibbles::default()),
3210 Some(&SparseNode::new_branch(0b111.into()))
3211 );
3212
3213 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3215 run_hash_builder(
3216 [(key1(), value()), (key3(), value())],
3217 NoopAccountTrieCursor::default(),
3218 Default::default(),
3219 [key3()],
3220 );
3221 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3222 let hash_mask = branch_node_hash_masks.get(&path).copied();
3223 let tree_mask = branch_node_tree_masks.get(&path).copied();
3224 sparse
3225 .reveal_node(
3226 path,
3227 TrieNode::decode(&mut &node[..]).unwrap(),
3228 TrieMasks { hash_mask, tree_mask },
3229 )
3230 .unwrap();
3231 }
3232
3233 assert_eq!(
3235 sparse.nodes.get(&Nibbles::default()),
3236 Some(&SparseNode::new_branch(0b111.into()))
3237 );
3238
3239 let (_, _, hash_builder_proof_nodes, _, _) = run_hash_builder(
3242 [(key1(), value()), (key2(), value()), (key3(), value())],
3243 NoopAccountTrieCursor::default(),
3244 Default::default(),
3245 [key1(), key2(), key3()],
3246 );
3247
3248 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
3249 }
3250
3251 #[test]
3262 fn sparse_trie_reveal_node_2() {
3263 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x00]));
3264 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x01]));
3265 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x02]));
3266 let value = || Account::default();
3267
3268 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3270 run_hash_builder(
3271 [(key1(), value()), (key2(), value()), (key3(), value())],
3272 NoopAccountTrieCursor::default(),
3273 Default::default(),
3274 [Nibbles::default()],
3275 );
3276
3277 let provider = DefaultTrieNodeProvider;
3278 let mut sparse = SerialSparseTrie::from_root(
3279 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
3280 TrieMasks {
3281 hash_mask: branch_node_hash_masks.get(&Nibbles::default()).copied(),
3282 tree_mask: branch_node_tree_masks.get(&Nibbles::default()).copied(),
3283 },
3284 false,
3285 )
3286 .unwrap();
3287
3288 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3291 run_hash_builder(
3292 [(key1(), value()), (key2(), value()), (key3(), value())],
3293 NoopAccountTrieCursor::default(),
3294 Default::default(),
3295 [key1(), Nibbles::from_nibbles_unchecked([0x01])],
3296 );
3297 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3298 let hash_mask = branch_node_hash_masks.get(&path).copied();
3299 let tree_mask = branch_node_tree_masks.get(&path).copied();
3300 sparse
3301 .reveal_node(
3302 path,
3303 TrieNode::decode(&mut &node[..]).unwrap(),
3304 TrieMasks { hash_mask, tree_mask },
3305 )
3306 .unwrap();
3307 }
3308
3309 assert_eq!(
3311 sparse.nodes.get(&Nibbles::default()),
3312 Some(&SparseNode::new_branch(0b11.into()))
3313 );
3314
3315 sparse.remove_leaf(&key1(), &provider).unwrap();
3317
3318 assert_eq!(
3320 sparse.nodes.get(&Nibbles::default()),
3321 Some(&SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x01])))
3322 );
3323
3324 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3326 run_hash_builder(
3327 [(key1(), value()), (key2(), value()), (key3(), value())],
3328 NoopAccountTrieCursor::default(),
3329 Default::default(),
3330 [key2()],
3331 );
3332 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3333 let hash_mask = branch_node_hash_masks.get(&path).copied();
3334 let tree_mask = branch_node_tree_masks.get(&path).copied();
3335 sparse
3336 .reveal_node(
3337 path,
3338 TrieNode::decode(&mut &node[..]).unwrap(),
3339 TrieMasks { hash_mask, tree_mask },
3340 )
3341 .unwrap();
3342 }
3343
3344 assert_eq!(
3346 sparse.nodes.get(&Nibbles::default()),
3347 Some(&SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x01])))
3348 );
3349 }
3350
3351 #[test]
3360 fn sparse_trie_reveal_node_3() {
3361 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x01]));
3362 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x02]));
3363 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x00]));
3364 let value = || Account::default();
3365 let value_encoded = || {
3366 let mut account_rlp = Vec::new();
3367 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
3368 account_rlp
3369 };
3370
3371 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3373 run_hash_builder(
3374 [(key1(), value()), (key2(), value())],
3375 NoopAccountTrieCursor::default(),
3376 Default::default(),
3377 [Nibbles::default()],
3378 );
3379
3380 let provider = DefaultTrieNodeProvider;
3381 let mut sparse = SerialSparseTrie::from_root(
3382 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
3383 TrieMasks {
3384 hash_mask: branch_node_hash_masks.get(&Nibbles::default()).copied(),
3385 tree_mask: branch_node_tree_masks.get(&Nibbles::default()).copied(),
3386 },
3387 false,
3388 )
3389 .unwrap();
3390
3391 assert_matches!(
3393 sparse.nodes.get(&Nibbles::default()),
3394 Some(SparseNode::Extension { key, hash: None, store_in_db_trie: None }) if *key == Nibbles::from_nibbles([0x00])
3395 );
3396
3397 sparse.update_leaf(key3(), value_encoded(), &provider).unwrap();
3399
3400 assert_matches!(
3402 sparse.nodes.get(&Nibbles::default()),
3403 Some(SparseNode::Branch { state_mask, hash: None, store_in_db_trie: None }) if *state_mask == TrieMask::new(0b11)
3404 );
3405
3406 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3408 run_hash_builder(
3409 [(key1(), value()), (key2(), value())],
3410 NoopAccountTrieCursor::default(),
3411 Default::default(),
3412 [key1()],
3413 );
3414 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3415 let hash_mask = branch_node_hash_masks.get(&path).copied();
3416 let tree_mask = branch_node_tree_masks.get(&path).copied();
3417 sparse
3418 .reveal_node(
3419 path,
3420 TrieNode::decode(&mut &node[..]).unwrap(),
3421 TrieMasks { hash_mask, tree_mask },
3422 )
3423 .unwrap();
3424 }
3425
3426 assert_matches!(
3428 sparse.nodes.get(&Nibbles::default()),
3429 Some(SparseNode::Branch { state_mask, hash: None, store_in_db_trie: None }) if *state_mask == TrieMask::new(0b11)
3430 );
3431 }
3432
3433 #[test]
3434 fn sparse_trie_get_changed_nodes_at_depth() {
3435 let provider = DefaultTrieNodeProvider;
3436 let mut sparse = SerialSparseTrie::default();
3437
3438 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3439
3440 sparse
3453 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3454 .unwrap();
3455 sparse
3456 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3457 .unwrap();
3458 sparse
3459 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3460 .unwrap();
3461 sparse
3462 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
3463 .unwrap();
3464 sparse
3465 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
3466 .unwrap();
3467 sparse
3468 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
3469 .unwrap();
3470
3471 assert_eq!(
3472 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 0),
3473 (vec![(0, Nibbles::default())], PrefixSetMut::default())
3474 );
3475 assert_eq!(
3476 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 1),
3477 (vec![(1, Nibbles::from_nibbles_unchecked([0x5]))], [Nibbles::default()].into())
3478 );
3479 assert_eq!(
3480 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 2),
3481 (
3482 vec![
3483 (2, Nibbles::from_nibbles_unchecked([0x5, 0x0])),
3484 (2, Nibbles::from_nibbles_unchecked([0x5, 0x2])),
3485 (2, Nibbles::from_nibbles_unchecked([0x5, 0x3]))
3486 ],
3487 [Nibbles::default(), Nibbles::from_nibbles_unchecked([0x5])].into()
3488 )
3489 );
3490 assert_eq!(
3491 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 3),
3492 (
3493 vec![
3494 (3, Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3])),
3495 (2, Nibbles::from_nibbles_unchecked([0x5, 0x2])),
3496 (3, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x1])),
3497 (3, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3]))
3498 ],
3499 [
3500 Nibbles::default(),
3501 Nibbles::from_nibbles_unchecked([0x5]),
3502 Nibbles::from_nibbles_unchecked([0x5, 0x0]),
3503 Nibbles::from_nibbles_unchecked([0x5, 0x3])
3504 ]
3505 .into()
3506 )
3507 );
3508 assert_eq!(
3509 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 4),
3510 (
3511 vec![
3512 (4, Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3, 0x1])),
3513 (4, Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3, 0x3])),
3514 (2, Nibbles::from_nibbles_unchecked([0x5, 0x2])),
3515 (3, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x1])),
3516 (4, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3, 0x0])),
3517 (4, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3, 0x2]))
3518 ],
3519 [
3520 Nibbles::default(),
3521 Nibbles::from_nibbles_unchecked([0x5]),
3522 Nibbles::from_nibbles_unchecked([0x5, 0x0]),
3523 Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3]),
3524 Nibbles::from_nibbles_unchecked([0x5, 0x3]),
3525 Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3])
3526 ]
3527 .into()
3528 )
3529 );
3530 }
3531
3532 #[test]
3533 fn hash_builder_branch_hash_mask() {
3534 let key1 = || pad_nibbles_left(Nibbles::from_nibbles_unchecked([0x00]));
3535 let key2 = || pad_nibbles_left(Nibbles::from_nibbles_unchecked([0x01]));
3536 let value = || Account { bytecode_hash: Some(B256::repeat_byte(1)), ..Default::default() };
3537 let value_encoded = || {
3538 let mut account_rlp = Vec::new();
3539 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
3540 account_rlp
3541 };
3542
3543 let (hash_builder_root, hash_builder_updates, _, _, _) = run_hash_builder(
3544 [(key1(), value()), (key2(), value())],
3545 NoopAccountTrieCursor::default(),
3546 Default::default(),
3547 [Nibbles::default()],
3548 );
3549
3550 let provider = DefaultTrieNodeProvider;
3551 let mut sparse = SerialSparseTrie::default();
3552 sparse.update_leaf(key1(), value_encoded(), &provider).unwrap();
3553 sparse.update_leaf(key2(), value_encoded(), &provider).unwrap();
3554 let sparse_root = sparse.root();
3555 let sparse_updates = sparse.take_updates();
3556
3557 assert_eq!(sparse_root, hash_builder_root);
3558 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
3559 }
3560
3561 #[test]
3562 fn sparse_trie_wipe() {
3563 let provider = DefaultTrieNodeProvider;
3564 let mut sparse = SerialSparseTrie::default().with_updates(true);
3565
3566 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3567
3568 sparse
3581 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3582 .unwrap();
3583 sparse
3584 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3585 .unwrap();
3586 sparse
3587 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3588 .unwrap();
3589 sparse
3590 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
3591 .unwrap();
3592 sparse
3593 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
3594 .unwrap();
3595 sparse
3596 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
3597 .unwrap();
3598
3599 sparse.wipe();
3600
3601 assert_matches!(
3602 &sparse.updates,
3603 Some(SparseTrieUpdates{ updated_nodes, removed_nodes, wiped })
3604 if updated_nodes.is_empty() && removed_nodes.is_empty() && *wiped
3605 );
3606 assert_eq!(sparse.root(), EMPTY_ROOT_HASH);
3607 }
3608
3609 #[test]
3610 fn sparse_trie_clear() {
3611 let provider = DefaultTrieNodeProvider;
3614 let mut sparse = SerialSparseTrie::default();
3615 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3616 sparse
3617 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3618 .unwrap();
3619 sparse
3620 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3621 .unwrap();
3622 sparse
3623 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3624 .unwrap();
3625 sparse
3626 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value, &provider)
3627 .unwrap();
3628
3629 sparse.clear();
3630
3631 let empty_trie = SerialSparseTrie::default();
3632 assert_eq!(empty_trie, sparse);
3633 }
3634
3635 #[test]
3636 fn sparse_trie_display() {
3637 let provider = DefaultTrieNodeProvider;
3638 let mut sparse = SerialSparseTrie::default();
3639
3640 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3641
3642 sparse
3655 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3656 .unwrap();
3657 sparse
3658 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3659 .unwrap();
3660 sparse
3661 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3662 .unwrap();
3663 sparse
3664 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
3665 .unwrap();
3666 sparse
3667 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
3668 .unwrap();
3669 sparse
3670 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
3671 .unwrap();
3672
3673 let normal_printed = format!("{sparse}");
3674 let expected = "\
3675Root -> Extension { key: Nibbles(0x5), hash: None, store_in_db_trie: None }
36765 -> Branch { state_mask: TrieMask(0000000000001101), hash: None, store_in_db_trie: None }
367750 -> Extension { key: Nibbles(0x23), hash: None, store_in_db_trie: None }
36785023 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
367950231 -> Leaf { key: Nibbles(0x), hash: None }
368050233 -> Leaf { key: Nibbles(0x), hash: None }
368152013 -> Leaf { key: Nibbles(0x013), hash: None }
368253 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
368353102 -> Leaf { key: Nibbles(0x02), hash: None }
3684533 -> Branch { state_mask: TrieMask(0000000000000101), hash: None, store_in_db_trie: None }
368553302 -> Leaf { key: Nibbles(0x2), hash: None }
368653320 -> Leaf { key: Nibbles(0x0), hash: None }
3687";
3688 assert_eq!(normal_printed, expected);
3689
3690 let alternate_printed = format!("{sparse:#}");
3691 let expected = "\
3692Root -> Extension { key: Nibbles(0x5), hash: None, store_in_db_trie: None }
3693 5 -> Branch { state_mask: TrieMask(0000000000001101), hash: None, store_in_db_trie: None }
3694 50 -> Extension { key: Nibbles(0x23), hash: None, store_in_db_trie: None }
3695 5023 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
3696 50231 -> Leaf { key: Nibbles(0x), hash: None }
3697 50233 -> Leaf { key: Nibbles(0x), hash: None }
3698 52013 -> Leaf { key: Nibbles(0x013), hash: None }
3699 53 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
3700 53102 -> Leaf { key: Nibbles(0x02), hash: None }
3701 533 -> Branch { state_mask: TrieMask(0000000000000101), hash: None, store_in_db_trie: None }
3702 53302 -> Leaf { key: Nibbles(0x2), hash: None }
3703 53320 -> Leaf { key: Nibbles(0x0), hash: None }
3704";
3705
3706 assert_eq!(alternate_printed, expected);
3707 }
3708}