1use crate::{
2 provider::{RevealedNode, TrieNodeProvider},
3 LeafLookup, LeafLookupError, SparseTrieInterface, SparseTrieUpdates,
4};
5use alloc::{
6 borrow::Cow,
7 boxed::Box,
8 fmt,
9 string::{String, ToString},
10 vec,
11 vec::Vec,
12};
13use alloy_primitives::{
14 hex, keccak256,
15 map::{Entry, HashMap, HashSet},
16 B256,
17};
18use alloy_rlp::Decodable;
19use reth_execution_errors::{SparseTrieErrorKind, SparseTrieResult};
20use reth_trie_common::{
21 prefix_set::{PrefixSet, PrefixSetMut},
22 BranchNodeCompact, BranchNodeRef, ExtensionNodeRef, LeafNodeRef, Nibbles, ProofTrieNode,
23 RlpNode, TrieMask, TrieMasks, TrieNode, CHILD_INDEX_RANGE, EMPTY_ROOT_HASH,
24};
25use smallvec::SmallVec;
26use tracing::{debug, instrument, trace};
27
28const SPARSE_TRIE_SUBTRIE_HASHES_LEVEL: usize = 2;
31
32#[derive(PartialEq, Eq, Debug, Clone)]
45pub enum SparseTrie<T = SerialSparseTrie> {
46 Blind(Option<Box<T>>),
54 Revealed(Box<T>),
60}
61
62impl<T: Default> Default for SparseTrie<T> {
63 fn default() -> Self {
64 Self::Blind(None)
65 }
66}
67
68impl<T: SparseTrieInterface + Default> SparseTrie<T> {
69 pub fn revealed_empty() -> Self {
80 Self::Revealed(Box::default())
81 }
82
83 pub fn reveal_root(
95 &mut self,
96 root: TrieNode,
97 masks: TrieMasks,
98 retain_updates: bool,
99 ) -> SparseTrieResult<&mut T> {
100 if self.is_blind() {
103 let mut revealed_trie = if let Self::Blind(Some(cleared_trie)) = core::mem::take(self) {
104 cleared_trie
105 } else {
106 Box::default()
107 };
108
109 *revealed_trie = revealed_trie.with_root(root, masks, retain_updates)?;
110 *self = Self::Revealed(revealed_trie);
111 }
112
113 Ok(self.as_revealed_mut().unwrap())
114 }
115}
116
117impl<T: SparseTrieInterface> SparseTrie<T> {
118 pub const fn blind() -> Self {
131 Self::Blind(None)
132 }
133
134 pub fn blind_from(mut trie: T) -> Self {
137 trie.clear();
138 Self::Blind(Some(Box::new(trie)))
139 }
140
141 pub const fn is_blind(&self) -> bool {
143 matches!(self, Self::Blind(_))
144 }
145
146 pub const fn is_revealed(&self) -> bool {
148 matches!(self, Self::Revealed(_))
149 }
150
151 pub const fn as_revealed_ref(&self) -> Option<&T> {
155 if let Self::Revealed(revealed) = self {
156 Some(revealed)
157 } else {
158 None
159 }
160 }
161
162 pub fn as_revealed_mut(&mut self) -> Option<&mut T> {
166 if let Self::Revealed(revealed) = self {
167 Some(revealed)
168 } else {
169 None
170 }
171 }
172
173 pub fn wipe(&mut self) -> SparseTrieResult<()> {
178 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
179 revealed.wipe();
180 Ok(())
181 }
182
183 pub fn root(&mut self) -> Option<B256> {
194 Some(self.as_revealed_mut()?.root())
195 }
196
197 pub fn root_with_updates(&mut self) -> Option<(B256, SparseTrieUpdates)> {
210 let revealed = self.as_revealed_mut()?;
211 Some((revealed.root(), revealed.take_updates()))
212 }
213
214 pub fn clear(self) -> Self {
218 match self {
219 Self::Blind(_) => self,
220 Self::Revealed(mut trie) => {
221 trie.clear();
222 Self::Blind(Some(trie))
223 }
224 }
225 }
226
227 #[instrument(level = "trace", target = "trie::sparse", skip_all)]
233 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 #[instrument(level = "trace", target = "trie::sparse", skip_all)]
250 pub fn remove_leaf(
251 &mut self,
252 path: &Nibbles,
253 provider: impl TrieNodeProvider,
254 ) -> SparseTrieResult<()> {
255 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
256 revealed.remove_leaf(path, provider)?;
257 Ok(())
258 }
259
260 pub fn shrink_nodes_to(&mut self, size: usize) {
263 match self {
264 Self::Blind(Some(trie)) | Self::Revealed(trie) => {
265 trie.shrink_nodes_to(size);
266 }
267 _ => {}
268 }
269 }
270
271 pub fn shrink_values_to(&mut self, size: usize) {
274 match self {
275 Self::Blind(Some(trie)) | Self::Revealed(trie) => {
276 trie.shrink_values_to(size);
277 }
278 _ => {}
279 }
280 }
281}
282
283#[derive(Clone, PartialEq, Eq)]
297pub struct SerialSparseTrie {
298 nodes: HashMap<Nibbles, SparseNode>,
301 branch_node_tree_masks: HashMap<Nibbles, TrieMask>,
303 branch_node_hash_masks: HashMap<Nibbles, TrieMask>,
305 values: HashMap<Nibbles, Vec<u8>>,
308 prefix_set: PrefixSetMut,
311 updates: Option<SparseTrieUpdates>,
313 rlp_buf: Vec<u8>,
315}
316
317impl fmt::Debug for SerialSparseTrie {
318 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
319 f.debug_struct("SerialSparseTrie")
320 .field("nodes", &self.nodes)
321 .field("branch_tree_masks", &self.branch_node_tree_masks)
322 .field("branch_hash_masks", &self.branch_node_hash_masks)
323 .field("values", &self.values)
324 .field("prefix_set", &self.prefix_set)
325 .field("updates", &self.updates)
326 .field("rlp_buf", &hex::encode(&self.rlp_buf))
327 .finish_non_exhaustive()
328 }
329}
330
331fn encode_nibbles(nibbles: &Nibbles) -> String {
333 let encoded = hex::encode(nibbles.pack());
334 encoded[..nibbles.len()].to_string()
335}
336
337impl fmt::Display for SerialSparseTrie {
338 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
339 let mut stack = Vec::new();
341 let mut visited = HashSet::new();
342
343 const INDENT: &str = " ";
345
346 stack.push((Nibbles::default(), self.nodes_ref().get(&Nibbles::default()).unwrap(), 0));
348
349 while let Some((path, node, depth)) = stack.pop() {
350 if !visited.insert(path) {
351 continue;
352 }
353
354 if f.alternate() {
356 write!(f, "{}", INDENT.repeat(depth))?;
357 }
358
359 let packed_path = if depth == 0 { String::from("Root") } else { encode_nibbles(&path) };
360
361 match node {
362 SparseNode::Empty | SparseNode::Hash(_) => {
363 writeln!(f, "{packed_path} -> {node:?}")?;
364 }
365 SparseNode::Leaf { key, .. } => {
366 let mut full_path = path;
368 full_path.extend(key);
369 let packed_path = encode_nibbles(&full_path);
370
371 writeln!(f, "{packed_path} -> {node:?}")?;
372 }
373 SparseNode::Extension { key, .. } => {
374 writeln!(f, "{packed_path} -> {node:?}")?;
375
376 let mut child_path = path;
378 child_path.extend(key);
379 if let Some(child_node) = self.nodes_ref().get(&child_path) {
380 stack.push((child_path, child_node, depth + 1));
381 }
382 }
383 SparseNode::Branch { state_mask, .. } => {
384 writeln!(f, "{packed_path} -> {node:?}")?;
385
386 for i in CHILD_INDEX_RANGE.rev() {
387 if state_mask.is_bit_set(i) {
388 let mut child_path = path;
389 child_path.push_unchecked(i);
390 if let Some(child_node) = self.nodes_ref().get(&child_path) {
391 stack.push((child_path, child_node, depth + 1));
392 }
393 }
394 }
395 }
396 }
397 }
398
399 Ok(())
400 }
401}
402
403impl Default for SerialSparseTrie {
404 fn default() -> Self {
405 Self {
406 nodes: HashMap::from_iter([(Nibbles::default(), SparseNode::Empty)]),
407 branch_node_tree_masks: HashMap::default(),
408 branch_node_hash_masks: HashMap::default(),
409 values: HashMap::default(),
410 prefix_set: PrefixSetMut::default(),
411 updates: None,
412 rlp_buf: Vec::new(),
413 }
414 }
415}
416
417impl SparseTrieInterface for SerialSparseTrie {
418 fn with_root(
419 mut self,
420 root: TrieNode,
421 masks: TrieMasks,
422 retain_updates: bool,
423 ) -> SparseTrieResult<Self> {
424 self = self.with_updates(retain_updates);
425
426 let path = Nibbles::default();
429 let _removed_root = self.nodes.remove(&path).expect("root node should exist");
430 debug_assert_eq!(_removed_root, SparseNode::Empty);
431
432 self.reveal_node(path, root, masks)?;
433 Ok(self)
434 }
435
436 fn with_updates(mut self, retain_updates: bool) -> Self {
437 if retain_updates {
438 self.updates = Some(SparseTrieUpdates::default());
439 }
440 self
441 }
442
443 fn reserve_nodes(&mut self, additional: usize) {
444 self.nodes.reserve(additional);
445 }
446 fn reveal_node(
447 &mut self,
448 path: Nibbles,
449 node: TrieNode,
450 masks: TrieMasks,
451 ) -> SparseTrieResult<()> {
452 trace!(target: "trie::sparse", ?path, ?node, ?masks, "reveal_node called");
453
454 if self.nodes.get(&path).is_some_and(|node| !node.is_hash()) {
456 return Ok(())
457 }
458
459 if let Some(tree_mask) = masks.tree_mask {
460 self.branch_node_tree_masks.insert(path, tree_mask);
461 }
462 if let Some(hash_mask) = masks.hash_mask {
463 self.branch_node_hash_masks.insert(path, hash_mask);
464 }
465
466 match node {
467 TrieNode::EmptyRoot => {
468 debug_assert!(path.is_empty());
470 self.nodes.insert(path, SparseNode::Empty);
471 }
472 TrieNode::Branch(branch) => {
473 let mut stack_ptr = branch.as_ref().first_child_index();
475 for idx in CHILD_INDEX_RANGE {
476 if branch.state_mask.is_bit_set(idx) {
477 let mut child_path = path;
478 child_path.push_unchecked(idx);
479 self.reveal_node_or_hash(child_path, &branch.stack[stack_ptr])?;
481 stack_ptr += 1;
482 }
483 }
484 match self.nodes.entry(path) {
487 Entry::Occupied(mut entry) => match entry.get() {
488 SparseNode::Hash(hash) => {
490 entry.insert(SparseNode::Branch {
491 state_mask: branch.state_mask,
492 hash: Some(*hash),
495 store_in_db_trie: Some(
496 masks.hash_mask.is_some_and(|mask| !mask.is_empty()) ||
497 masks.tree_mask.is_some_and(|mask| !mask.is_empty()),
498 ),
499 });
500 }
501 SparseNode::Branch { .. } | SparseNode::Extension { .. } => {}
504 node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => {
506 return Err(SparseTrieErrorKind::Reveal {
507 path: *entry.key(),
508 node: Box::new(node.clone()),
509 }
510 .into())
511 }
512 },
513 Entry::Vacant(entry) => {
514 entry.insert(SparseNode::new_branch(branch.state_mask));
515 }
516 }
517 }
518 TrieNode::Extension(ext) => match self.nodes.entry(path) {
519 Entry::Occupied(mut entry) => match entry.get() {
520 SparseNode::Hash(hash) => {
522 let mut child_path = *entry.key();
523 child_path.extend(&ext.key);
524 entry.insert(SparseNode::Extension {
525 key: ext.key,
526 hash: Some(*hash),
529 store_in_db_trie: None,
530 });
531 self.reveal_node_or_hash(child_path, &ext.child)?;
532 }
533 SparseNode::Extension { .. } | SparseNode::Branch { .. } => {}
536 node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => {
538 return Err(SparseTrieErrorKind::Reveal {
539 path: *entry.key(),
540 node: Box::new(node.clone()),
541 }
542 .into())
543 }
544 },
545 Entry::Vacant(entry) => {
546 let mut child_path = *entry.key();
547 child_path.extend(&ext.key);
548 entry.insert(SparseNode::new_ext(ext.key));
549 self.reveal_node_or_hash(child_path, &ext.child)?;
550 }
551 },
552 TrieNode::Leaf(leaf) => match self.nodes.entry(path) {
553 Entry::Occupied(mut entry) => match entry.get() {
554 SparseNode::Hash(hash) => {
556 let mut full = *entry.key();
557 full.extend(&leaf.key);
558 self.values.insert(full, leaf.value.clone());
559 entry.insert(SparseNode::Leaf {
560 key: leaf.key,
561 hash: Some(*hash),
564 });
565 }
566 SparseNode::Leaf { .. } => {}
568 node @ (SparseNode::Empty |
570 SparseNode::Extension { .. } |
571 SparseNode::Branch { .. }) => {
572 return Err(SparseTrieErrorKind::Reveal {
573 path: *entry.key(),
574 node: Box::new(node.clone()),
575 }
576 .into())
577 }
578 },
579 Entry::Vacant(entry) => {
580 let mut full = *entry.key();
581 full.extend(&leaf.key);
582 entry.insert(SparseNode::new_leaf(leaf.key));
583 self.values.insert(full, leaf.value.clone());
584 }
585 },
586 }
587
588 Ok(())
589 }
590
591 fn reveal_nodes(&mut self, mut nodes: Vec<ProofTrieNode>) -> SparseTrieResult<()> {
592 nodes.sort_unstable_by_key(|node| node.path);
593 for node in nodes {
594 self.reveal_node(node.path, node.node, node.masks)?;
595 }
596 Ok(())
597 }
598
599 #[instrument(level = "trace", target = "trie::sparse::serial", skip(self, provider))]
600 fn update_leaf<P: TrieNodeProvider>(
601 &mut self,
602 full_path: Nibbles,
603 value: Vec<u8>,
604 provider: P,
605 ) -> SparseTrieResult<()> {
606 self.prefix_set.insert(full_path);
607 let existing = self.values.insert(full_path, value);
608 if existing.is_some() {
609 return Ok(())
611 }
612
613 let mut current = Nibbles::default();
614 while let Some(node) = self.nodes.get_mut(¤t) {
615 match node {
616 SparseNode::Empty => {
617 *node = SparseNode::new_leaf(full_path);
618 break
619 }
620 &mut SparseNode::Hash(hash) => {
621 return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into())
622 }
623 SparseNode::Leaf { key: current_key, .. } => {
624 current.extend(current_key);
625
626 if current == full_path {
628 unreachable!("we already checked leaf presence in the beginning");
629 }
630
631 let common = current.common_prefix_length(&full_path);
633
634 let new_ext_key = current.slice(current.len() - current_key.len()..common);
636 *node = SparseNode::new_ext(new_ext_key);
637
638 self.nodes.reserve(3);
640 self.nodes.insert(
641 current.slice(..common),
642 SparseNode::new_split_branch(
643 current.get_unchecked(common),
644 full_path.get_unchecked(common),
645 ),
646 );
647 self.nodes.insert(
648 full_path.slice(..=common),
649 SparseNode::new_leaf(full_path.slice(common + 1..)),
650 );
651 self.nodes.insert(
652 current.slice(..=common),
653 SparseNode::new_leaf(current.slice(common + 1..)),
654 );
655
656 break;
657 }
658 SparseNode::Extension { key, .. } => {
659 current.extend(key);
660
661 if !full_path.starts_with(¤t) {
662 let common = current.common_prefix_length(&full_path);
664 *key = current.slice(current.len() - key.len()..common);
665
666 if self.updates.is_some() {
670 if self.nodes.get(¤t).unwrap().is_hash() {
672 debug!(
673 target: "trie::sparse",
674 leaf_full_path = ?full_path,
675 child_path = ?current,
676 "Extension node child not revealed in update_leaf, falling back to db",
677 );
678 if let Some(RevealedNode { node, tree_mask, hash_mask }) =
679 provider.trie_node(¤t)?
680 {
681 let decoded = TrieNode::decode(&mut &node[..])?;
682 trace!(
683 target: "trie::sparse",
684 ?current,
685 ?decoded,
686 ?tree_mask,
687 ?hash_mask,
688 "Revealing extension node child",
689 );
690 self.reveal_node(
691 current,
692 decoded,
693 TrieMasks { hash_mask, tree_mask },
694 )?;
695 }
696 }
697 }
698
699 self.nodes.reserve(3);
702 let branch = SparseNode::new_split_branch(
703 current.get_unchecked(common),
704 full_path.get_unchecked(common),
705 );
706 self.nodes.insert(current.slice(..common), branch);
707
708 let new_leaf = SparseNode::new_leaf(full_path.slice(common + 1..));
710 self.nodes.insert(full_path.slice(..=common), new_leaf);
711
712 let key = current.slice(common + 1..);
714 if !key.is_empty() {
715 self.nodes.insert(current.slice(..=common), SparseNode::new_ext(key));
716 }
717
718 break;
719 }
720 }
721 SparseNode::Branch { state_mask, .. } => {
722 let nibble = full_path.get_unchecked(current.len());
723 current.push_unchecked(nibble);
724 if !state_mask.is_bit_set(nibble) {
725 state_mask.set_bit(nibble);
726 let new_leaf = SparseNode::new_leaf(full_path.slice(current.len()..));
727 self.nodes.insert(current, new_leaf);
728 break;
729 }
730 }
731 };
732 }
733
734 Ok(())
735 }
736
737 #[instrument(level = "trace", target = "trie::sparse::serial", skip(self, provider))]
738 fn remove_leaf<P: TrieNodeProvider>(
739 &mut self,
740 full_path: &Nibbles,
741 provider: P,
742 ) -> SparseTrieResult<()> {
743 trace!(target: "trie::sparse", ?full_path, "remove_leaf called");
744
745 if self.values.remove(full_path).is_none() {
746 if let Some(&SparseNode::Hash(hash)) = self.nodes.get(full_path) {
747 return Err(SparseTrieErrorKind::BlindedNode { path: *full_path, hash }.into())
749 }
750
751 trace!(target: "trie::sparse", ?full_path, "Leaf node is not present in the trie");
752 return Ok(())
754 }
755 self.prefix_set.insert(*full_path);
756
757 let mut removed_nodes = self.take_nodes_for_path(full_path)?;
762 let mut child = removed_nodes.pop().expect("leaf exists");
764 #[cfg(debug_assertions)]
765 {
766 let mut child_path = child.path;
767 let SparseNode::Leaf { key, .. } = &child.node else { panic!("expected leaf node") };
768 child_path.extend(key);
769 assert_eq!(&child_path, full_path);
770 }
771
772 if removed_nodes.is_empty() {
774 debug_assert!(self.nodes.is_empty());
775 self.nodes.insert(Nibbles::default(), SparseNode::Empty);
776
777 return Ok(())
778 }
779
780 while let Some(removed_node) = removed_nodes.pop() {
783 let removed_path = removed_node.path;
784
785 let new_node = match &removed_node.node {
786 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
787 &SparseNode::Hash(hash) => {
788 return Err(SparseTrieErrorKind::BlindedNode { path: removed_path, hash }.into())
789 }
790 SparseNode::Leaf { .. } => {
791 unreachable!("we already popped the leaf node")
792 }
793 SparseNode::Extension { key, .. } => {
794 match &child.node {
797 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
798 &SparseNode::Hash(hash) => {
799 return Err(
800 SparseTrieErrorKind::BlindedNode { path: child.path, hash }.into()
801 )
802 }
803 SparseNode::Leaf { key: leaf_key, .. } => {
809 self.nodes.remove(&child.path);
810
811 let mut new_key = *key;
812 new_key.extend(leaf_key);
813 SparseNode::new_leaf(new_key)
814 }
815 SparseNode::Extension { key: extension_key, .. } => {
818 self.nodes.remove(&child.path);
819
820 let mut new_key = *key;
821 new_key.extend(extension_key);
822 SparseNode::new_ext(new_key)
823 }
824 SparseNode::Branch { .. } => removed_node.node,
826 }
827 }
828 &SparseNode::Branch { mut state_mask, hash: _, store_in_db_trie: _ } => {
829 if let Some(removed_nibble) = removed_node.unset_branch_nibble {
833 state_mask.unset_bit(removed_nibble);
834 }
835
836 if state_mask.count_bits() == 1 {
838 let child_nibble =
839 state_mask.first_set_bit_index().expect("state mask is not empty");
840
841 let mut child_path = removed_path;
843 child_path.push_unchecked(child_nibble);
844
845 trace!(target: "trie::sparse", ?removed_path, ?child_path, "Branch node has only one child");
846
847 let child = self.reveal_remaining_child_on_leaf_removal(
850 &provider,
851 full_path,
852 &child_path,
853 true, )?;
855
856 let mut delete_child = false;
857 let new_node = match &child {
858 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
859 &SparseNode::Hash(hash) => {
860 return Err(SparseTrieErrorKind::BlindedNode {
861 path: child_path,
862 hash,
863 }
864 .into())
865 }
866 SparseNode::Leaf { key, .. } => {
870 delete_child = true;
871
872 let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]);
873 new_key.extend(key);
874 SparseNode::new_leaf(new_key)
875 }
876 SparseNode::Extension { key, .. } => {
880 delete_child = true;
881
882 let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]);
883 new_key.extend(key);
884 SparseNode::new_ext(new_key)
885 }
886 SparseNode::Branch { .. } => {
889 SparseNode::new_ext(Nibbles::from_nibbles_unchecked([child_nibble]))
890 }
891 };
892
893 if delete_child {
894 self.nodes.remove(&child_path);
895 }
896
897 if let Some(updates) = self.updates.as_mut() {
898 updates.updated_nodes.remove(&removed_path);
899 updates.removed_nodes.insert(removed_path);
900 }
901
902 new_node
903 }
904 else {
906 SparseNode::new_branch(state_mask)
907 }
908 }
909 };
910
911 child = RemovedSparseNode {
912 path: removed_path,
913 node: new_node.clone(),
914 unset_branch_nibble: None,
915 };
916 trace!(target: "trie::sparse", ?removed_path, ?new_node, "Re-inserting the node");
917 self.nodes.insert(removed_path, new_node);
918 }
919
920 Ok(())
921 }
922
923 #[instrument(target = "trie::sparse::serial", skip(self))]
924 fn root(&mut self) -> B256 {
925 let mut prefix_set = core::mem::take(&mut self.prefix_set).freeze();
927 let rlp_node = self.rlp_node_allocate(&mut prefix_set);
928 if let Some(root_hash) = rlp_node.as_hash() {
929 root_hash
930 } else {
931 keccak256(rlp_node)
932 }
933 }
934
935 fn update_subtrie_hashes(&mut self) {
936 self.update_rlp_node_level(SPARSE_TRIE_SUBTRIE_HASHES_LEVEL);
937 }
938
939 fn get_leaf_value(&self, full_path: &Nibbles) -> Option<&Vec<u8>> {
940 self.values.get(full_path)
941 }
942
943 fn updates_ref(&self) -> Cow<'_, SparseTrieUpdates> {
944 self.updates.as_ref().map_or(Cow::Owned(SparseTrieUpdates::default()), Cow::Borrowed)
945 }
946
947 fn take_updates(&mut self) -> SparseTrieUpdates {
948 self.updates.take().unwrap_or_default()
949 }
950
951 fn wipe(&mut self) {
952 self.nodes = HashMap::from_iter([(Nibbles::default(), SparseNode::Empty)]);
953 self.values = HashMap::default();
954 self.prefix_set = PrefixSetMut::all();
955 self.updates = self.updates.is_some().then(SparseTrieUpdates::wiped);
956 }
957
958 fn clear(&mut self) {
959 self.nodes.clear();
960 self.nodes.insert(Nibbles::default(), SparseNode::Empty);
961
962 self.branch_node_tree_masks.clear();
963 self.branch_node_hash_masks.clear();
964 self.values.clear();
965 self.prefix_set.clear();
966 self.updates = None;
967 self.rlp_buf.clear();
968 }
969
970 fn find_leaf(
971 &self,
972 full_path: &Nibbles,
973 expected_value: Option<&Vec<u8>>,
974 ) -> Result<LeafLookup, LeafLookupError> {
975 #[inline]
977 fn check_value_match(
978 actual_value: &Vec<u8>,
979 expected_value: Option<&Vec<u8>>,
980 path: &Nibbles,
981 ) -> Result<(), LeafLookupError> {
982 if let Some(expected) = expected_value &&
983 actual_value != expected
984 {
985 return Err(LeafLookupError::ValueMismatch {
986 path: *path,
987 expected: Some(expected.clone()),
988 actual: actual_value.clone(),
989 });
990 }
991 Ok(())
992 }
993
994 let mut current = Nibbles::default(); if let Some(actual_value) = self.values.get(full_path) {
1002 check_value_match(actual_value, expected_value, full_path)?;
1004 return Ok(LeafLookup::Exists);
1005 }
1006
1007 while current.len() < full_path.len() {
1014 match self.nodes.get(¤t) {
1015 Some(SparseNode::Empty) | None => {
1016 return Ok(LeafLookup::NonExistent);
1019 }
1020 Some(&SparseNode::Hash(hash)) => {
1021 return Err(LeafLookupError::BlindedNode { path: current, hash });
1023 }
1024 Some(SparseNode::Leaf { key, .. }) => {
1025 current.extend(key);
1027 if ¤t == full_path {
1028 if let Some(value) = self.values.get(full_path) {
1030 check_value_match(value, expected_value, full_path)?;
1031 return Ok(LeafLookup::Exists);
1032 }
1033 }
1034
1035 return Ok(LeafLookup::NonExistent);
1038 }
1039 Some(SparseNode::Extension { key, .. }) => {
1040 let saved_len = current.len();
1042 current.extend(key);
1043
1044 if full_path.len() < current.len() || !full_path.starts_with(¤t) {
1045 current.truncate(saved_len); return Ok(LeafLookup::NonExistent);
1047 }
1048 }
1050 Some(SparseNode::Branch { state_mask, .. }) => {
1051 let nibble = full_path.get_unchecked(current.len());
1053 if !state_mask.is_bit_set(nibble) {
1054 return Ok(LeafLookup::NonExistent);
1056 }
1057
1058 current.push_unchecked(nibble);
1060 }
1061 }
1062 }
1063
1064 match self.nodes.get(full_path) {
1067 Some(SparseNode::Leaf { key, .. }) if key.is_empty() => {
1068 if let Some(value) = self.values.get(full_path) {
1071 check_value_match(value, expected_value, full_path)?;
1072 return Ok(LeafLookup::Exists);
1073 }
1074 }
1075 Some(&SparseNode::Hash(hash)) => {
1076 return Err(LeafLookupError::BlindedNode { path: *full_path, hash });
1077 }
1078 _ => {
1079 return Ok(LeafLookup::NonExistent);
1081 }
1082 }
1083
1084 Ok(LeafLookup::NonExistent)
1086 }
1087
1088 fn shrink_nodes_to(&mut self, size: usize) {
1089 self.nodes.shrink_to(size);
1090 self.branch_node_tree_masks.shrink_to(size);
1091 self.branch_node_hash_masks.shrink_to(size);
1092 }
1093
1094 fn shrink_values_to(&mut self, size: usize) {
1095 self.values.shrink_to(size);
1096 }
1097}
1098
1099impl SerialSparseTrie {
1100 pub fn from_root(
1115 root: TrieNode,
1116 masks: TrieMasks,
1117 retain_updates: bool,
1118 ) -> SparseTrieResult<Self> {
1119 Self::default().with_root(root, masks, retain_updates)
1120 }
1121
1122 pub fn updates_ref(&self) -> Cow<'_, SparseTrieUpdates> {
1126 self.updates.as_ref().map_or(Cow::Owned(SparseTrieUpdates::default()), Cow::Borrowed)
1127 }
1128
1129 pub const fn nodes_ref(&self) -> &HashMap<Nibbles, SparseNode> {
1131 &self.nodes
1132 }
1133
1134 fn reveal_node_or_hash(&mut self, path: Nibbles, child: &[u8]) -> SparseTrieResult<()> {
1153 if child.len() == B256::len_bytes() + 1 {
1154 let hash = B256::from_slice(&child[1..]);
1155 match self.nodes.entry(path) {
1156 Entry::Occupied(entry) => match entry.get() {
1157 SparseNode::Hash(previous_hash) if previous_hash != &hash => {
1159 return Err(SparseTrieErrorKind::Reveal {
1160 path: *entry.key(),
1161 node: Box::new(SparseNode::Hash(hash)),
1162 }
1163 .into())
1164 }
1165 _ => {}
1166 },
1167 Entry::Vacant(entry) => {
1168 entry.insert(SparseNode::Hash(hash));
1169 }
1170 }
1171 return Ok(())
1172 }
1173
1174 self.reveal_node(path, TrieNode::decode(&mut &child[..])?, TrieMasks::none())
1175 }
1176
1177 fn take_nodes_for_path(&mut self, path: &Nibbles) -> SparseTrieResult<Vec<RemovedSparseNode>> {
1194 let mut current = Nibbles::default(); let mut nodes = Vec::new(); while let Some(node) = self.nodes.remove(¤t) {
1198 match &node {
1199 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
1200 &SparseNode::Hash(hash) => {
1201 return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into())
1202 }
1203 SparseNode::Leaf { key: _key, .. } => {
1204 #[cfg(debug_assertions)]
1208 {
1209 let mut current = current;
1210 current.extend(_key);
1211 assert_eq!(¤t, path);
1212 }
1213
1214 nodes.push(RemovedSparseNode {
1215 path: current,
1216 node,
1217 unset_branch_nibble: None,
1218 });
1219 break
1220 }
1221 SparseNode::Extension { key, .. } => {
1222 #[cfg(debug_assertions)]
1223 {
1224 let mut current = current;
1225 current.extend(key);
1226 assert!(
1227 path.starts_with(¤t),
1228 "path: {path:?}, current: {current:?}, key: {key:?}",
1229 );
1230 }
1231
1232 let path = current;
1233 current.extend(key);
1234 nodes.push(RemovedSparseNode { path, node, unset_branch_nibble: None });
1235 }
1236 SparseNode::Branch { state_mask, .. } => {
1237 let nibble = path.get_unchecked(current.len());
1238 debug_assert!(
1239 state_mask.is_bit_set(nibble),
1240 "current: {current:?}, path: {path:?}, nibble: {nibble:?}, state_mask: {state_mask:?}",
1241 );
1242
1243 let mut child_path = current;
1249 child_path.push_unchecked(nibble);
1250 let unset_branch_nibble = self
1251 .nodes
1252 .get(&child_path)
1253 .is_some_and(move |node| match node {
1254 SparseNode::Leaf { key, .. } => {
1255 child_path.extend(key);
1257 &child_path == path
1258 }
1259 _ => false,
1260 })
1261 .then_some(nibble);
1262
1263 nodes.push(RemovedSparseNode { path: current, node, unset_branch_nibble });
1264
1265 current.push_unchecked(nibble);
1266 }
1267 }
1268 }
1269
1270 Ok(nodes)
1271 }
1272
1273 fn reveal_remaining_child_on_leaf_removal<P: TrieNodeProvider>(
1283 &mut self,
1284 provider: P,
1285 full_path: &Nibbles, remaining_child_path: &Nibbles,
1287 recurse_into_extension: bool,
1288 ) -> SparseTrieResult<SparseNode> {
1289 let remaining_child_node = match self.nodes.get(remaining_child_path).unwrap() {
1290 SparseNode::Hash(_) => {
1291 debug!(
1292 target: "trie::parallel_sparse",
1293 child_path = ?remaining_child_path,
1294 leaf_full_path = ?full_path,
1295 "Node child not revealed in remove_leaf, falling back to db",
1296 );
1297 if let Some(RevealedNode { node, tree_mask, hash_mask }) =
1298 provider.trie_node(remaining_child_path)?
1299 {
1300 let decoded = TrieNode::decode(&mut &node[..])?;
1301 trace!(
1302 target: "trie::parallel_sparse",
1303 ?remaining_child_path,
1304 ?decoded,
1305 ?tree_mask,
1306 ?hash_mask,
1307 "Revealing remaining blinded branch child"
1308 );
1309 self.reveal_node(
1310 *remaining_child_path,
1311 decoded,
1312 TrieMasks { hash_mask, tree_mask },
1313 )?;
1314 self.nodes.get(remaining_child_path).unwrap().clone()
1315 } else {
1316 return Err(SparseTrieErrorKind::NodeNotFoundInProvider {
1317 path: *remaining_child_path,
1318 }
1319 .into())
1320 }
1321 }
1322 node => node.clone(),
1323 };
1324
1325 if let SparseNode::Extension { key, .. } = &remaining_child_node &&
1330 recurse_into_extension
1331 {
1332 let mut remaining_grandchild_path = *remaining_child_path;
1333 remaining_grandchild_path.extend(key);
1334
1335 trace!(
1336 target: "trie::parallel_sparse",
1337 remaining_grandchild_path = ?remaining_grandchild_path,
1338 child_path = ?remaining_child_path,
1339 leaf_full_path = ?full_path,
1340 "Revealing child of extension node, which is the last remaining child of the branch"
1341 );
1342
1343 self.reveal_remaining_child_on_leaf_removal(
1344 provider,
1345 full_path,
1346 &remaining_grandchild_path,
1347 false, )?;
1349 }
1350
1351 Ok(remaining_child_node)
1352 }
1353
1354 #[instrument(level = "trace", target = "trie::sparse::serial", skip(self))]
1363 pub fn update_rlp_node_level(&mut self, depth: usize) {
1364 let mut prefix_set = core::mem::take(&mut self.prefix_set).freeze();
1366 let mut buffers = RlpNodeBuffers::default();
1367
1368 let (targets, new_prefix_set) = self.get_changed_nodes_at_depth(&mut prefix_set, depth);
1370 self.prefix_set = new_prefix_set;
1372
1373 trace!(target: "trie::sparse", ?depth, ?targets, "Updating nodes at depth");
1374
1375 let mut temp_rlp_buf = core::mem::take(&mut self.rlp_buf);
1376 for (level, path) in targets {
1377 buffers.path_stack.push(RlpNodePathStackItem {
1378 level,
1379 path,
1380 is_in_prefix_set: Some(true),
1381 });
1382 self.rlp_node(&mut prefix_set, &mut buffers, &mut temp_rlp_buf);
1383 }
1384 self.rlp_buf = temp_rlp_buf;
1385 }
1386
1387 #[instrument(level = "trace", target = "trie::sparse::serial", skip(self))]
1409 fn get_changed_nodes_at_depth(
1410 &self,
1411 prefix_set: &mut PrefixSet,
1412 depth: usize,
1413 ) -> (Vec<(usize, Nibbles)>, PrefixSetMut) {
1414 let mut unchanged_prefix_set = PrefixSetMut::default();
1415 let mut paths = Vec::from([(Nibbles::default(), 0)]);
1416 let mut targets = Vec::new();
1417
1418 while let Some((mut path, level)) = paths.pop() {
1419 match self.nodes.get(&path).unwrap() {
1420 SparseNode::Empty | SparseNode::Hash(_) => {}
1421 SparseNode::Leaf { key: _, hash } => {
1422 if hash.is_some() && !prefix_set.contains(&path) {
1423 continue
1424 }
1425
1426 targets.push((level, path));
1427 }
1428 SparseNode::Extension { key, hash, store_in_db_trie: _ } => {
1429 if hash.is_some() && !prefix_set.contains(&path) {
1430 continue
1431 }
1432
1433 if level >= depth {
1434 targets.push((level, path));
1435 } else {
1436 unchanged_prefix_set.insert(path);
1437
1438 path.extend(key);
1439 paths.push((path, level + 1));
1440 }
1441 }
1442 SparseNode::Branch { state_mask, hash, store_in_db_trie: _ } => {
1443 if hash.is_some() && !prefix_set.contains(&path) {
1444 continue
1445 }
1446
1447 if level >= depth {
1448 targets.push((level, path));
1449 } else {
1450 unchanged_prefix_set.insert(path);
1451
1452 for bit in CHILD_INDEX_RANGE.rev() {
1453 if state_mask.is_bit_set(bit) {
1454 let mut child_path = path;
1455 child_path.push_unchecked(bit);
1456 paths.push((child_path, level + 1));
1457 }
1458 }
1459 }
1460 }
1461 }
1462 }
1463
1464 (targets, unchanged_prefix_set)
1465 }
1466
1467 pub fn rlp_node_allocate(&mut self, prefix_set: &mut PrefixSet) -> RlpNode {
1473 let mut buffers = RlpNodeBuffers::new_with_root_path();
1474 let mut temp_rlp_buf = core::mem::take(&mut self.rlp_buf);
1475 let result = self.rlp_node(prefix_set, &mut buffers, &mut temp_rlp_buf);
1476 self.rlp_buf = temp_rlp_buf;
1477
1478 result
1479 }
1480
1481 #[instrument(level = "trace", target = "trie::sparse::serial", skip_all, ret(level = "trace"))]
1496 pub fn rlp_node(
1497 &mut self,
1498 prefix_set: &mut PrefixSet,
1499 buffers: &mut RlpNodeBuffers,
1500 rlp_buf: &mut Vec<u8>,
1501 ) -> RlpNode {
1502 let _starting_path = buffers.path_stack.last().map(|item| item.path);
1503
1504 'main: while let Some(RlpNodePathStackItem { level, path, mut is_in_prefix_set }) =
1505 buffers.path_stack.pop()
1506 {
1507 let node = self.nodes.get_mut(&path).unwrap();
1508 trace!(
1509 target: "trie::sparse",
1510 ?_starting_path,
1511 ?level,
1512 ?path,
1513 ?is_in_prefix_set,
1514 ?node,
1515 "Popped node from path stack"
1516 );
1517
1518 let mut prefix_set_contains =
1522 |path: &Nibbles| *is_in_prefix_set.get_or_insert_with(|| prefix_set.contains(path));
1523
1524 let (rlp_node, node_type) = match node {
1525 SparseNode::Empty => (RlpNode::word_rlp(&EMPTY_ROOT_HASH), SparseNodeType::Empty),
1526 SparseNode::Hash(hash) => (RlpNode::word_rlp(hash), SparseNodeType::Hash),
1527 SparseNode::Leaf { key, hash } => {
1528 let mut path = path;
1529 path.extend(key);
1530 if let Some(hash) = hash.filter(|_| !prefix_set_contains(&path)) {
1531 (RlpNode::word_rlp(&hash), SparseNodeType::Leaf)
1532 } else {
1533 let value = self.values.get(&path).unwrap();
1534 rlp_buf.clear();
1535 let rlp_node = LeafNodeRef { key, value }.rlp(rlp_buf);
1536 *hash = rlp_node.as_hash();
1537 (rlp_node, SparseNodeType::Leaf)
1538 }
1539 }
1540 SparseNode::Extension { key, hash, store_in_db_trie } => {
1541 let mut child_path = path;
1542 child_path.extend(key);
1543 if let Some((hash, store_in_db_trie)) =
1544 hash.zip(*store_in_db_trie).filter(|_| !prefix_set_contains(&path))
1545 {
1546 (
1547 RlpNode::word_rlp(&hash),
1548 SparseNodeType::Extension { store_in_db_trie: Some(store_in_db_trie) },
1549 )
1550 } else if buffers.rlp_node_stack.last().is_some_and(|e| e.path == child_path) {
1551 let RlpNodeStackItem {
1552 path: _,
1553 rlp_node: child,
1554 node_type: child_node_type,
1555 } = buffers.rlp_node_stack.pop().unwrap();
1556 rlp_buf.clear();
1557 let rlp_node = ExtensionNodeRef::new(key, &child).rlp(rlp_buf);
1558 *hash = rlp_node.as_hash();
1559
1560 let store_in_db_trie_value = child_node_type.store_in_db_trie();
1561
1562 trace!(
1563 target: "trie::sparse",
1564 ?path,
1565 ?child_path,
1566 ?child_node_type,
1567 "Extension node"
1568 );
1569
1570 *store_in_db_trie = store_in_db_trie_value;
1571
1572 (
1573 rlp_node,
1574 SparseNodeType::Extension {
1575 store_in_db_trie: store_in_db_trie_value,
1578 },
1579 )
1580 } else {
1581 buffers.path_stack.extend([
1583 RlpNodePathStackItem { level, path, is_in_prefix_set },
1584 RlpNodePathStackItem {
1585 level: level + 1,
1586 path: child_path,
1587 is_in_prefix_set: None,
1588 },
1589 ]);
1590 continue
1591 }
1592 }
1593 SparseNode::Branch { state_mask, hash, store_in_db_trie } => {
1594 if let Some((hash, store_in_db_trie)) =
1595 hash.zip(*store_in_db_trie).filter(|_| !prefix_set_contains(&path))
1596 {
1597 buffers.rlp_node_stack.push(RlpNodeStackItem {
1598 path,
1599 rlp_node: RlpNode::word_rlp(&hash),
1600 node_type: SparseNodeType::Branch {
1601 store_in_db_trie: Some(store_in_db_trie),
1602 },
1603 });
1604 continue
1605 }
1606 let retain_updates = self.updates.is_some() && prefix_set_contains(&path);
1607
1608 buffers.branch_child_buf.clear();
1609 for bit in CHILD_INDEX_RANGE.rev() {
1612 if state_mask.is_bit_set(bit) {
1613 let mut child = path;
1614 child.push_unchecked(bit);
1615 buffers.branch_child_buf.push(child);
1616 }
1617 }
1618
1619 buffers
1620 .branch_value_stack_buf
1621 .resize(buffers.branch_child_buf.len(), Default::default());
1622 let mut added_children = false;
1623
1624 let mut tree_mask = TrieMask::default();
1625 let mut hash_mask = TrieMask::default();
1626 let mut hashes = Vec::new();
1627 for (i, child_path) in buffers.branch_child_buf.iter().enumerate() {
1628 if buffers.rlp_node_stack.last().is_some_and(|e| &e.path == child_path) {
1629 let RlpNodeStackItem {
1630 path: _,
1631 rlp_node: child,
1632 node_type: child_node_type,
1633 } = buffers.rlp_node_stack.pop().unwrap();
1634
1635 if retain_updates {
1637 let last_child_nibble = child_path.last().unwrap();
1639
1640 let should_set_tree_mask_bit = if let Some(store_in_db_trie) =
1642 child_node_type.store_in_db_trie()
1643 {
1644 store_in_db_trie
1647 } else {
1648 child_node_type.is_hash() &&
1650 self.branch_node_tree_masks.get(&path).is_some_and(
1651 |mask| mask.is_bit_set(last_child_nibble),
1652 )
1653 };
1654 if should_set_tree_mask_bit {
1655 tree_mask.set_bit(last_child_nibble);
1656 }
1657
1658 let hash = child.as_hash().filter(|_| {
1662 child_node_type.is_branch() ||
1663 (child_node_type.is_hash() &&
1664 self.branch_node_hash_masks
1665 .get(&path)
1666 .is_some_and(|mask| {
1667 mask.is_bit_set(last_child_nibble)
1668 }))
1669 });
1670 if let Some(hash) = hash {
1671 hash_mask.set_bit(last_child_nibble);
1672 hashes.push(hash);
1673 }
1674 }
1675
1676 let original_idx = buffers.branch_child_buf.len() - i - 1;
1680 buffers.branch_value_stack_buf[original_idx] = child;
1681 added_children = true;
1682 } else {
1683 debug_assert!(!added_children);
1684 buffers.path_stack.push(RlpNodePathStackItem {
1685 level,
1686 path,
1687 is_in_prefix_set,
1688 });
1689 buffers.path_stack.extend(buffers.branch_child_buf.drain(..).map(
1690 |path| RlpNodePathStackItem {
1691 level: level + 1,
1692 path,
1693 is_in_prefix_set: None,
1694 },
1695 ));
1696 continue 'main
1697 }
1698 }
1699
1700 trace!(
1701 target: "trie::sparse",
1702 ?path,
1703 ?tree_mask,
1704 ?hash_mask,
1705 "Branch node masks"
1706 );
1707
1708 rlp_buf.clear();
1709 let branch_node_ref =
1710 BranchNodeRef::new(&buffers.branch_value_stack_buf, *state_mask);
1711 let rlp_node = branch_node_ref.rlp(rlp_buf);
1712 *hash = rlp_node.as_hash();
1713
1714 let store_in_db_trie_value = if let Some(updates) =
1717 self.updates.as_mut().filter(|_| retain_updates && !path.is_empty())
1718 {
1719 let store_in_db_trie = !tree_mask.is_empty() || !hash_mask.is_empty();
1720 if store_in_db_trie {
1721 hashes.reverse();
1724 let branch_node = BranchNodeCompact::new(
1725 *state_mask,
1726 tree_mask,
1727 hash_mask,
1728 hashes,
1729 hash.filter(|_| path.is_empty()),
1730 );
1731 updates.updated_nodes.insert(path, branch_node);
1732 } else if self
1733 .branch_node_tree_masks
1734 .get(&path)
1735 .is_some_and(|mask| !mask.is_empty()) ||
1736 self.branch_node_hash_masks
1737 .get(&path)
1738 .is_some_and(|mask| !mask.is_empty())
1739 {
1740 updates.updated_nodes.remove(&path);
1744 updates.removed_nodes.insert(path);
1745 } else if self
1746 .branch_node_tree_masks
1747 .get(&path)
1748 .is_none_or(|mask| mask.is_empty()) &&
1749 self.branch_node_hash_masks
1750 .get(&path)
1751 .is_none_or(|mask| mask.is_empty())
1752 {
1753 updates.updated_nodes.remove(&path);
1756 }
1757
1758 store_in_db_trie
1759 } else {
1760 false
1761 };
1762 *store_in_db_trie = Some(store_in_db_trie_value);
1763
1764 (
1765 rlp_node,
1766 SparseNodeType::Branch { store_in_db_trie: Some(store_in_db_trie_value) },
1767 )
1768 }
1769 };
1770
1771 trace!(
1772 target: "trie::sparse",
1773 ?_starting_path,
1774 ?level,
1775 ?path,
1776 ?node,
1777 ?node_type,
1778 ?is_in_prefix_set,
1779 "Added node to rlp node stack"
1780 );
1781
1782 buffers.rlp_node_stack.push(RlpNodeStackItem { path, rlp_node, node_type });
1783 }
1784
1785 debug_assert_eq!(buffers.rlp_node_stack.len(), 1);
1786 buffers.rlp_node_stack.pop().unwrap().rlp_node
1787 }
1788}
1789
1790#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1792pub enum SparseNodeType {
1793 Empty,
1795 Hash,
1797 Leaf,
1799 Extension {
1801 store_in_db_trie: Option<bool>,
1803 },
1804 Branch {
1806 store_in_db_trie: Option<bool>,
1808 },
1809}
1810
1811impl SparseNodeType {
1812 pub const fn is_hash(&self) -> bool {
1814 matches!(self, Self::Hash)
1815 }
1816
1817 pub const fn is_branch(&self) -> bool {
1819 matches!(self, Self::Branch { .. })
1820 }
1821
1822 pub const fn store_in_db_trie(&self) -> Option<bool> {
1824 match *self {
1825 Self::Extension { store_in_db_trie } | Self::Branch { store_in_db_trie } => {
1826 store_in_db_trie
1827 }
1828 _ => None,
1829 }
1830 }
1831}
1832
1833#[derive(Debug, Clone, PartialEq, Eq)]
1835pub enum SparseNode {
1836 Empty,
1838 Hash(B256),
1840 Leaf {
1842 key: Nibbles,
1844 hash: Option<B256>,
1847 },
1848 Extension {
1850 key: Nibbles,
1852 hash: Option<B256>,
1857 store_in_db_trie: Option<bool>,
1862 },
1863 Branch {
1865 state_mask: TrieMask,
1867 hash: Option<B256>,
1872 store_in_db_trie: Option<bool>,
1877 },
1878}
1879
1880impl SparseNode {
1881 pub fn from_node(node: TrieNode) -> Self {
1883 match node {
1884 TrieNode::EmptyRoot => Self::Empty,
1885 TrieNode::Leaf(leaf) => Self::new_leaf(leaf.key),
1886 TrieNode::Extension(ext) => Self::new_ext(ext.key),
1887 TrieNode::Branch(branch) => Self::new_branch(branch.state_mask),
1888 }
1889 }
1890
1891 pub const fn new_branch(state_mask: TrieMask) -> Self {
1893 Self::Branch { state_mask, hash: None, store_in_db_trie: None }
1894 }
1895
1896 pub const fn new_split_branch(bit_a: u8, bit_b: u8) -> Self {
1898 let state_mask = TrieMask::new(
1899 (1u16 << bit_a) | (1u16 << bit_b),
1901 );
1902 Self::Branch { state_mask, hash: None, store_in_db_trie: None }
1903 }
1904
1905 pub const fn new_ext(key: Nibbles) -> Self {
1907 Self::Extension { key, hash: None, store_in_db_trie: None }
1908 }
1909
1910 pub const fn new_leaf(key: Nibbles) -> Self {
1912 Self::Leaf { key, hash: None }
1913 }
1914
1915 pub const fn is_hash(&self) -> bool {
1917 matches!(self, Self::Hash(_))
1918 }
1919
1920 pub const fn hash(&self) -> Option<B256> {
1922 match self {
1923 Self::Empty => None,
1924 Self::Hash(hash) => Some(*hash),
1925 Self::Leaf { hash, .. } | Self::Extension { hash, .. } | Self::Branch { hash, .. } => {
1926 *hash
1927 }
1928 }
1929 }
1930
1931 #[cfg(any(test, feature = "test-utils"))]
1935 pub const fn set_hash(&mut self, new_hash: Option<B256>) {
1936 match self {
1937 Self::Empty | Self::Hash(_) => {
1938 }
1940 Self::Leaf { hash, .. } | Self::Extension { hash, .. } | Self::Branch { hash, .. } => {
1941 *hash = new_hash;
1942 }
1943 }
1944 }
1945}
1946
1947#[derive(Debug)]
1950struct RemovedSparseNode {
1951 path: Nibbles,
1953 node: SparseNode,
1955 unset_branch_nibble: Option<u8>,
1964}
1965
1966#[derive(Debug, Default)]
1970pub struct RlpNodeBuffers {
1971 path_stack: Vec<RlpNodePathStackItem>,
1973 rlp_node_stack: Vec<RlpNodeStackItem>,
1975 branch_child_buf: SmallVec<[Nibbles; 16]>,
1977 branch_value_stack_buf: SmallVec<[RlpNode; 16]>,
1979}
1980
1981impl RlpNodeBuffers {
1982 fn new_with_root_path() -> Self {
1984 Self {
1985 path_stack: vec![RlpNodePathStackItem {
1986 level: 0,
1987 path: Nibbles::default(),
1988 is_in_prefix_set: None,
1989 }],
1990 rlp_node_stack: Vec::new(),
1991 branch_child_buf: SmallVec::<[Nibbles; 16]>::new_const(),
1992 branch_value_stack_buf: SmallVec::<[RlpNode; 16]>::new_const(),
1993 }
1994 }
1995}
1996
1997#[derive(Clone, PartialEq, Eq, Debug)]
1999pub struct RlpNodePathStackItem {
2000 pub level: usize,
2002 pub path: Nibbles,
2004 pub is_in_prefix_set: Option<bool>,
2006}
2007
2008#[derive(Clone, PartialEq, Eq, Debug)]
2010pub struct RlpNodeStackItem {
2011 pub path: Nibbles,
2013 pub rlp_node: RlpNode,
2015 pub node_type: SparseNodeType,
2017}
2018
2019impl SparseTrieUpdates {
2020 pub fn wiped() -> Self {
2022 Self { wiped: true, ..Default::default() }
2023 }
2024
2025 pub fn clear(&mut self) {
2029 self.updated_nodes.clear();
2030 self.removed_nodes.clear();
2031 self.wiped = false;
2032 }
2033
2034 pub fn extend(&mut self, other: Self) {
2036 self.updated_nodes.extend(other.updated_nodes);
2037 self.removed_nodes.extend(other.removed_nodes);
2038 self.wiped |= other.wiped;
2039 }
2040}
2041
2042#[cfg(test)]
2043mod find_leaf_tests {
2044 use super::*;
2045 use crate::provider::DefaultTrieNodeProvider;
2046 use alloy_rlp::Encodable;
2047 use assert_matches::assert_matches;
2048 use reth_primitives_traits::Account;
2049 use reth_trie_common::LeafNode;
2050
2051 fn encode_value(nonce: u64) -> Vec<u8> {
2053 let account = Account { nonce, ..Default::default() };
2054 let trie_account = account.into_trie_account(EMPTY_ROOT_HASH);
2055 let mut buf = Vec::new();
2056 trie_account.encode(&mut buf);
2057 buf
2058 }
2059
2060 const VALUE_A: fn() -> Vec<u8> = || encode_value(1);
2061 const VALUE_B: fn() -> Vec<u8> = || encode_value(2);
2062
2063 #[test]
2064 fn find_leaf_existing_leaf() {
2065 let provider = DefaultTrieNodeProvider;
2067 let mut sparse = SerialSparseTrie::default();
2068 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
2069 let value = b"test_value".to_vec();
2070
2071 sparse.update_leaf(path, value.clone(), &provider).unwrap();
2072
2073 let result = sparse.find_leaf(&path, None);
2075 assert_matches!(result, Ok(LeafLookup::Exists));
2076
2077 let result = sparse.find_leaf(&path, Some(&value));
2079 assert_matches!(result, Ok(LeafLookup::Exists));
2080 }
2081
2082 #[test]
2083 fn find_leaf_value_mismatch() {
2084 let provider = DefaultTrieNodeProvider;
2086 let mut sparse = SerialSparseTrie::default();
2087 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
2088 let value = b"test_value".to_vec();
2089 let wrong_value = b"wrong_value".to_vec();
2090
2091 sparse.update_leaf(path, value, &provider).unwrap();
2092
2093 let result = sparse.find_leaf(&path, Some(&wrong_value));
2095 assert_matches!(
2096 result,
2097 Err(LeafLookupError::ValueMismatch { path: p, expected: Some(e), actual: _a }) if p == path && e == wrong_value
2098 );
2099 }
2100
2101 #[test]
2102 fn find_leaf_not_found_empty_trie() {
2103 let sparse = SerialSparseTrie::default();
2105 let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]);
2106
2107 let result = sparse.find_leaf(&path, None);
2109 assert_matches!(result, Ok(LeafLookup::NonExistent));
2110 }
2111
2112 #[test]
2113 fn find_leaf_empty_trie() {
2114 let sparse = SerialSparseTrie::default();
2115 let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2116
2117 let result = sparse.find_leaf(&path, None);
2118 assert_matches!(result, Ok(LeafLookup::NonExistent));
2119 }
2120
2121 #[test]
2122 fn find_leaf_exists_no_value_check() {
2123 let provider = DefaultTrieNodeProvider;
2124 let mut sparse = SerialSparseTrie::default();
2125 let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2126 sparse.update_leaf(path, VALUE_A(), &provider).unwrap();
2127
2128 let result = sparse.find_leaf(&path, None);
2129 assert_matches!(result, Ok(LeafLookup::Exists));
2130 }
2131
2132 #[test]
2133 fn find_leaf_exists_with_value_check_ok() {
2134 let provider = DefaultTrieNodeProvider;
2135 let mut sparse = SerialSparseTrie::default();
2136 let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2137 let value = VALUE_A();
2138 sparse.update_leaf(path, value.clone(), &provider).unwrap();
2139
2140 let result = sparse.find_leaf(&path, Some(&value));
2141 assert_matches!(result, Ok(LeafLookup::Exists));
2142 }
2143
2144 #[test]
2145 fn find_leaf_exclusion_branch_divergence() {
2146 let provider = DefaultTrieNodeProvider;
2147 let mut sparse = SerialSparseTrie::default();
2148 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();
2153 sparse.update_leaf(path2, VALUE_B(), &provider).unwrap();
2154
2155 let result = sparse.find_leaf(&search_path, None);
2156 assert_matches!(result, Ok(LeafLookup::NonExistent));
2157 }
2158
2159 #[test]
2160 fn find_leaf_exclusion_extension_divergence() {
2161 let provider = DefaultTrieNodeProvider;
2162 let mut sparse = SerialSparseTrie::default();
2163 let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]);
2165 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x7, 0x8]);
2167
2168 sparse.update_leaf(path1, VALUE_A(), &provider).unwrap();
2169
2170 let result = sparse.find_leaf(&search_path, None);
2171 assert_matches!(result, Ok(LeafLookup::NonExistent));
2172 }
2173
2174 #[test]
2175 fn find_leaf_exclusion_leaf_divergence() {
2176 let provider = DefaultTrieNodeProvider;
2177 let mut sparse = SerialSparseTrie::default();
2178 let existing_leaf_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2179 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]);
2180
2181 sparse.update_leaf(existing_leaf_path, VALUE_A(), &provider).unwrap();
2182
2183 let result = sparse.find_leaf(&search_path, None);
2184 assert_matches!(result, Ok(LeafLookup::NonExistent));
2185 }
2186
2187 #[test]
2188 fn find_leaf_exclusion_path_ends_at_branch() {
2189 let provider = DefaultTrieNodeProvider;
2190 let mut sparse = SerialSparseTrie::default();
2191 let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); let path2 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x5, 0x6]);
2193 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2]); sparse.update_leaf(path1, VALUE_A(), &provider).unwrap();
2196 sparse.update_leaf(path2, VALUE_B(), &provider).unwrap();
2197
2198 let result = sparse.find_leaf(&search_path, None);
2199 assert_matches!(result, Ok(LeafLookup::NonExistent));
2200 }
2201
2202 #[test]
2203 fn find_leaf_error_trie_node_at_leaf_path() {
2204 let blinded_hash = B256::repeat_byte(0xBB);
2206 let leaf_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2207
2208 let mut nodes = alloy_primitives::map::HashMap::default();
2209 nodes.insert(
2211 Nibbles::default(),
2212 SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x1, 0x2])),
2213 ); nodes.insert(
2215 Nibbles::from_nibbles_unchecked([0x1, 0x2]),
2216 SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x3])),
2217 ); nodes.insert(
2219 Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3]),
2220 SparseNode::new_branch(TrieMask::new(0b10000)),
2221 ); nodes.insert(leaf_path, SparseNode::Hash(blinded_hash)); let sparse = SerialSparseTrie {
2225 nodes,
2226 branch_node_tree_masks: Default::default(),
2227 branch_node_hash_masks: Default::default(),
2228 values: Default::default(),
2230 prefix_set: Default::default(),
2231 updates: None,
2232 rlp_buf: Vec::new(),
2233 };
2234
2235 let result = sparse.find_leaf(&leaf_path, None);
2236
2237 assert_matches!(result, Err(LeafLookupError::BlindedNode { path, hash })
2239 if path == leaf_path && hash == blinded_hash
2240 );
2241 }
2242
2243 #[test]
2244 fn find_leaf_error_trie_node() {
2245 let blinded_hash = B256::repeat_byte(0xAA);
2246 let path_to_blind = Nibbles::from_nibbles_unchecked([0x1]);
2247 let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]);
2248
2249 let mut nodes = HashMap::default();
2250
2251 let state_mask = TrieMask::new(0b100010);
2254 nodes.insert(Nibbles::default(), SparseNode::new_branch(state_mask));
2255
2256 nodes.insert(path_to_blind, SparseNode::Hash(blinded_hash));
2257 let path_revealed = Nibbles::from_nibbles_unchecked([0x5]);
2258 let path_revealed_leaf = Nibbles::from_nibbles_unchecked([0x5, 0x6, 0x7, 0x8]);
2259 nodes.insert(
2260 path_revealed,
2261 SparseNode::new_leaf(Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8])),
2262 );
2263
2264 let mut values = HashMap::default();
2265 values.insert(path_revealed_leaf, VALUE_A());
2266
2267 let sparse = SerialSparseTrie {
2268 nodes,
2269 branch_node_tree_masks: Default::default(),
2270 branch_node_hash_masks: Default::default(),
2271 values,
2272 prefix_set: Default::default(),
2273 updates: None,
2274 rlp_buf: Vec::new(),
2275 };
2276
2277 let result = sparse.find_leaf(&search_path, None);
2278
2279 assert_matches!(result, Err(LeafLookupError::BlindedNode { path, hash })
2281 if path == path_to_blind && hash == blinded_hash
2282 );
2283 }
2284
2285 #[test]
2286 fn find_leaf_error_trie_node_via_reveal() {
2287 let blinded_hash = B256::repeat_byte(0xAA);
2288 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]);
2292 let revealed_leaf_suffix = Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8]);
2293 let revealed_leaf_full_path = Nibbles::from_nibbles_unchecked([0x5, 0x6, 0x7, 0x8]);
2294 let revealed_value = VALUE_A();
2295
2296 let rlp_node_child1 = RlpNode::word_rlp(&blinded_hash); let leaf_node_child5 = LeafNode::new(revealed_leaf_suffix, revealed_value.clone());
2300 let leaf_node_child5_rlp_buf = alloy_rlp::encode(&leaf_node_child5);
2301 let hash_of_child5 = keccak256(&leaf_node_child5_rlp_buf);
2302 let rlp_node_child5 = RlpNode::word_rlp(&hash_of_child5);
2303
2304 let root_branch_node = reth_trie_common::BranchNode::new(
2307 vec![rlp_node_child1, rlp_node_child5], TrieMask::new(0b100010), );
2310 let root_trie_node = TrieNode::Branch(root_branch_node);
2311
2312 let mut sparse = SerialSparseTrie::from_root(root_trie_node, TrieMasks::none(), false)
2315 .expect("Failed to create trie from root");
2316
2317 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 );
2320 assert!(sparse.nodes.get(&revealed_leaf_prefix).unwrap().is_hash()); assert!(sparse.values.is_empty());
2322
2323 sparse
2325 .reveal_node(revealed_leaf_prefix, TrieNode::Leaf(leaf_node_child5), TrieMasks::none())
2326 .expect("Failed to reveal leaf node");
2327
2328 assert_matches!(sparse.nodes.get(&Nibbles::default()), Some(SparseNode::Branch { state_mask, .. }) if *state_mask == TrieMask::new(0b100010));
2330 assert_matches!(sparse.nodes.get(&path_to_blind), Some(SparseNode::Hash(h)) if *h == blinded_hash );
2331 assert_matches!(sparse.nodes.get(&revealed_leaf_prefix), Some(SparseNode::Leaf { key, .. }) if *key == revealed_leaf_suffix);
2332 assert_eq!(sparse.values.get(&revealed_leaf_full_path), Some(&revealed_value));
2333
2334 let result = sparse.find_leaf(&search_path, None);
2335
2336 assert_matches!(result, Err(LeafLookupError::BlindedNode { path, hash })
2339 if path == path_to_blind && hash == blinded_hash
2340 );
2341 }
2342}
2343
2344#[cfg(test)]
2345mod tests {
2346 use super::*;
2347 use crate::provider::DefaultTrieNodeProvider;
2348 use alloy_primitives::{map::B256Set, U256};
2349 use alloy_rlp::Encodable;
2350 use assert_matches::assert_matches;
2351 use itertools::Itertools;
2352 use prop::sample::SizeRange;
2353 use proptest::prelude::*;
2354 use proptest_arbitrary_interop::arb;
2355 use reth_primitives_traits::Account;
2356 use reth_provider::{test_utils::create_test_provider_factory, TrieWriter};
2357 use reth_trie::{
2358 hashed_cursor::{noop::NoopHashedCursor, HashedPostStateCursor},
2359 node_iter::{TrieElement, TrieNodeIter},
2360 trie_cursor::{noop::NoopAccountTrieCursor, TrieCursor, TrieCursorFactory},
2361 walker::TrieWalker,
2362 BranchNode, ExtensionNode, HashedPostState, LeafNode,
2363 };
2364 use reth_trie_common::{
2365 proof::{ProofNodes, ProofRetainer},
2366 updates::TrieUpdates,
2367 HashBuilder,
2368 };
2369 use reth_trie_db::DatabaseTrieCursorFactory;
2370 use std::collections::{BTreeMap, BTreeSet};
2371
2372 fn pad_nibbles_left(nibbles: Nibbles) -> Nibbles {
2374 let mut base =
2375 Nibbles::from_nibbles_unchecked(vec![0; B256::len_bytes() * 2 - nibbles.len()]);
2376 base.extend(&nibbles);
2377 base
2378 }
2379
2380 fn pad_nibbles_right(mut nibbles: Nibbles) -> Nibbles {
2382 nibbles.extend(&Nibbles::from_nibbles_unchecked(vec![
2383 0;
2384 B256::len_bytes() * 2 - nibbles.len()
2385 ]));
2386 nibbles
2387 }
2388
2389 fn run_hash_builder(
2394 state: impl IntoIterator<Item = (Nibbles, Account)> + Clone,
2395 trie_cursor: impl TrieCursor,
2396 destroyed_accounts: B256Set,
2397 proof_targets: impl IntoIterator<Item = Nibbles>,
2398 ) -> (B256, TrieUpdates, ProofNodes, HashMap<Nibbles, TrieMask>, HashMap<Nibbles, TrieMask>)
2399 {
2400 let mut account_rlp = Vec::new();
2401
2402 let mut hash_builder = HashBuilder::default()
2403 .with_updates(true)
2404 .with_proof_retainer(ProofRetainer::from_iter(proof_targets));
2405
2406 let mut prefix_set = PrefixSetMut::default();
2407 prefix_set.extend_keys(state.clone().into_iter().map(|(nibbles, _)| nibbles));
2408 prefix_set.extend_keys(destroyed_accounts.iter().map(Nibbles::unpack));
2409 let walker = TrieWalker::<_>::state_trie(trie_cursor, prefix_set.freeze())
2410 .with_deletions_retained(true);
2411 let hashed_post_state = HashedPostState::default()
2412 .with_accounts(state.into_iter().map(|(nibbles, account)| {
2413 (nibbles.pack().into_inner().unwrap().into(), Some(account))
2414 }))
2415 .into_sorted();
2416 let mut node_iter = TrieNodeIter::state_trie(
2417 walker,
2418 HashedPostStateCursor::new_account(
2419 NoopHashedCursor::<Account>::default(),
2420 &hashed_post_state,
2421 ),
2422 );
2423
2424 while let Some(node) = node_iter.try_next().unwrap() {
2425 match node {
2426 TrieElement::Branch(branch) => {
2427 hash_builder.add_branch(branch.key, branch.value, branch.children_are_in_trie);
2428 }
2429 TrieElement::Leaf(key, account) => {
2430 let account = account.into_trie_account(EMPTY_ROOT_HASH);
2431 account.encode(&mut account_rlp);
2432
2433 hash_builder.add_leaf(Nibbles::unpack(key), &account_rlp);
2434 account_rlp.clear();
2435 }
2436 }
2437 }
2438 let root = hash_builder.root();
2439 let proof_nodes = hash_builder.take_proof_nodes();
2440 let branch_node_hash_masks = hash_builder
2441 .updated_branch_nodes
2442 .clone()
2443 .unwrap_or_default()
2444 .iter()
2445 .map(|(path, node)| (*path, node.hash_mask))
2446 .collect();
2447 let branch_node_tree_masks = hash_builder
2448 .updated_branch_nodes
2449 .clone()
2450 .unwrap_or_default()
2451 .iter()
2452 .map(|(path, node)| (*path, node.tree_mask))
2453 .collect();
2454
2455 let mut trie_updates = TrieUpdates::default();
2456 let removed_keys = node_iter.walker.take_removed_keys();
2457 trie_updates.finalize(hash_builder, removed_keys, destroyed_accounts);
2458
2459 (root, trie_updates, proof_nodes, branch_node_hash_masks, branch_node_tree_masks)
2460 }
2461
2462 fn assert_eq_sparse_trie_proof_nodes(sparse_trie: &SerialSparseTrie, proof_nodes: ProofNodes) {
2464 let proof_nodes = proof_nodes
2465 .into_nodes_sorted()
2466 .into_iter()
2467 .map(|(path, node)| (path, TrieNode::decode(&mut node.as_ref()).unwrap()));
2468
2469 let sparse_nodes = sparse_trie.nodes.iter().sorted_by_key(|(path, _)| *path);
2470
2471 for ((proof_node_path, proof_node), (sparse_node_path, sparse_node)) in
2472 proof_nodes.zip(sparse_nodes)
2473 {
2474 assert_eq!(&proof_node_path, sparse_node_path);
2475
2476 let equals = match (&proof_node, &sparse_node) {
2477 (TrieNode::EmptyRoot, SparseNode::Empty) => true,
2479 (
2481 TrieNode::Branch(BranchNode { state_mask: proof_state_mask, .. }),
2482 SparseNode::Branch { state_mask: sparse_state_mask, .. },
2483 ) => proof_state_mask == sparse_state_mask,
2484 (
2486 TrieNode::Extension(ExtensionNode { key: proof_key, .. }),
2487 SparseNode::Extension { key: sparse_key, .. },
2488 ) |
2489 (
2491 TrieNode::Leaf(LeafNode { key: proof_key, .. }),
2492 SparseNode::Leaf { key: sparse_key, .. },
2493 ) => proof_key == sparse_key,
2494 (_, SparseNode::Empty | SparseNode::Hash(_)) => continue,
2496 _ => false,
2497 };
2498 assert!(
2499 equals,
2500 "path: {proof_node_path:?}\nproof node: {proof_node:?}\nsparse node: {sparse_node:?}"
2501 );
2502 }
2503 }
2504
2505 #[test]
2506 fn sparse_trie_is_blind() {
2507 assert!(SparseTrie::<SerialSparseTrie>::blind().is_blind());
2508 assert!(!SparseTrie::<SerialSparseTrie>::revealed_empty().is_blind());
2509 }
2510
2511 #[test]
2512 fn sparse_trie_empty_update_one() {
2513 let key = Nibbles::unpack(B256::with_last_byte(42));
2514 let value = || Account::default();
2515 let value_encoded = || {
2516 let mut account_rlp = Vec::new();
2517 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2518 account_rlp
2519 };
2520
2521 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2522 run_hash_builder(
2523 [(key, value())],
2524 NoopAccountTrieCursor::default(),
2525 Default::default(),
2526 [key],
2527 );
2528
2529 let provider = DefaultTrieNodeProvider;
2530 let mut sparse = SerialSparseTrie::default().with_updates(true);
2531 sparse.update_leaf(key, value_encoded(), &provider).unwrap();
2532 let sparse_root = sparse.root();
2533 let sparse_updates = sparse.take_updates();
2534
2535 assert_eq!(sparse_root, hash_builder_root);
2536 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2537 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2538 }
2539
2540 #[test]
2541 fn sparse_trie_empty_update_multiple_lower_nibbles() {
2542 reth_tracing::init_test_tracing();
2543
2544 let paths = (0..=16).map(|b| Nibbles::unpack(B256::with_last_byte(b))).collect::<Vec<_>>();
2545 let value = || Account::default();
2546 let value_encoded = || {
2547 let mut account_rlp = Vec::new();
2548 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2549 account_rlp
2550 };
2551
2552 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2553 run_hash_builder(
2554 paths.iter().copied().zip(std::iter::repeat_with(value)),
2555 NoopAccountTrieCursor::default(),
2556 Default::default(),
2557 paths.clone(),
2558 );
2559
2560 let provider = DefaultTrieNodeProvider;
2561 let mut sparse = SerialSparseTrie::default().with_updates(true);
2562 for path in &paths {
2563 sparse.update_leaf(*path, value_encoded(), &provider).unwrap();
2564 }
2565 let sparse_root = sparse.root();
2566 let sparse_updates = sparse.take_updates();
2567
2568 assert_eq!(sparse_root, hash_builder_root);
2569 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2570 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2571 }
2572
2573 #[test]
2574 fn sparse_trie_empty_update_multiple_upper_nibbles() {
2575 let paths = (239..=255).map(|b| Nibbles::unpack(B256::repeat_byte(b))).collect::<Vec<_>>();
2576 let value = || Account::default();
2577 let value_encoded = || {
2578 let mut account_rlp = Vec::new();
2579 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2580 account_rlp
2581 };
2582
2583 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2584 run_hash_builder(
2585 paths.iter().copied().zip(std::iter::repeat_with(value)),
2586 NoopAccountTrieCursor::default(),
2587 Default::default(),
2588 paths.clone(),
2589 );
2590
2591 let provider = DefaultTrieNodeProvider;
2592 let mut sparse = SerialSparseTrie::default().with_updates(true);
2593 for path in &paths {
2594 sparse.update_leaf(*path, value_encoded(), &provider).unwrap();
2595 }
2596 let sparse_root = sparse.root();
2597 let sparse_updates = sparse.take_updates();
2598
2599 assert_eq!(sparse_root, hash_builder_root);
2600 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2601 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2602 }
2603
2604 #[test]
2605 fn sparse_trie_empty_update_multiple() {
2606 let paths = (0..=255)
2607 .map(|b| {
2608 Nibbles::unpack(if b % 2 == 0 {
2609 B256::repeat_byte(b)
2610 } else {
2611 B256::with_last_byte(b)
2612 })
2613 })
2614 .collect::<Vec<_>>();
2615 let value = || Account::default();
2616 let value_encoded = || {
2617 let mut account_rlp = Vec::new();
2618 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2619 account_rlp
2620 };
2621
2622 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2623 run_hash_builder(
2624 paths.iter().sorted_unstable().copied().zip(std::iter::repeat_with(value)),
2625 NoopAccountTrieCursor::default(),
2626 Default::default(),
2627 paths.clone(),
2628 );
2629
2630 let provider = DefaultTrieNodeProvider;
2631 let mut sparse = SerialSparseTrie::default().with_updates(true);
2632 for path in &paths {
2633 sparse.update_leaf(*path, value_encoded(), &provider).unwrap();
2634 }
2635 let sparse_root = sparse.root();
2636 let sparse_updates = sparse.take_updates();
2637
2638 assert_eq!(sparse_root, hash_builder_root);
2639 pretty_assertions::assert_eq!(
2640 BTreeMap::from_iter(sparse_updates.updated_nodes),
2641 BTreeMap::from_iter(hash_builder_updates.account_nodes)
2642 );
2643 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2644 }
2645
2646 #[test]
2647 fn sparse_trie_empty_update_repeated() {
2648 let paths = (0..=255).map(|b| Nibbles::unpack(B256::repeat_byte(b))).collect::<Vec<_>>();
2649 let old_value = Account { nonce: 1, ..Default::default() };
2650 let old_value_encoded = {
2651 let mut account_rlp = Vec::new();
2652 old_value.into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2653 account_rlp
2654 };
2655 let new_value = Account { nonce: 2, ..Default::default() };
2656 let new_value_encoded = {
2657 let mut account_rlp = Vec::new();
2658 new_value.into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
2659 account_rlp
2660 };
2661
2662 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2663 run_hash_builder(
2664 paths.iter().copied().zip(std::iter::repeat_with(|| old_value)),
2665 NoopAccountTrieCursor::default(),
2666 Default::default(),
2667 paths.clone(),
2668 );
2669
2670 let provider = DefaultTrieNodeProvider;
2671 let mut sparse = SerialSparseTrie::default().with_updates(true);
2672 for path in &paths {
2673 sparse.update_leaf(*path, old_value_encoded.clone(), &provider).unwrap();
2674 }
2675 let sparse_root = sparse.root();
2676 let sparse_updates = sparse.updates_ref();
2677
2678 assert_eq!(sparse_root, hash_builder_root);
2679 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2680 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2681
2682 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
2683 run_hash_builder(
2684 paths.iter().copied().zip(std::iter::repeat_with(|| new_value)),
2685 NoopAccountTrieCursor::default(),
2686 Default::default(),
2687 paths.clone(),
2688 );
2689
2690 for path in &paths {
2691 sparse.update_leaf(*path, new_value_encoded.clone(), &provider).unwrap();
2692 }
2693 let sparse_root = sparse.root();
2694 let sparse_updates = sparse.take_updates();
2695
2696 assert_eq!(sparse_root, hash_builder_root);
2697 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2698 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2699 }
2700
2701 #[test]
2702 fn sparse_trie_remove_leaf() {
2703 reth_tracing::init_test_tracing();
2704
2705 let provider = DefaultTrieNodeProvider;
2706 let mut sparse = SerialSparseTrie::default();
2707
2708 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
2709
2710 sparse
2711 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
2712 .unwrap();
2713 sparse
2714 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
2715 .unwrap();
2716 sparse
2717 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
2718 .unwrap();
2719 sparse
2720 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
2721 .unwrap();
2722 sparse
2723 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
2724 .unwrap();
2725 sparse
2726 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
2727 .unwrap();
2728
2729 pretty_assertions::assert_eq!(
2742 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2743 BTreeMap::from_iter([
2744 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2745 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1101.into())),
2746 (
2747 Nibbles::from_nibbles([0x5, 0x0]),
2748 SparseNode::new_ext(Nibbles::from_nibbles([0x2, 0x3]))
2749 ),
2750 (
2751 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3]),
2752 SparseNode::new_branch(0b1010.into())
2753 ),
2754 (
2755 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]),
2756 SparseNode::new_leaf(Nibbles::default())
2757 ),
2758 (
2759 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]),
2760 SparseNode::new_leaf(Nibbles::default())
2761 ),
2762 (
2763 Nibbles::from_nibbles([0x5, 0x2]),
2764 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x1, 0x3]))
2765 ),
2766 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
2767 (
2768 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
2769 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
2770 ),
2771 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2772 (
2773 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2774 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2775 ),
2776 (
2777 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2778 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2779 )
2780 ])
2781 );
2782
2783 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), &provider).unwrap();
2784
2785 pretty_assertions::assert_eq!(
2797 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2798 BTreeMap::from_iter([
2799 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2800 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2801 (
2802 Nibbles::from_nibbles([0x5, 0x0]),
2803 SparseNode::new_ext(Nibbles::from_nibbles([0x2, 0x3]))
2804 ),
2805 (
2806 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3]),
2807 SparseNode::new_branch(0b1010.into())
2808 ),
2809 (
2810 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]),
2811 SparseNode::new_leaf(Nibbles::default())
2812 ),
2813 (
2814 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]),
2815 SparseNode::new_leaf(Nibbles::default())
2816 ),
2817 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
2818 (
2819 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
2820 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
2821 ),
2822 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2823 (
2824 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2825 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2826 ),
2827 (
2828 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2829 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2830 )
2831 ])
2832 );
2833
2834 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), &provider).unwrap();
2835
2836 pretty_assertions::assert_eq!(
2845 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2846 BTreeMap::from_iter([
2847 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2848 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2849 (
2850 Nibbles::from_nibbles([0x5, 0x0]),
2851 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
2852 ),
2853 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
2854 (
2855 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
2856 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
2857 ),
2858 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2859 (
2860 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2861 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2862 ),
2863 (
2864 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2865 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2866 )
2867 ])
2868 );
2869
2870 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), &provider).unwrap();
2871
2872 pretty_assertions::assert_eq!(
2879 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2880 BTreeMap::from_iter([
2881 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2882 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2883 (
2884 Nibbles::from_nibbles([0x5, 0x0]),
2885 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
2886 ),
2887 (
2888 Nibbles::from_nibbles([0x5, 0x3]),
2889 SparseNode::new_ext(Nibbles::from_nibbles([0x3]))
2890 ),
2891 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
2892 (
2893 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
2894 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
2895 ),
2896 (
2897 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
2898 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
2899 )
2900 ])
2901 );
2902
2903 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), &provider).unwrap();
2904
2905 pretty_assertions::assert_eq!(
2910 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2911 BTreeMap::from_iter([
2912 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
2913 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
2914 (
2915 Nibbles::from_nibbles([0x5, 0x0]),
2916 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
2917 ),
2918 (
2919 Nibbles::from_nibbles([0x5, 0x3]),
2920 SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x0, 0x2]))
2921 ),
2922 ])
2923 );
2924
2925 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), &provider).unwrap();
2926
2927 pretty_assertions::assert_eq!(
2929 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2930 BTreeMap::from_iter([(
2931 Nibbles::default(),
2932 SparseNode::new_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]))
2933 ),])
2934 );
2935
2936 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), &provider).unwrap();
2937
2938 pretty_assertions::assert_eq!(
2940 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
2941 BTreeMap::from_iter([(Nibbles::default(), SparseNode::Empty)])
2942 );
2943 }
2944
2945 #[test]
2946 fn sparse_trie_remove_leaf_blinded() {
2947 let leaf = LeafNode::new(
2948 Nibbles::default(),
2949 alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(),
2950 );
2951 let branch = TrieNode::Branch(BranchNode::new(
2952 vec![
2953 RlpNode::word_rlp(&B256::repeat_byte(1)),
2954 RlpNode::from_raw_rlp(&alloy_rlp::encode(leaf.clone())).unwrap(),
2955 ],
2956 TrieMask::new(0b11),
2957 ));
2958
2959 let provider = DefaultTrieNodeProvider;
2960 let mut sparse = SerialSparseTrie::from_root(
2961 branch.clone(),
2962 TrieMasks { hash_mask: Some(TrieMask::new(0b01)), tree_mask: None },
2963 false,
2964 )
2965 .unwrap();
2966
2967 sparse
2973 .reveal_node(
2974 Nibbles::default(),
2975 branch,
2976 TrieMasks { hash_mask: None, tree_mask: Some(TrieMask::new(0b01)) },
2977 )
2978 .unwrap();
2979 sparse
2980 .reveal_node(Nibbles::from_nibbles([0x1]), TrieNode::Leaf(leaf), TrieMasks::none())
2981 .unwrap();
2982
2983 assert_matches!(
2985 sparse.remove_leaf(&Nibbles::from_nibbles([0x0]), &provider).map_err(|e| e.into_kind()),
2986 Err(SparseTrieErrorKind::BlindedNode { path, hash }) if path == Nibbles::from_nibbles([0x0]) && hash == B256::repeat_byte(1)
2987 );
2988 }
2989
2990 #[test]
2991 fn sparse_trie_remove_leaf_non_existent() {
2992 let leaf = LeafNode::new(
2993 Nibbles::default(),
2994 alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(),
2995 );
2996 let branch = TrieNode::Branch(BranchNode::new(
2997 vec![
2998 RlpNode::word_rlp(&B256::repeat_byte(1)),
2999 RlpNode::from_raw_rlp(&alloy_rlp::encode(leaf.clone())).unwrap(),
3000 ],
3001 TrieMask::new(0b11),
3002 ));
3003
3004 let provider = DefaultTrieNodeProvider;
3005 let mut sparse = SerialSparseTrie::from_root(
3006 branch.clone(),
3007 TrieMasks { hash_mask: Some(TrieMask::new(0b01)), tree_mask: None },
3008 false,
3009 )
3010 .unwrap();
3011
3012 sparse
3018 .reveal_node(
3019 Nibbles::default(),
3020 branch,
3021 TrieMasks { hash_mask: None, tree_mask: Some(TrieMask::new(0b01)) },
3022 )
3023 .unwrap();
3024 sparse
3025 .reveal_node(Nibbles::from_nibbles([0x1]), TrieNode::Leaf(leaf), TrieMasks::none())
3026 .unwrap();
3027
3028 let sparse_old = sparse.clone();
3030 assert_matches!(sparse.remove_leaf(&Nibbles::from_nibbles([0x2]), &provider), Ok(()));
3031 assert_eq!(sparse, sparse_old);
3032 }
3033
3034 #[test]
3035 fn sparse_trie_fuzz() {
3036 const KEY_NIBBLES_LEN: usize = 3;
3040
3041 fn test(updates: Vec<(BTreeMap<Nibbles, Account>, BTreeSet<Nibbles>)>) {
3042 {
3043 let mut state = BTreeMap::default();
3044 let default_provider = DefaultTrieNodeProvider;
3045 let provider_factory = create_test_provider_factory();
3046 let mut sparse = SerialSparseTrie::default().with_updates(true);
3047
3048 for (update, keys_to_delete) in updates {
3049 for (key, account) in update.clone() {
3051 let account = account.into_trie_account(EMPTY_ROOT_HASH);
3052 let mut account_rlp = Vec::new();
3053 account.encode(&mut account_rlp);
3054 sparse.update_leaf(key, account_rlp, &default_provider).unwrap();
3055 }
3056 let mut updated_sparse = sparse.clone();
3060 let sparse_root = updated_sparse.root();
3061 let sparse_updates = updated_sparse.take_updates();
3062
3063 state.extend(update);
3065 let provider = provider_factory.provider().unwrap();
3066 let trie_cursor = DatabaseTrieCursorFactory::new(provider.tx_ref());
3067 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
3068 run_hash_builder(
3069 state.clone(),
3070 trie_cursor.account_trie_cursor().unwrap(),
3071 Default::default(),
3072 state.keys().copied(),
3073 );
3074
3075 let hash_builder_account_nodes = hash_builder_updates.account_nodes.clone();
3077
3078 let provider_rw = provider_factory.provider_rw().unwrap();
3080 provider_rw.write_trie_updates(hash_builder_updates).unwrap();
3081 provider_rw.commit().unwrap();
3082
3083 assert_eq!(sparse_root, hash_builder_root);
3085 pretty_assertions::assert_eq!(
3087 BTreeMap::from_iter(sparse_updates.updated_nodes),
3088 BTreeMap::from_iter(hash_builder_account_nodes)
3089 );
3090 assert_eq_sparse_trie_proof_nodes(&updated_sparse, hash_builder_proof_nodes);
3092
3093 for key in &keys_to_delete {
3096 state.remove(key).unwrap();
3097 sparse.remove_leaf(key, &default_provider).unwrap();
3098 }
3099
3100 let mut updated_sparse = sparse.clone();
3104 let sparse_root = updated_sparse.root();
3105 let sparse_updates = updated_sparse.take_updates();
3106
3107 let provider = provider_factory.provider().unwrap();
3108 let trie_cursor = DatabaseTrieCursorFactory::new(provider.tx_ref());
3109 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _, _) =
3110 run_hash_builder(
3111 state.clone(),
3112 trie_cursor.account_trie_cursor().unwrap(),
3113 keys_to_delete
3114 .iter()
3115 .map(|nibbles| B256::from_slice(&nibbles.pack()))
3116 .collect(),
3117 state.keys().copied(),
3118 );
3119
3120 let hash_builder_account_nodes = hash_builder_updates.account_nodes.clone();
3122
3123 let provider_rw = provider_factory.provider_rw().unwrap();
3125 provider_rw.write_trie_updates(hash_builder_updates).unwrap();
3126 provider_rw.commit().unwrap();
3127
3128 assert_eq!(sparse_root, hash_builder_root);
3130 pretty_assertions::assert_eq!(
3132 BTreeMap::from_iter(sparse_updates.updated_nodes),
3133 BTreeMap::from_iter(hash_builder_account_nodes)
3134 );
3135 assert_eq_sparse_trie_proof_nodes(&updated_sparse, hash_builder_proof_nodes);
3137 }
3138 }
3139 }
3140
3141 fn transform_updates(
3142 updates: Vec<BTreeMap<Nibbles, Account>>,
3143 mut rng: impl rand::Rng,
3144 ) -> Vec<(BTreeMap<Nibbles, Account>, BTreeSet<Nibbles>)> {
3145 let mut keys = BTreeSet::new();
3146 updates
3147 .into_iter()
3148 .map(|update| {
3149 keys.extend(update.keys().copied());
3150
3151 let keys_to_delete_len = update.len() / 2;
3152 let keys_to_delete = (0..keys_to_delete_len)
3153 .map(|_| {
3154 let key =
3155 *rand::seq::IteratorRandom::choose(keys.iter(), &mut rng).unwrap();
3156 keys.take(&key).unwrap()
3157 })
3158 .collect();
3159
3160 (update, keys_to_delete)
3161 })
3162 .collect::<Vec<_>>()
3163 }
3164
3165 proptest!(ProptestConfig::with_cases(10), |(
3166 updates in proptest::collection::vec(
3167 proptest::collection::btree_map(
3168 any_with::<Nibbles>(SizeRange::new(KEY_NIBBLES_LEN..=KEY_NIBBLES_LEN)).prop_map(pad_nibbles_right),
3169 arb::<Account>(),
3170 1..50,
3171 ),
3172 1..50,
3173 ).prop_perturb(transform_updates)
3174 )| {
3175 test(updates)
3176 });
3177 }
3178
3179 #[test]
3191 fn sparse_trie_reveal_node_1() {
3192 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00]));
3193 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01]));
3194 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x02]));
3195 let value = || Account::default();
3196 let value_encoded = || {
3197 let mut account_rlp = Vec::new();
3198 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
3199 account_rlp
3200 };
3201
3202 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3204 run_hash_builder(
3205 [(key1(), value()), (key3(), value())],
3206 NoopAccountTrieCursor::default(),
3207 Default::default(),
3208 [Nibbles::default()],
3209 );
3210
3211 let provider = DefaultTrieNodeProvider;
3212 let mut sparse = SerialSparseTrie::from_root(
3213 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
3214 TrieMasks {
3215 hash_mask: branch_node_hash_masks.get(&Nibbles::default()).copied(),
3216 tree_mask: branch_node_tree_masks.get(&Nibbles::default()).copied(),
3217 },
3218 false,
3219 )
3220 .unwrap();
3221
3222 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3224 run_hash_builder(
3225 [(key1(), value()), (key3(), value())],
3226 NoopAccountTrieCursor::default(),
3227 Default::default(),
3228 [key1()],
3229 );
3230 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3231 let hash_mask = branch_node_hash_masks.get(&path).copied();
3232 let tree_mask = branch_node_tree_masks.get(&path).copied();
3233 sparse
3234 .reveal_node(
3235 path,
3236 TrieNode::decode(&mut &node[..]).unwrap(),
3237 TrieMasks { hash_mask, tree_mask },
3238 )
3239 .unwrap();
3240 }
3241
3242 assert_eq!(
3244 sparse.nodes.get(&Nibbles::default()),
3245 Some(&SparseNode::new_branch(0b101.into()))
3246 );
3247
3248 sparse.update_leaf(key2(), value_encoded(), &provider).unwrap();
3250
3251 assert_eq!(
3253 sparse.nodes.get(&Nibbles::default()),
3254 Some(&SparseNode::new_branch(0b111.into()))
3255 );
3256
3257 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3259 run_hash_builder(
3260 [(key1(), value()), (key3(), value())],
3261 NoopAccountTrieCursor::default(),
3262 Default::default(),
3263 [key3()],
3264 );
3265 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3266 let hash_mask = branch_node_hash_masks.get(&path).copied();
3267 let tree_mask = branch_node_tree_masks.get(&path).copied();
3268 sparse
3269 .reveal_node(
3270 path,
3271 TrieNode::decode(&mut &node[..]).unwrap(),
3272 TrieMasks { hash_mask, tree_mask },
3273 )
3274 .unwrap();
3275 }
3276
3277 assert_eq!(
3279 sparse.nodes.get(&Nibbles::default()),
3280 Some(&SparseNode::new_branch(0b111.into()))
3281 );
3282
3283 let (_, _, hash_builder_proof_nodes, _, _) = run_hash_builder(
3286 [(key1(), value()), (key2(), value()), (key3(), value())],
3287 NoopAccountTrieCursor::default(),
3288 Default::default(),
3289 [key1(), key2(), key3()],
3290 );
3291
3292 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
3293 }
3294
3295 #[test]
3306 fn sparse_trie_reveal_node_2() {
3307 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x00]));
3308 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x01]));
3309 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x02]));
3310 let value = || Account::default();
3311
3312 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3314 run_hash_builder(
3315 [(key1(), value()), (key2(), value()), (key3(), value())],
3316 NoopAccountTrieCursor::default(),
3317 Default::default(),
3318 [Nibbles::default()],
3319 );
3320
3321 let provider = DefaultTrieNodeProvider;
3322 let mut sparse = SerialSparseTrie::from_root(
3323 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
3324 TrieMasks {
3325 hash_mask: branch_node_hash_masks.get(&Nibbles::default()).copied(),
3326 tree_mask: branch_node_tree_masks.get(&Nibbles::default()).copied(),
3327 },
3328 false,
3329 )
3330 .unwrap();
3331
3332 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3335 run_hash_builder(
3336 [(key1(), value()), (key2(), value()), (key3(), value())],
3337 NoopAccountTrieCursor::default(),
3338 Default::default(),
3339 [key1(), Nibbles::from_nibbles_unchecked([0x01])],
3340 );
3341 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3342 let hash_mask = branch_node_hash_masks.get(&path).copied();
3343 let tree_mask = branch_node_tree_masks.get(&path).copied();
3344 sparse
3345 .reveal_node(
3346 path,
3347 TrieNode::decode(&mut &node[..]).unwrap(),
3348 TrieMasks { hash_mask, tree_mask },
3349 )
3350 .unwrap();
3351 }
3352
3353 assert_eq!(
3355 sparse.nodes.get(&Nibbles::default()),
3356 Some(&SparseNode::new_branch(0b11.into()))
3357 );
3358
3359 sparse.remove_leaf(&key1(), &provider).unwrap();
3361
3362 assert_eq!(
3364 sparse.nodes.get(&Nibbles::default()),
3365 Some(&SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x01])))
3366 );
3367
3368 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3370 run_hash_builder(
3371 [(key1(), value()), (key2(), value()), (key3(), value())],
3372 NoopAccountTrieCursor::default(),
3373 Default::default(),
3374 [key2()],
3375 );
3376 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3377 let hash_mask = branch_node_hash_masks.get(&path).copied();
3378 let tree_mask = branch_node_tree_masks.get(&path).copied();
3379 sparse
3380 .reveal_node(
3381 path,
3382 TrieNode::decode(&mut &node[..]).unwrap(),
3383 TrieMasks { hash_mask, tree_mask },
3384 )
3385 .unwrap();
3386 }
3387
3388 assert_eq!(
3390 sparse.nodes.get(&Nibbles::default()),
3391 Some(&SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x01])))
3392 );
3393 }
3394
3395 #[test]
3404 fn sparse_trie_reveal_node_3() {
3405 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x01]));
3406 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x02]));
3407 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x00]));
3408 let value = || Account::default();
3409 let value_encoded = || {
3410 let mut account_rlp = Vec::new();
3411 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
3412 account_rlp
3413 };
3414
3415 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3417 run_hash_builder(
3418 [(key1(), value()), (key2(), value())],
3419 NoopAccountTrieCursor::default(),
3420 Default::default(),
3421 [Nibbles::default()],
3422 );
3423
3424 let provider = DefaultTrieNodeProvider;
3425 let mut sparse = SerialSparseTrie::from_root(
3426 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
3427 TrieMasks {
3428 hash_mask: branch_node_hash_masks.get(&Nibbles::default()).copied(),
3429 tree_mask: branch_node_tree_masks.get(&Nibbles::default()).copied(),
3430 },
3431 false,
3432 )
3433 .unwrap();
3434
3435 assert_matches!(
3437 sparse.nodes.get(&Nibbles::default()),
3438 Some(SparseNode::Extension { key, hash: None, store_in_db_trie: None }) if *key == Nibbles::from_nibbles([0x00])
3439 );
3440
3441 sparse.update_leaf(key3(), value_encoded(), &provider).unwrap();
3443
3444 assert_matches!(
3446 sparse.nodes.get(&Nibbles::default()),
3447 Some(SparseNode::Branch { state_mask, hash: None, store_in_db_trie: None }) if *state_mask == TrieMask::new(0b11)
3448 );
3449
3450 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks, branch_node_tree_masks) =
3452 run_hash_builder(
3453 [(key1(), value()), (key2(), value())],
3454 NoopAccountTrieCursor::default(),
3455 Default::default(),
3456 [key1()],
3457 );
3458 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
3459 let hash_mask = branch_node_hash_masks.get(&path).copied();
3460 let tree_mask = branch_node_tree_masks.get(&path).copied();
3461 sparse
3462 .reveal_node(
3463 path,
3464 TrieNode::decode(&mut &node[..]).unwrap(),
3465 TrieMasks { hash_mask, tree_mask },
3466 )
3467 .unwrap();
3468 }
3469
3470 assert_matches!(
3472 sparse.nodes.get(&Nibbles::default()),
3473 Some(SparseNode::Branch { state_mask, hash: None, store_in_db_trie: None }) if *state_mask == TrieMask::new(0b11)
3474 );
3475 }
3476
3477 #[test]
3478 fn sparse_trie_get_changed_nodes_at_depth() {
3479 let provider = DefaultTrieNodeProvider;
3480 let mut sparse = SerialSparseTrie::default();
3481
3482 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3483
3484 sparse
3497 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3498 .unwrap();
3499 sparse
3500 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3501 .unwrap();
3502 sparse
3503 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3504 .unwrap();
3505 sparse
3506 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
3507 .unwrap();
3508 sparse
3509 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
3510 .unwrap();
3511 sparse
3512 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
3513 .unwrap();
3514
3515 assert_eq!(
3516 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 0),
3517 (vec![(0, Nibbles::default())], PrefixSetMut::default())
3518 );
3519 assert_eq!(
3520 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 1),
3521 (vec![(1, Nibbles::from_nibbles_unchecked([0x5]))], [Nibbles::default()].into())
3522 );
3523 assert_eq!(
3524 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 2),
3525 (
3526 vec![
3527 (2, Nibbles::from_nibbles_unchecked([0x5, 0x0])),
3528 (2, Nibbles::from_nibbles_unchecked([0x5, 0x2])),
3529 (2, Nibbles::from_nibbles_unchecked([0x5, 0x3]))
3530 ],
3531 [Nibbles::default(), Nibbles::from_nibbles_unchecked([0x5])].into()
3532 )
3533 );
3534 assert_eq!(
3535 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 3),
3536 (
3537 vec![
3538 (3, Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3])),
3539 (2, Nibbles::from_nibbles_unchecked([0x5, 0x2])),
3540 (3, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x1])),
3541 (3, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3]))
3542 ],
3543 [
3544 Nibbles::default(),
3545 Nibbles::from_nibbles_unchecked([0x5]),
3546 Nibbles::from_nibbles_unchecked([0x5, 0x0]),
3547 Nibbles::from_nibbles_unchecked([0x5, 0x3])
3548 ]
3549 .into()
3550 )
3551 );
3552 assert_eq!(
3553 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 4),
3554 (
3555 vec![
3556 (4, Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3, 0x1])),
3557 (4, Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3, 0x3])),
3558 (2, Nibbles::from_nibbles_unchecked([0x5, 0x2])),
3559 (3, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x1])),
3560 (4, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3, 0x0])),
3561 (4, Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3, 0x2]))
3562 ],
3563 [
3564 Nibbles::default(),
3565 Nibbles::from_nibbles_unchecked([0x5]),
3566 Nibbles::from_nibbles_unchecked([0x5, 0x0]),
3567 Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3]),
3568 Nibbles::from_nibbles_unchecked([0x5, 0x3]),
3569 Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3])
3570 ]
3571 .into()
3572 )
3573 );
3574 }
3575
3576 #[test]
3577 fn hash_builder_branch_hash_mask() {
3578 let key1 = || pad_nibbles_left(Nibbles::from_nibbles_unchecked([0x00]));
3579 let key2 = || pad_nibbles_left(Nibbles::from_nibbles_unchecked([0x01]));
3580 let value = || Account { bytecode_hash: Some(B256::repeat_byte(1)), ..Default::default() };
3581 let value_encoded = || {
3582 let mut account_rlp = Vec::new();
3583 value().into_trie_account(EMPTY_ROOT_HASH).encode(&mut account_rlp);
3584 account_rlp
3585 };
3586
3587 let (hash_builder_root, hash_builder_updates, _, _, _) = run_hash_builder(
3588 [(key1(), value()), (key2(), value())],
3589 NoopAccountTrieCursor::default(),
3590 Default::default(),
3591 [Nibbles::default()],
3592 );
3593
3594 let provider = DefaultTrieNodeProvider;
3595 let mut sparse = SerialSparseTrie::default();
3596 sparse.update_leaf(key1(), value_encoded(), &provider).unwrap();
3597 sparse.update_leaf(key2(), value_encoded(), &provider).unwrap();
3598 let sparse_root = sparse.root();
3599 let sparse_updates = sparse.take_updates();
3600
3601 assert_eq!(sparse_root, hash_builder_root);
3602 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
3603 }
3604
3605 #[test]
3606 fn sparse_trie_wipe() {
3607 let provider = DefaultTrieNodeProvider;
3608 let mut sparse = SerialSparseTrie::default().with_updates(true);
3609
3610 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3611
3612 sparse
3625 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3626 .unwrap();
3627 sparse
3628 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3629 .unwrap();
3630 sparse
3631 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3632 .unwrap();
3633 sparse
3634 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
3635 .unwrap();
3636 sparse
3637 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
3638 .unwrap();
3639 sparse
3640 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
3641 .unwrap();
3642
3643 sparse.wipe();
3644
3645 assert_matches!(
3646 &sparse.updates,
3647 Some(SparseTrieUpdates{ updated_nodes, removed_nodes, wiped })
3648 if updated_nodes.is_empty() && removed_nodes.is_empty() && *wiped
3649 );
3650 assert_eq!(sparse.root(), EMPTY_ROOT_HASH);
3651 }
3652
3653 #[test]
3654 fn sparse_trie_clear() {
3655 let provider = DefaultTrieNodeProvider;
3658 let mut sparse = SerialSparseTrie::default();
3659 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3660 sparse
3661 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3662 .unwrap();
3663 sparse
3664 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3665 .unwrap();
3666 sparse
3667 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3668 .unwrap();
3669 sparse
3670 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value, &provider)
3671 .unwrap();
3672
3673 sparse.clear();
3674
3675 let empty_trie = SerialSparseTrie::default();
3676 assert_eq!(empty_trie, sparse);
3677 }
3678
3679 #[test]
3680 fn sparse_trie_display() {
3681 let provider = DefaultTrieNodeProvider;
3682 let mut sparse = SerialSparseTrie::default();
3683
3684 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
3685
3686 sparse
3699 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider)
3700 .unwrap();
3701 sparse
3702 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider)
3703 .unwrap();
3704 sparse
3705 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider)
3706 .unwrap();
3707 sparse
3708 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider)
3709 .unwrap();
3710 sparse
3711 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider)
3712 .unwrap();
3713 sparse
3714 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider)
3715 .unwrap();
3716
3717 let normal_printed = format!("{sparse}");
3718 let expected = "\
3719Root -> Extension { key: Nibbles(0x5), hash: None, store_in_db_trie: None }
37205 -> Branch { state_mask: TrieMask(0000000000001101), hash: None, store_in_db_trie: None }
372150 -> Extension { key: Nibbles(0x23), hash: None, store_in_db_trie: None }
37225023 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
372350231 -> Leaf { key: Nibbles(0x), hash: None }
372450233 -> Leaf { key: Nibbles(0x), hash: None }
372552013 -> Leaf { key: Nibbles(0x013), hash: None }
372653 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
372753102 -> Leaf { key: Nibbles(0x02), hash: None }
3728533 -> Branch { state_mask: TrieMask(0000000000000101), hash: None, store_in_db_trie: None }
372953302 -> Leaf { key: Nibbles(0x2), hash: None }
373053320 -> Leaf { key: Nibbles(0x0), hash: None }
3731";
3732 assert_eq!(normal_printed, expected);
3733
3734 let alternate_printed = format!("{sparse:#}");
3735 let expected = "\
3736Root -> Extension { key: Nibbles(0x5), hash: None, store_in_db_trie: None }
3737 5 -> Branch { state_mask: TrieMask(0000000000001101), hash: None, store_in_db_trie: None }
3738 50 -> Extension { key: Nibbles(0x23), hash: None, store_in_db_trie: None }
3739 5023 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
3740 50231 -> Leaf { key: Nibbles(0x), hash: None }
3741 50233 -> Leaf { key: Nibbles(0x), hash: None }
3742 52013 -> Leaf { key: Nibbles(0x013), hash: None }
3743 53 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None }
3744 53102 -> Leaf { key: Nibbles(0x02), hash: None }
3745 533 -> Branch { state_mask: TrieMask(0000000000000101), hash: None, store_in_db_trie: None }
3746 53302 -> Leaf { key: Nibbles(0x2), hash: None }
3747 53320 -> Leaf { key: Nibbles(0x0), hash: None }
3748";
3749
3750 assert_eq!(alternate_printed, expected);
3751 }
3752}