1use crate::blinded::{BlindedProvider, DefaultBlindedProvider};
2use alloy_primitives::{
3 hex, keccak256,
4 map::{Entry, HashMap, HashSet},
5 B256,
6};
7use alloy_rlp::Decodable;
8use reth_execution_errors::{SparseTrieError, SparseTrieErrorKind, SparseTrieResult};
9use reth_tracing::tracing::trace;
10use reth_trie_common::{
11 prefix_set::{PrefixSet, PrefixSetMut},
12 BranchNodeCompact, BranchNodeRef, ExtensionNodeRef, LeafNodeRef, Nibbles, RlpNode, TrieMask,
13 TrieNode, CHILD_INDEX_RANGE, EMPTY_ROOT_HASH,
14};
15use smallvec::SmallVec;
16use std::{borrow::Cow, fmt};
17
18#[derive(PartialEq, Eq)]
21pub enum SparseTrie<P = DefaultBlindedProvider> {
22 Blind,
24 Revealed(Box<RevealedSparseTrie<P>>),
26}
27
28impl<P> fmt::Debug for SparseTrie<P> {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 Self::Blind => write!(f, "Blind"),
32 Self::Revealed(revealed) => write!(f, "Revealed({revealed:?})"),
33 }
34 }
35}
36
37impl<P> Default for SparseTrie<P> {
38 fn default() -> Self {
39 Self::Blind
40 }
41}
42
43impl SparseTrie {
44 pub const fn blind() -> Self {
46 Self::Blind
47 }
48
49 pub fn revealed_empty() -> Self {
51 Self::Revealed(Box::default())
52 }
53
54 pub fn reveal_root(
60 &mut self,
61 root: TrieNode,
62 hash_mask: Option<TrieMask>,
63 retain_updates: bool,
64 ) -> SparseTrieResult<&mut RevealedSparseTrie> {
65 self.reveal_root_with_provider(Default::default(), root, hash_mask, retain_updates)
66 }
67}
68
69impl<P> SparseTrie<P> {
70 pub const fn is_blind(&self) -> bool {
72 matches!(self, Self::Blind)
73 }
74
75 pub fn as_revealed_mut(&mut self) -> Option<&mut RevealedSparseTrie<P>> {
77 if let Self::Revealed(revealed) = self {
78 Some(revealed)
79 } else {
80 None
81 }
82 }
83
84 pub fn reveal_root_with_provider(
90 &mut self,
91 provider: P,
92 root: TrieNode,
93 hash_mask: Option<TrieMask>,
94 retain_updates: bool,
95 ) -> SparseTrieResult<&mut RevealedSparseTrie<P>> {
96 if self.is_blind() {
97 *self = Self::Revealed(Box::new(RevealedSparseTrie::from_provider_and_root(
98 provider,
99 root,
100 hash_mask,
101 retain_updates,
102 )?))
103 }
104 Ok(self.as_revealed_mut().unwrap())
105 }
106
107 pub fn wipe(&mut self) -> SparseTrieResult<()> {
109 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
110 revealed.wipe();
111 Ok(())
112 }
113
114 pub fn root(&mut self) -> Option<B256> {
116 Some(self.as_revealed_mut()?.root())
117 }
118
119 pub fn calculate_below_level(&mut self, level: usize) {
121 self.as_revealed_mut().unwrap().update_rlp_node_level(level);
122 }
123}
124
125impl<P> SparseTrie<P>
126where
127 P: BlindedProvider,
128 SparseTrieError: From<P::Error>,
129{
130 pub fn update_leaf(&mut self, path: Nibbles, value: Vec<u8>) -> SparseTrieResult<()> {
132 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
133 revealed.update_leaf(path, value)?;
134 Ok(())
135 }
136
137 pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> {
139 let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?;
140 revealed.remove_leaf(path)?;
141 Ok(())
142 }
143}
144
145#[derive(Clone, PartialEq, Eq)]
154pub struct RevealedSparseTrie<P = DefaultBlindedProvider> {
155 provider: P,
157 nodes: HashMap<Nibbles, SparseNode>,
159 branch_node_hash_masks: HashMap<Nibbles, TrieMask>,
161 values: HashMap<Nibbles, Vec<u8>>,
163 prefix_set: PrefixSetMut,
165 updates: Option<SparseTrieUpdates>,
167 rlp_buf: Vec<u8>,
169}
170
171impl<P> fmt::Debug for RevealedSparseTrie<P> {
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 f.debug_struct("RevealedSparseTrie")
174 .field("nodes", &self.nodes)
175 .field("branch_hash_masks", &self.branch_node_hash_masks)
176 .field("values", &self.values)
177 .field("prefix_set", &self.prefix_set)
178 .field("updates", &self.updates)
179 .field("rlp_buf", &hex::encode(&self.rlp_buf))
180 .finish_non_exhaustive()
181 }
182}
183
184impl Default for RevealedSparseTrie {
185 fn default() -> Self {
186 Self {
187 provider: Default::default(),
188 nodes: HashMap::from_iter([(Nibbles::default(), SparseNode::Empty)]),
189 branch_node_hash_masks: HashMap::default(),
190 values: HashMap::default(),
191 prefix_set: PrefixSetMut::default(),
192 updates: None,
193 rlp_buf: Vec::new(),
194 }
195 }
196}
197
198impl RevealedSparseTrie {
199 pub fn from_root(
201 node: TrieNode,
202 hash_mask: Option<TrieMask>,
203 retain_updates: bool,
204 ) -> SparseTrieResult<Self> {
205 let mut this = Self {
206 provider: Default::default(),
207 nodes: HashMap::default(),
208 branch_node_hash_masks: HashMap::default(),
209 values: HashMap::default(),
210 prefix_set: PrefixSetMut::default(),
211 rlp_buf: Vec::new(),
212 updates: None,
213 }
214 .with_updates(retain_updates);
215 this.reveal_node(Nibbles::default(), node, hash_mask)?;
216 Ok(this)
217 }
218}
219
220impl<P> RevealedSparseTrie<P> {
221 pub fn from_provider_and_root(
223 provider: P,
224 node: TrieNode,
225 hash_mask: Option<TrieMask>,
226 retain_updates: bool,
227 ) -> SparseTrieResult<Self> {
228 let mut this = Self {
229 provider,
230 nodes: HashMap::default(),
231 branch_node_hash_masks: HashMap::default(),
232 values: HashMap::default(),
233 prefix_set: PrefixSetMut::default(),
234 rlp_buf: Vec::new(),
235 updates: None,
236 }
237 .with_updates(retain_updates);
238 this.reveal_node(Nibbles::default(), node, hash_mask)?;
239 Ok(this)
240 }
241
242 pub fn with_provider<BP>(self, provider: BP) -> RevealedSparseTrie<BP> {
244 RevealedSparseTrie {
245 provider,
246 nodes: self.nodes,
247 branch_node_hash_masks: self.branch_node_hash_masks,
248 values: self.values,
249 prefix_set: self.prefix_set,
250 updates: self.updates,
251 rlp_buf: self.rlp_buf,
252 }
253 }
254
255 pub fn with_updates(mut self, retain_updates: bool) -> Self {
257 if retain_updates {
258 self.updates = Some(SparseTrieUpdates::default());
259 }
260 self
261 }
262
263 pub fn updates_ref(&self) -> Cow<'_, SparseTrieUpdates> {
265 self.updates.as_ref().map_or(Cow::Owned(SparseTrieUpdates::default()), Cow::Borrowed)
266 }
267
268 pub fn get_leaf_value(&self, path: &Nibbles) -> Option<&Vec<u8>> {
270 self.values.get(path)
271 }
272
273 pub fn take_updates(&mut self) -> SparseTrieUpdates {
275 self.updates.take().unwrap_or_default()
276 }
277
278 pub fn reveal_node(
280 &mut self,
281 path: Nibbles,
282 node: TrieNode,
283 hash_mask: Option<TrieMask>,
284 ) -> SparseTrieResult<()> {
285 if let Some(hash_mask) = hash_mask {
286 self.branch_node_hash_masks.insert(path.clone(), hash_mask);
287 }
288
289 match node {
290 TrieNode::EmptyRoot => {
291 debug_assert!(path.is_empty());
292 self.nodes.insert(path, SparseNode::Empty);
293 }
294 TrieNode::Branch(branch) => {
295 let mut stack_ptr = branch.as_ref().first_child_index();
296 for idx in CHILD_INDEX_RANGE {
297 if branch.state_mask.is_bit_set(idx) {
298 let mut child_path = path.clone();
299 child_path.push_unchecked(idx);
300 self.reveal_node_or_hash(child_path, &branch.stack[stack_ptr])?;
301 stack_ptr += 1;
302 }
303 }
304
305 match self.nodes.entry(path) {
306 Entry::Occupied(mut entry) => match entry.get() {
307 SparseNode::Hash(_) => {
309 entry.insert(SparseNode::new_branch(branch.state_mask));
310 }
311 SparseNode::Branch { .. } | SparseNode::Extension { .. } => {}
314 node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => {
316 return Err(SparseTrieErrorKind::Reveal {
317 path: entry.key().clone(),
318 node: Box::new(node.clone()),
319 }
320 .into())
321 }
322 },
323 Entry::Vacant(entry) => {
324 entry.insert(SparseNode::new_branch(branch.state_mask));
325 }
326 }
327 }
328 TrieNode::Extension(ext) => match self.nodes.entry(path) {
329 Entry::Occupied(mut entry) => match entry.get() {
330 SparseNode::Hash(_) => {
331 let mut child_path = entry.key().clone();
332 child_path.extend_from_slice_unchecked(&ext.key);
333 entry.insert(SparseNode::new_ext(ext.key));
334 self.reveal_node_or_hash(child_path, &ext.child)?;
335 }
336 SparseNode::Extension { .. } | SparseNode::Branch { .. } => {}
339 node @ (SparseNode::Empty | SparseNode::Leaf { .. }) => {
341 return Err(SparseTrieErrorKind::Reveal {
342 path: entry.key().clone(),
343 node: Box::new(node.clone()),
344 }
345 .into())
346 }
347 },
348 Entry::Vacant(entry) => {
349 let mut child_path = entry.key().clone();
350 child_path.extend_from_slice_unchecked(&ext.key);
351 entry.insert(SparseNode::new_ext(ext.key));
352 self.reveal_node_or_hash(child_path, &ext.child)?;
353 }
354 },
355 TrieNode::Leaf(leaf) => match self.nodes.entry(path) {
356 Entry::Occupied(mut entry) => match entry.get() {
357 SparseNode::Hash(_) => {
358 let mut full = entry.key().clone();
359 full.extend_from_slice_unchecked(&leaf.key);
360 entry.insert(SparseNode::new_leaf(leaf.key));
361 self.values.insert(full, leaf.value);
362 }
363 SparseNode::Leaf { .. } => {}
365 node @ (SparseNode::Empty |
367 SparseNode::Extension { .. } |
368 SparseNode::Branch { .. }) => {
369 return Err(SparseTrieErrorKind::Reveal {
370 path: entry.key().clone(),
371 node: Box::new(node.clone()),
372 }
373 .into())
374 }
375 },
376 Entry::Vacant(entry) => {
377 let mut full = entry.key().clone();
378 full.extend_from_slice_unchecked(&leaf.key);
379 entry.insert(SparseNode::new_leaf(leaf.key));
380 self.values.insert(full, leaf.value);
381 }
382 },
383 }
384
385 Ok(())
386 }
387
388 fn reveal_node_or_hash(&mut self, path: Nibbles, child: &[u8]) -> SparseTrieResult<()> {
389 if child.len() == B256::len_bytes() + 1 {
390 let hash = B256::from_slice(&child[1..]);
391 match self.nodes.entry(path) {
392 Entry::Occupied(entry) => match entry.get() {
393 SparseNode::Hash(previous_hash) if previous_hash != &hash => {
395 return Err(SparseTrieErrorKind::Reveal {
396 path: entry.key().clone(),
397 node: Box::new(SparseNode::Hash(hash)),
398 }
399 .into())
400 }
401 _ => {}
402 },
403 Entry::Vacant(entry) => {
404 entry.insert(SparseNode::Hash(hash));
405 }
406 }
407 return Ok(())
408 }
409
410 self.reveal_node(path, TrieNode::decode(&mut &child[..])?, None)
411 }
412
413 fn take_nodes_for_path(&mut self, path: &Nibbles) -> SparseTrieResult<Vec<RemovedSparseNode>> {
415 let mut current = Nibbles::default(); let mut nodes = Vec::new(); while let Some(node) = self.nodes.remove(¤t) {
419 match &node {
420 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
421 &SparseNode::Hash(hash) => {
422 return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into())
423 }
424 SparseNode::Leaf { key: _key, .. } => {
425 #[cfg(debug_assertions)]
429 {
430 let mut current = current.clone();
431 current.extend_from_slice_unchecked(_key);
432 assert_eq!(¤t, path);
433 }
434
435 nodes.push(RemovedSparseNode {
436 path: current.clone(),
437 node,
438 unset_branch_nibble: None,
439 });
440 break
441 }
442 SparseNode::Extension { key, .. } => {
443 #[cfg(debug_assertions)]
444 {
445 let mut current = current.clone();
446 current.extend_from_slice_unchecked(key);
447 assert!(
448 path.starts_with(¤t),
449 "path: {:?}, current: {:?}, key: {:?}",
450 path,
451 current,
452 key
453 );
454 }
455
456 let path = current.clone();
457 current.extend_from_slice_unchecked(key);
458 nodes.push(RemovedSparseNode { path, node, unset_branch_nibble: None });
459 }
460 SparseNode::Branch { state_mask, .. } => {
461 let nibble = path[current.len()];
462 debug_assert!(
463 state_mask.is_bit_set(nibble),
464 "current: {:?}, path: {:?}, nibble: {:?}, state_mask: {:?}",
465 current,
466 path,
467 nibble,
468 state_mask
469 );
470
471 let mut child_path =
477 Nibbles::from_nibbles([current.as_slice(), &[nibble]].concat());
478 let unset_branch_nibble = self
479 .nodes
480 .get(&child_path)
481 .is_some_and(move |node| match node {
482 SparseNode::Leaf { key, .. } => {
483 child_path.extend_from_slice_unchecked(key);
485 &child_path == path
486 }
487 _ => false,
488 })
489 .then_some(nibble);
490
491 nodes.push(RemovedSparseNode {
492 path: current.clone(),
493 node,
494 unset_branch_nibble,
495 });
496
497 current.push_unchecked(nibble);
498 }
499 }
500 }
501
502 Ok(nodes)
503 }
504
505 pub fn wipe(&mut self) {
507 self.nodes = HashMap::from_iter([(Nibbles::default(), SparseNode::Empty)]);
508 self.values = HashMap::default();
509 self.prefix_set = PrefixSetMut::all();
510 self.updates = self.updates.is_some().then(SparseTrieUpdates::wiped);
511 }
512
513 pub fn root(&mut self) -> B256 {
516 let mut prefix_set = std::mem::take(&mut self.prefix_set).freeze();
518 let rlp_node = self.rlp_node_allocate(Nibbles::default(), &mut prefix_set);
519 if let Some(root_hash) = rlp_node.as_hash() {
520 root_hash
521 } else {
522 keccak256(rlp_node)
523 }
524 }
525
526 pub fn update_rlp_node_level(&mut self, depth: usize) {
529 let mut prefix_set = self.prefix_set.clone().freeze();
530 let mut buffers = RlpNodeBuffers::default();
531
532 let targets = self.get_changed_nodes_at_depth(&mut prefix_set, depth);
533 for target in targets {
534 buffers.path_stack.push((target, Some(true)));
535 self.rlp_node(&mut prefix_set, &mut buffers);
536 }
537 }
538
539 fn get_changed_nodes_at_depth(&self, prefix_set: &mut PrefixSet, depth: usize) -> Vec<Nibbles> {
543 let mut paths = Vec::from([(Nibbles::default(), 0)]);
544 let mut targets = Vec::new();
545
546 while let Some((mut path, level)) = paths.pop() {
547 match self.nodes.get(&path).unwrap() {
548 SparseNode::Empty | SparseNode::Hash(_) => {}
549 SparseNode::Leaf { hash, .. } => {
550 if hash.is_some() && !prefix_set.contains(&path) {
551 continue
552 }
553
554 targets.push(path);
555 }
556 SparseNode::Extension { key, hash } => {
557 if hash.is_some() && !prefix_set.contains(&path) {
558 continue
559 }
560
561 if level >= depth {
562 targets.push(path);
563 } else {
564 path.extend_from_slice_unchecked(key);
565 paths.push((path, level + 1));
566 }
567 }
568 SparseNode::Branch { state_mask, hash, .. } => {
569 if hash.is_some() && !prefix_set.contains(&path) {
570 continue
571 }
572
573 if level >= depth {
574 targets.push(path);
575 } else {
576 for bit in CHILD_INDEX_RANGE.rev() {
577 if state_mask.is_bit_set(bit) {
578 let mut child_path = path.clone();
579 child_path.push_unchecked(bit);
580 paths.push((child_path, level + 1));
581 }
582 }
583 }
584 }
585 }
586 }
587
588 targets
589 }
590
591 fn rlp_node_allocate(&mut self, path: Nibbles, prefix_set: &mut PrefixSet) -> RlpNode {
592 let mut buffers = RlpNodeBuffers::new_with_path(path);
593 self.rlp_node(prefix_set, &mut buffers)
594 }
595
596 fn rlp_node(&mut self, prefix_set: &mut PrefixSet, buffers: &mut RlpNodeBuffers) -> RlpNode {
597 'main: while let Some((path, mut is_in_prefix_set)) = buffers.path_stack.pop() {
598 let mut prefix_set_contains =
602 |path: &Nibbles| *is_in_prefix_set.get_or_insert_with(|| prefix_set.contains(path));
603
604 let (rlp_node, calculated, node_type) = match self.nodes.get_mut(&path).unwrap() {
605 SparseNode::Empty => {
606 (RlpNode::word_rlp(&EMPTY_ROOT_HASH), false, SparseNodeType::Empty)
607 }
608 SparseNode::Hash(hash) => (RlpNode::word_rlp(hash), false, SparseNodeType::Hash),
609 SparseNode::Leaf { key, hash } => {
610 let mut path = path.clone();
611 path.extend_from_slice_unchecked(key);
612 if let Some(hash) = hash.filter(|_| !prefix_set_contains(&path)) {
613 (RlpNode::word_rlp(&hash), false, SparseNodeType::Leaf)
614 } else {
615 let value = self.values.get(&path).unwrap();
616 self.rlp_buf.clear();
617 let rlp_node = LeafNodeRef { key, value }.rlp(&mut self.rlp_buf);
618 *hash = rlp_node.as_hash();
619 (rlp_node, true, SparseNodeType::Leaf)
620 }
621 }
622 SparseNode::Extension { key, hash } => {
623 let mut child_path = path.clone();
624 child_path.extend_from_slice_unchecked(key);
625 if let Some(hash) = hash.filter(|_| !prefix_set_contains(&path)) {
626 (
627 RlpNode::word_rlp(&hash),
628 false,
629 SparseNodeType::Extension { store_in_db_trie: true },
630 )
631 } else if buffers.rlp_node_stack.last().is_some_and(|e| e.0 == child_path) {
632 let (_, child, _, node_type) = buffers.rlp_node_stack.pop().unwrap();
633 self.rlp_buf.clear();
634 let rlp_node = ExtensionNodeRef::new(key, &child).rlp(&mut self.rlp_buf);
635 *hash = rlp_node.as_hash();
636
637 (
638 rlp_node,
639 true,
640 SparseNodeType::Extension {
641 store_in_db_trie: node_type.store_in_db_trie(),
644 },
645 )
646 } else {
647 buffers.path_stack.extend([(path, is_in_prefix_set), (child_path, None)]);
649 continue
650 }
651 }
652 SparseNode::Branch { state_mask, hash, store_in_db_trie } => {
653 if let Some((hash, store_in_db_trie)) =
654 hash.zip(*store_in_db_trie).filter(|_| !prefix_set_contains(&path))
655 {
656 buffers.rlp_node_stack.push((
657 path,
658 RlpNode::word_rlp(&hash),
659 false,
660 SparseNodeType::Branch { store_in_db_trie },
661 ));
662 continue
663 }
664 let retain_updates = self.updates.is_some() && prefix_set_contains(&path);
665
666 buffers.branch_child_buf.clear();
667 for bit in CHILD_INDEX_RANGE.rev() {
670 if state_mask.is_bit_set(bit) {
671 let mut child = path.clone();
672 child.push_unchecked(bit);
673 buffers.branch_child_buf.push(child);
674 }
675 }
676
677 buffers
678 .branch_value_stack_buf
679 .resize(buffers.branch_child_buf.len(), Default::default());
680 let mut added_children = false;
681
682 let mut tree_mask_values = Vec::new();
684 let mut hash_mask_values = Vec::new();
685 let mut hashes = Vec::new();
686 for (i, child_path) in buffers.branch_child_buf.iter().enumerate() {
687 if buffers.rlp_node_stack.last().is_some_and(|e| &e.0 == child_path) {
688 let (_, child, calculated, node_type) =
689 buffers.rlp_node_stack.pop().unwrap();
690
691 if retain_updates {
693 let tree_mask_value = if node_type.store_in_db_trie() {
695 true
698 } else {
699 !calculated
703 };
704 tree_mask_values.push(tree_mask_value);
705
706 let hash = child.as_hash().filter(|_| {
710 node_type.is_branch() ||
711 (node_type.is_hash() &&
712 self.branch_node_hash_masks
713 .get(&path)
714 .is_some_and(|mask| {
715 mask.is_bit_set(child_path.last().unwrap())
716 }))
717 });
718 let hash_mask_value = hash.is_some();
719 hash_mask_values.push(hash_mask_value);
720 if let Some(hash) = hash {
721 hashes.push(hash);
722 }
723
724 trace!(
725 target: "trie::sparse",
726 ?path,
727 ?child_path,
728 ?tree_mask_value,
729 ?hash_mask_value,
730 "Updating branch node child masks"
731 );
732 }
733
734 buffers.branch_value_stack_buf
737 [buffers.branch_child_buf.len() - i - 1] = child;
738 added_children = true;
739 } else {
740 debug_assert!(!added_children);
741 buffers.path_stack.push((path, is_in_prefix_set));
742 buffers
743 .path_stack
744 .extend(buffers.branch_child_buf.drain(..).map(|p| (p, None)));
745 continue 'main
746 }
747 }
748
749 self.rlp_buf.clear();
750 let branch_node_ref =
751 BranchNodeRef::new(&buffers.branch_value_stack_buf, *state_mask);
752 let rlp_node = branch_node_ref.rlp(&mut self.rlp_buf);
753 *hash = rlp_node.as_hash();
754
755 let store_in_db_trie_value = if let Some(updates) =
758 self.updates.as_mut().filter(|_| retain_updates && !path.is_empty())
759 {
760 let mut tree_mask_values = tree_mask_values.into_iter().rev();
761 let mut hash_mask_values = hash_mask_values.into_iter().rev();
762 let mut tree_mask = TrieMask::default();
763 let mut hash_mask = TrieMask::default();
764 for (i, child) in branch_node_ref.children() {
765 if child.is_some() {
766 if hash_mask_values.next().unwrap() {
767 hash_mask.set_bit(i);
768 }
769 if tree_mask_values.next().unwrap() {
770 tree_mask.set_bit(i);
771 }
772 }
773 }
774
775 let store_in_db_trie = !tree_mask.is_empty() || !hash_mask.is_empty();
778 if store_in_db_trie {
779 hashes.reverse();
780 let branch_node = BranchNodeCompact::new(
781 *state_mask,
782 tree_mask,
783 hash_mask,
784 hashes,
785 hash.filter(|_| path.len() == 0),
786 );
787 updates.updated_nodes.insert(path.clone(), branch_node);
788 }
789
790 store_in_db_trie
791 } else {
792 false
793 };
794 *store_in_db_trie = Some(store_in_db_trie_value);
795
796 (
797 rlp_node,
798 true,
799 SparseNodeType::Branch { store_in_db_trie: store_in_db_trie_value },
800 )
801 }
802 };
803 buffers.rlp_node_stack.push((path, rlp_node, calculated, node_type));
804 }
805
806 debug_assert_eq!(buffers.rlp_node_stack.len(), 1);
807 buffers.rlp_node_stack.pop().unwrap().1
808 }
809}
810
811impl<P> RevealedSparseTrie<P>
812where
813 P: BlindedProvider,
814 SparseTrieError: From<P::Error>,
815{
816 pub fn update_leaf(&mut self, path: Nibbles, value: Vec<u8>) -> SparseTrieResult<()> {
818 self.prefix_set.insert(path.clone());
819 let existing = self.values.insert(path.clone(), value);
820 if existing.is_some() {
821 return Ok(())
823 }
824
825 let mut current = Nibbles::default();
826 while let Some(node) = self.nodes.get_mut(¤t) {
827 match node {
828 SparseNode::Empty => {
829 *node = SparseNode::new_leaf(path);
830 break
831 }
832 &mut SparseNode::Hash(hash) => {
833 return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into())
834 }
835 SparseNode::Leaf { key: current_key, .. } => {
836 current.extend_from_slice_unchecked(current_key);
837
838 if current == path {
840 unreachable!("we already checked leaf presence in the beginning");
841 }
842
843 let common = current.common_prefix_length(&path);
845
846 let new_ext_key = current.slice(current.len() - current_key.len()..common);
848 *node = SparseNode::new_ext(new_ext_key);
849
850 self.nodes.reserve(3);
852 self.nodes.insert(
853 current.slice(..common),
854 SparseNode::new_split_branch(current[common], path[common]),
855 );
856 self.nodes.insert(
857 path.slice(..=common),
858 SparseNode::new_leaf(path.slice(common + 1..)),
859 );
860 self.nodes.insert(
861 current.slice(..=common),
862 SparseNode::new_leaf(current.slice(common + 1..)),
863 );
864
865 break;
866 }
867 SparseNode::Extension { key, .. } => {
868 current.extend_from_slice(key);
869
870 if !path.starts_with(¤t) {
871 let common = current.common_prefix_length(&path);
873 *key = current.slice(current.len() - key.len()..common);
874
875 if self.updates.is_some() {
879 if self.nodes.get(¤t).unwrap().is_hash() {
881 if let Some(node) = self.provider.blinded_node(¤t)? {
882 let decoded = TrieNode::decode(&mut &node[..])?;
883 trace!(target: "trie::sparse", ?current, ?decoded, "Revealing extension node child");
884 self.reveal_node(current.clone(), decoded, None)?;
889 }
890 }
891 }
892
893 self.nodes.reserve(3);
896 let branch = SparseNode::new_split_branch(current[common], path[common]);
897 self.nodes.insert(current.slice(..common), branch);
898
899 let new_leaf = SparseNode::new_leaf(path.slice(common + 1..));
901 self.nodes.insert(path.slice(..=common), new_leaf);
902
903 let key = current.slice(common + 1..);
905 if !key.is_empty() {
906 self.nodes.insert(current.slice(..=common), SparseNode::new_ext(key));
907 }
908
909 break;
910 }
911 }
912 SparseNode::Branch { state_mask, .. } => {
913 let nibble = path[current.len()];
914 current.push_unchecked(nibble);
915 if !state_mask.is_bit_set(nibble) {
916 state_mask.set_bit(nibble);
917 let new_leaf = SparseNode::new_leaf(path.slice(current.len()..));
918 self.nodes.insert(current, new_leaf);
919 break;
920 }
921 }
922 };
923 }
924
925 Ok(())
926 }
927
928 pub fn remove_leaf(&mut self, path: &Nibbles) -> SparseTrieResult<()> {
930 if self.values.remove(path).is_none() {
931 if let Some(&SparseNode::Hash(hash)) = self.nodes.get(path) {
932 return Err(SparseTrieErrorKind::BlindedNode { path: path.clone(), hash }.into())
934 }
935
936 return Ok(())
938 }
939 self.prefix_set.insert(path.clone());
940
941 let mut removed_nodes = self.take_nodes_for_path(path)?;
946 trace!(target: "trie::sparse", ?path, ?removed_nodes, "Removed nodes for path");
947 let mut child = removed_nodes.pop().expect("leaf exists");
949 #[cfg(debug_assertions)]
950 {
951 let mut child_path = child.path.clone();
952 let SparseNode::Leaf { key, .. } = &child.node else { panic!("expected leaf node") };
953 child_path.extend_from_slice_unchecked(key);
954 assert_eq!(&child_path, path);
955 }
956
957 if removed_nodes.is_empty() {
959 debug_assert!(self.nodes.is_empty());
960 self.nodes.insert(Nibbles::default(), SparseNode::Empty);
961
962 return Ok(())
963 }
964
965 while let Some(removed_node) = removed_nodes.pop() {
968 let removed_path = removed_node.path;
969
970 let new_node = match &removed_node.node {
971 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
972 &SparseNode::Hash(hash) => {
973 return Err(SparseTrieErrorKind::BlindedNode { path: removed_path, hash }.into())
974 }
975 SparseNode::Leaf { .. } => {
976 unreachable!("we already popped the leaf node")
977 }
978 SparseNode::Extension { key, .. } => {
979 match &child.node {
982 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
983 &SparseNode::Hash(hash) => {
984 return Err(
985 SparseTrieErrorKind::BlindedNode { path: child.path, hash }.into()
986 )
987 }
988 SparseNode::Leaf { key: leaf_key, .. } => {
994 self.nodes.remove(&child.path);
995
996 let mut new_key = key.clone();
997 new_key.extend_from_slice_unchecked(leaf_key);
998 SparseNode::new_leaf(new_key)
999 }
1000 SparseNode::Extension { key: extension_key, .. } => {
1003 self.nodes.remove(&child.path);
1004
1005 let mut new_key = key.clone();
1006 new_key.extend_from_slice_unchecked(extension_key);
1007 SparseNode::new_ext(new_key)
1008 }
1009 SparseNode::Branch { .. } => removed_node.node,
1011 }
1012 }
1013 SparseNode::Branch { mut state_mask, hash: _, store_in_db_trie: _ } => {
1014 if let Some(removed_nibble) = removed_node.unset_branch_nibble {
1018 state_mask.unset_bit(removed_nibble);
1019 }
1020
1021 if state_mask.count_bits() == 1 {
1023 let child_nibble =
1024 state_mask.first_set_bit_index().expect("state mask is not empty");
1025
1026 let mut child_path = removed_path.clone();
1028 child_path.push_unchecked(child_nibble);
1029
1030 trace!(target: "trie::sparse", ?removed_path, ?child_path, ?child, "Branch node has only one child");
1031
1032 if self.nodes.get(&child_path).unwrap().is_hash() {
1033 trace!(target: "trie::sparse", ?child_path, "Retrieving remaining blinded branch child");
1034 if let Some(node) = self.provider.blinded_node(&child_path)? {
1035 let decoded = TrieNode::decode(&mut &node[..])?;
1036 trace!(target: "trie::sparse", ?child_path, ?decoded, "Revealing remaining blinded branch child");
1037 self.reveal_node(child_path.clone(), decoded, None)?;
1041 }
1042 }
1043
1044 let child = self.nodes.get(&child_path).unwrap();
1046
1047 let mut delete_child = false;
1048 let new_node = match child {
1049 SparseNode::Empty => return Err(SparseTrieErrorKind::Blind.into()),
1050 &SparseNode::Hash(hash) => {
1051 return Err(SparseTrieErrorKind::BlindedNode {
1052 path: child_path,
1053 hash,
1054 }
1055 .into())
1056 }
1057 SparseNode::Leaf { key, .. } => {
1061 delete_child = true;
1062
1063 let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]);
1064 new_key.extend_from_slice_unchecked(key);
1065 SparseNode::new_leaf(new_key)
1066 }
1067 SparseNode::Extension { key, .. } => {
1071 delete_child = true;
1072
1073 let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]);
1074 new_key.extend_from_slice_unchecked(key);
1075 SparseNode::new_ext(new_key)
1076 }
1077 SparseNode::Branch { .. } => {
1080 SparseNode::new_ext(Nibbles::from_nibbles_unchecked([child_nibble]))
1081 }
1082 };
1083
1084 if delete_child {
1085 self.nodes.remove(&child_path);
1086 }
1087
1088 if let Some(updates) = self.updates.as_mut() {
1089 updates.removed_nodes.insert(removed_path.clone());
1090 }
1091
1092 new_node
1093 }
1094 else {
1097 SparseNode::new_branch(state_mask)
1098 }
1099 }
1100 };
1101
1102 child = RemovedSparseNode {
1103 path: removed_path.clone(),
1104 node: new_node.clone(),
1105 unset_branch_nibble: None,
1106 };
1107 trace!(target: "trie::sparse", ?removed_path, ?new_node, "Re-inserting the node");
1108 self.nodes.insert(removed_path, new_node);
1109 }
1110
1111 Ok(())
1112 }
1113}
1114
1115#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1117enum SparseNodeType {
1118 Empty,
1120 Hash,
1122 Leaf,
1124 Extension {
1126 store_in_db_trie: bool,
1128 },
1129 Branch {
1131 store_in_db_trie: bool,
1133 },
1134}
1135
1136impl SparseNodeType {
1137 const fn is_hash(&self) -> bool {
1138 matches!(self, Self::Hash)
1139 }
1140
1141 const fn is_branch(&self) -> bool {
1142 matches!(self, Self::Branch { .. })
1143 }
1144
1145 const fn store_in_db_trie(&self) -> bool {
1146 match *self {
1147 Self::Extension { store_in_db_trie } | Self::Branch { store_in_db_trie } => {
1148 store_in_db_trie
1149 }
1150 _ => false,
1151 }
1152 }
1153}
1154
1155#[derive(Debug, Clone, PartialEq, Eq)]
1157pub enum SparseNode {
1158 Empty,
1160 Hash(B256),
1162 Leaf {
1164 key: Nibbles,
1166 hash: Option<B256>,
1169 },
1170 Extension {
1172 key: Nibbles,
1174 hash: Option<B256>,
1177 },
1178 Branch {
1180 state_mask: TrieMask,
1182 hash: Option<B256>,
1185 store_in_db_trie: Option<bool>,
1188 },
1189}
1190
1191impl SparseNode {
1192 pub fn from_node(node: TrieNode) -> Self {
1194 match node {
1195 TrieNode::EmptyRoot => Self::Empty,
1196 TrieNode::Leaf(leaf) => Self::new_leaf(leaf.key),
1197 TrieNode::Extension(ext) => Self::new_ext(ext.key),
1198 TrieNode::Branch(branch) => Self::new_branch(branch.state_mask),
1199 }
1200 }
1201
1202 pub const fn new_branch(state_mask: TrieMask) -> Self {
1204 Self::Branch { state_mask, hash: None, store_in_db_trie: None }
1205 }
1206
1207 pub const fn new_split_branch(bit_a: u8, bit_b: u8) -> Self {
1209 let state_mask = TrieMask::new(
1210 (1u16 << bit_a) | (1u16 << bit_b),
1212 );
1213 Self::Branch { state_mask, hash: None, store_in_db_trie: None }
1214 }
1215
1216 pub const fn new_ext(key: Nibbles) -> Self {
1218 Self::Extension { key, hash: None }
1219 }
1220
1221 pub const fn new_leaf(key: Nibbles) -> Self {
1223 Self::Leaf { key, hash: None }
1224 }
1225
1226 pub const fn is_hash(&self) -> bool {
1228 matches!(self, Self::Hash(_))
1229 }
1230}
1231
1232#[derive(Debug)]
1233struct RemovedSparseNode {
1234 path: Nibbles,
1235 node: SparseNode,
1236 unset_branch_nibble: Option<u8>,
1237}
1238
1239#[derive(Debug, Default)]
1241struct RlpNodeBuffers {
1242 path_stack: Vec<(Nibbles, Option<bool>)>,
1244 rlp_node_stack: Vec<(Nibbles, RlpNode, bool, SparseNodeType)>,
1246 branch_child_buf: SmallVec<[Nibbles; 16]>,
1248 branch_value_stack_buf: SmallVec<[RlpNode; 16]>,
1250}
1251
1252impl RlpNodeBuffers {
1253 fn new_with_path(path: Nibbles) -> Self {
1255 Self {
1256 path_stack: vec![(path, None)],
1257 rlp_node_stack: Vec::new(),
1258 branch_child_buf: SmallVec::<[Nibbles; 16]>::new_const(),
1259 branch_value_stack_buf: SmallVec::<[RlpNode; 16]>::new_const(),
1260 }
1261 }
1262}
1263
1264#[derive(Debug, Clone, Default, PartialEq, Eq)]
1266pub struct SparseTrieUpdates {
1267 pub(crate) updated_nodes: HashMap<Nibbles, BranchNodeCompact>,
1268 pub(crate) removed_nodes: HashSet<Nibbles>,
1269 pub(crate) wiped: bool,
1270}
1271
1272impl SparseTrieUpdates {
1273 pub fn wiped() -> Self {
1275 Self { wiped: true, ..Default::default() }
1276 }
1277}
1278
1279#[cfg(test)]
1280mod tests {
1281 use super::*;
1282 use alloy_primitives::{
1283 map::{B256HashSet, HashSet},
1284 U256,
1285 };
1286 use alloy_rlp::Encodable;
1287 use assert_matches::assert_matches;
1288 use itertools::Itertools;
1289 use prop::sample::SizeRange;
1290 use proptest::prelude::*;
1291 use proptest_arbitrary_interop::arb;
1292 use rand::seq::IteratorRandom;
1293 use reth_primitives_traits::Account;
1294 use reth_trie::{
1295 hashed_cursor::{noop::NoopHashedAccountCursor, HashedPostStateAccountCursor},
1296 node_iter::{TrieElement, TrieNodeIter},
1297 trie_cursor::noop::NoopAccountTrieCursor,
1298 updates::TrieUpdates,
1299 walker::TrieWalker,
1300 BranchNode, ExtensionNode, HashedPostState, LeafNode, TrieAccount,
1301 };
1302 use reth_trie_common::{
1303 proof::{ProofNodes, ProofRetainer},
1304 HashBuilder,
1305 };
1306 use std::collections::BTreeMap;
1307
1308 fn pad_nibbles_left(nibbles: Nibbles) -> Nibbles {
1310 let mut base =
1311 Nibbles::from_nibbles_unchecked(vec![0; B256::len_bytes() * 2 - nibbles.len()]);
1312 base.extend_from_slice_unchecked(&nibbles);
1313 base
1314 }
1315
1316 fn pad_nibbles_right(mut nibbles: Nibbles) -> Nibbles {
1318 nibbles.extend_from_slice_unchecked(&vec![0; B256::len_bytes() * 2 - nibbles.len()]);
1319 nibbles
1320 }
1321
1322 fn run_hash_builder(
1327 state: impl IntoIterator<Item = (Nibbles, Account)> + Clone,
1328 destroyed_accounts: B256HashSet,
1329 proof_targets: impl IntoIterator<Item = Nibbles>,
1330 ) -> (B256, TrieUpdates, ProofNodes, HashMap<Nibbles, TrieMask>) {
1331 let mut account_rlp = Vec::new();
1332
1333 let mut hash_builder = HashBuilder::default()
1334 .with_updates(true)
1335 .with_proof_retainer(ProofRetainer::from_iter(proof_targets));
1336
1337 let mut prefix_set = PrefixSetMut::default();
1338 prefix_set.extend_keys(state.clone().into_iter().map(|(nibbles, _)| nibbles));
1339 let walker = TrieWalker::new(NoopAccountTrieCursor::default(), prefix_set.freeze())
1340 .with_deletions_retained(true);
1341 let hashed_post_state = HashedPostState::default()
1342 .with_accounts(state.into_iter().map(|(nibbles, account)| {
1343 (nibbles.pack().into_inner().unwrap().into(), Some(account))
1344 }))
1345 .into_sorted();
1346 let mut node_iter = TrieNodeIter::new(
1347 walker,
1348 HashedPostStateAccountCursor::new(
1349 NoopHashedAccountCursor::default(),
1350 hashed_post_state.accounts(),
1351 ),
1352 );
1353
1354 while let Some(node) = node_iter.try_next().unwrap() {
1355 match node {
1356 TrieElement::Branch(branch) => {
1357 hash_builder.add_branch(branch.key, branch.value, branch.children_are_in_trie);
1358 }
1359 TrieElement::Leaf(key, account) => {
1360 let account = TrieAccount::from((account, EMPTY_ROOT_HASH));
1361 account.encode(&mut account_rlp);
1362
1363 hash_builder.add_leaf(Nibbles::unpack(key), &account_rlp);
1364 account_rlp.clear();
1365 }
1366 }
1367 }
1368 let root = hash_builder.root();
1369 let proof_nodes = hash_builder.take_proof_nodes();
1370 let branch_node_hash_masks = hash_builder
1371 .updated_branch_nodes
1372 .clone()
1373 .unwrap_or_default()
1374 .iter()
1375 .map(|(path, node)| (path.clone(), node.hash_mask))
1376 .collect();
1377
1378 let mut trie_updates = TrieUpdates::default();
1379 let removed_keys = node_iter.walker.take_removed_keys();
1380 trie_updates.finalize(hash_builder, removed_keys, destroyed_accounts);
1381
1382 (root, trie_updates, proof_nodes, branch_node_hash_masks)
1383 }
1384
1385 fn assert_eq_sparse_trie_proof_nodes(
1387 sparse_trie: &RevealedSparseTrie,
1388 proof_nodes: ProofNodes,
1389 ) {
1390 let proof_nodes = proof_nodes
1391 .into_nodes_sorted()
1392 .into_iter()
1393 .map(|(path, node)| (path, TrieNode::decode(&mut node.as_ref()).unwrap()));
1394
1395 let sparse_nodes = sparse_trie.nodes.iter().sorted_by_key(|(path, _)| *path);
1396
1397 for ((proof_node_path, proof_node), (sparse_node_path, sparse_node)) in
1398 proof_nodes.zip(sparse_nodes)
1399 {
1400 assert_eq!(&proof_node_path, sparse_node_path);
1401
1402 let equals = match (&proof_node, &sparse_node) {
1403 (TrieNode::EmptyRoot, SparseNode::Empty) => true,
1405 (
1407 TrieNode::Branch(BranchNode { state_mask: proof_state_mask, .. }),
1408 SparseNode::Branch { state_mask: sparse_state_mask, .. },
1409 ) => proof_state_mask == sparse_state_mask,
1410 (
1412 TrieNode::Extension(ExtensionNode { key: proof_key, .. }),
1413 SparseNode::Extension { key: sparse_key, .. },
1414 ) |
1415 (
1417 TrieNode::Leaf(LeafNode { key: proof_key, .. }),
1418 SparseNode::Leaf { key: sparse_key, .. },
1419 ) => proof_key == sparse_key,
1420 (_, SparseNode::Empty | SparseNode::Hash(_)) => continue,
1422 _ => false,
1423 };
1424 assert!(equals, "proof node: {:?}, sparse node: {:?}", proof_node, sparse_node);
1425 }
1426 }
1427
1428 #[test]
1429 fn sparse_trie_is_blind() {
1430 assert!(SparseTrie::blind().is_blind());
1431 assert!(!SparseTrie::revealed_empty().is_blind());
1432 }
1433
1434 #[test]
1435 fn sparse_trie_empty_update_one() {
1436 let key = Nibbles::unpack(B256::with_last_byte(42));
1437 let value = || Account::default();
1438 let value_encoded = || {
1439 let mut account_rlp = Vec::new();
1440 TrieAccount::from((value(), EMPTY_ROOT_HASH)).encode(&mut account_rlp);
1441 account_rlp
1442 };
1443
1444 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _) =
1445 run_hash_builder([(key.clone(), value())], Default::default(), [key.clone()]);
1446
1447 let mut sparse = RevealedSparseTrie::default().with_updates(true);
1448 sparse.update_leaf(key, value_encoded()).unwrap();
1449 let sparse_root = sparse.root();
1450 let sparse_updates = sparse.take_updates();
1451
1452 assert_eq!(sparse_root, hash_builder_root);
1453 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
1454 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
1455 }
1456
1457 #[test]
1458 fn sparse_trie_empty_update_multiple_lower_nibbles() {
1459 reth_tracing::init_test_tracing();
1460
1461 let paths = (0..=16).map(|b| Nibbles::unpack(B256::with_last_byte(b))).collect::<Vec<_>>();
1462 let value = || Account::default();
1463 let value_encoded = || {
1464 let mut account_rlp = Vec::new();
1465 TrieAccount::from((value(), EMPTY_ROOT_HASH)).encode(&mut account_rlp);
1466 account_rlp
1467 };
1468
1469 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _) =
1470 run_hash_builder(
1471 paths.iter().cloned().zip(std::iter::repeat_with(value)),
1472 Default::default(),
1473 paths.clone(),
1474 );
1475
1476 let mut sparse = RevealedSparseTrie::default().with_updates(true);
1477 for path in &paths {
1478 sparse.update_leaf(path.clone(), value_encoded()).unwrap();
1479 }
1480 let sparse_root = sparse.root();
1481 let sparse_updates = sparse.take_updates();
1482
1483 assert_eq!(sparse_root, hash_builder_root);
1484 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
1485 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
1486 }
1487
1488 #[test]
1489 fn sparse_trie_empty_update_multiple_upper_nibbles() {
1490 let paths = (239..=255).map(|b| Nibbles::unpack(B256::repeat_byte(b))).collect::<Vec<_>>();
1491 let value = || Account::default();
1492 let value_encoded = || {
1493 let mut account_rlp = Vec::new();
1494 TrieAccount::from((value(), EMPTY_ROOT_HASH)).encode(&mut account_rlp);
1495 account_rlp
1496 };
1497
1498 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _) =
1499 run_hash_builder(
1500 paths.iter().cloned().zip(std::iter::repeat_with(value)),
1501 Default::default(),
1502 paths.clone(),
1503 );
1504
1505 let mut sparse = RevealedSparseTrie::default().with_updates(true);
1506 for path in &paths {
1507 sparse.update_leaf(path.clone(), value_encoded()).unwrap();
1508 }
1509 let sparse_root = sparse.root();
1510 let sparse_updates = sparse.take_updates();
1511
1512 assert_eq!(sparse_root, hash_builder_root);
1513 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
1514 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
1515 }
1516
1517 #[test]
1518 fn sparse_trie_empty_update_multiple() {
1519 let paths = (0..=255)
1520 .map(|b| {
1521 Nibbles::unpack(if b % 2 == 0 {
1522 B256::repeat_byte(b)
1523 } else {
1524 B256::with_last_byte(b)
1525 })
1526 })
1527 .collect::<Vec<_>>();
1528 let value = || Account::default();
1529 let value_encoded = || {
1530 let mut account_rlp = Vec::new();
1531 TrieAccount::from((value(), EMPTY_ROOT_HASH)).encode(&mut account_rlp);
1532 account_rlp
1533 };
1534
1535 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _) =
1536 run_hash_builder(
1537 paths.iter().sorted_unstable().cloned().zip(std::iter::repeat_with(value)),
1538 Default::default(),
1539 paths.clone(),
1540 );
1541
1542 let mut sparse = RevealedSparseTrie::default().with_updates(true);
1543 for path in &paths {
1544 sparse.update_leaf(path.clone(), value_encoded()).unwrap();
1545 }
1546 let sparse_root = sparse.root();
1547 let sparse_updates = sparse.take_updates();
1548
1549 assert_eq!(sparse_root, hash_builder_root);
1550 pretty_assertions::assert_eq!(
1551 BTreeMap::from_iter(sparse_updates.updated_nodes),
1552 BTreeMap::from_iter(hash_builder_updates.account_nodes)
1553 );
1554 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
1555 }
1556
1557 #[test]
1558 fn sparse_trie_empty_update_repeated() {
1559 let paths = (0..=255).map(|b| Nibbles::unpack(B256::repeat_byte(b))).collect::<Vec<_>>();
1560 let old_value = Account { nonce: 1, ..Default::default() };
1561 let old_value_encoded = {
1562 let mut account_rlp = Vec::new();
1563 TrieAccount::from((old_value, EMPTY_ROOT_HASH)).encode(&mut account_rlp);
1564 account_rlp
1565 };
1566 let new_value = Account { nonce: 2, ..Default::default() };
1567 let new_value_encoded = {
1568 let mut account_rlp = Vec::new();
1569 TrieAccount::from((new_value, EMPTY_ROOT_HASH)).encode(&mut account_rlp);
1570 account_rlp
1571 };
1572
1573 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _) =
1574 run_hash_builder(
1575 paths.iter().cloned().zip(std::iter::repeat_with(|| old_value)),
1576 Default::default(),
1577 paths.clone(),
1578 );
1579
1580 let mut sparse = RevealedSparseTrie::default().with_updates(true);
1581 for path in &paths {
1582 sparse.update_leaf(path.clone(), old_value_encoded.clone()).unwrap();
1583 }
1584 let sparse_root = sparse.root();
1585 let sparse_updates = sparse.updates_ref();
1586
1587 assert_eq!(sparse_root, hash_builder_root);
1588 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
1589 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
1590
1591 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _) =
1592 run_hash_builder(
1593 paths.iter().cloned().zip(std::iter::repeat_with(|| new_value)),
1594 Default::default(),
1595 paths.clone(),
1596 );
1597
1598 for path in &paths {
1599 sparse.update_leaf(path.clone(), new_value_encoded.clone()).unwrap();
1600 }
1601 let sparse_root = sparse.root();
1602 let sparse_updates = sparse.take_updates();
1603
1604 assert_eq!(sparse_root, hash_builder_root);
1605 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
1606 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
1607 }
1608
1609 #[test]
1610 fn sparse_trie_remove_leaf() {
1611 reth_tracing::init_test_tracing();
1612
1613 let mut sparse = RevealedSparseTrie::default();
1614
1615 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
1616
1617 sparse
1618 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone())
1619 .unwrap();
1620 sparse
1621 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone())
1622 .unwrap();
1623 sparse
1624 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone())
1625 .unwrap();
1626 sparse
1627 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone())
1628 .unwrap();
1629 sparse
1630 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone())
1631 .unwrap();
1632 sparse.update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value).unwrap();
1633
1634 pretty_assertions::assert_eq!(
1647 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
1648 BTreeMap::from_iter([
1649 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
1650 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1101.into())),
1651 (
1652 Nibbles::from_nibbles([0x5, 0x0]),
1653 SparseNode::new_ext(Nibbles::from_nibbles([0x2, 0x3]))
1654 ),
1655 (
1656 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3]),
1657 SparseNode::new_branch(0b1010.into())
1658 ),
1659 (
1660 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]),
1661 SparseNode::new_leaf(Nibbles::default())
1662 ),
1663 (
1664 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]),
1665 SparseNode::new_leaf(Nibbles::default())
1666 ),
1667 (
1668 Nibbles::from_nibbles([0x5, 0x2]),
1669 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x1, 0x3]))
1670 ),
1671 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
1672 (
1673 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
1674 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
1675 ),
1676 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
1677 (
1678 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
1679 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
1680 ),
1681 (
1682 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
1683 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
1684 )
1685 ])
1686 );
1687
1688 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3])).unwrap();
1689
1690 pretty_assertions::assert_eq!(
1702 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
1703 BTreeMap::from_iter([
1704 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
1705 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
1706 (
1707 Nibbles::from_nibbles([0x5, 0x0]),
1708 SparseNode::new_ext(Nibbles::from_nibbles([0x2, 0x3]))
1709 ),
1710 (
1711 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3]),
1712 SparseNode::new_branch(0b1010.into())
1713 ),
1714 (
1715 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]),
1716 SparseNode::new_leaf(Nibbles::default())
1717 ),
1718 (
1719 Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]),
1720 SparseNode::new_leaf(Nibbles::default())
1721 ),
1722 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
1723 (
1724 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
1725 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
1726 ),
1727 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
1728 (
1729 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
1730 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
1731 ),
1732 (
1733 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
1734 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
1735 )
1736 ])
1737 );
1738
1739 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1])).unwrap();
1740
1741 pretty_assertions::assert_eq!(
1750 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
1751 BTreeMap::from_iter([
1752 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
1753 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
1754 (
1755 Nibbles::from_nibbles([0x5, 0x0]),
1756 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
1757 ),
1758 (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())),
1759 (
1760 Nibbles::from_nibbles([0x5, 0x3, 0x1]),
1761 SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]))
1762 ),
1763 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
1764 (
1765 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
1766 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
1767 ),
1768 (
1769 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
1770 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
1771 )
1772 ])
1773 );
1774
1775 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2])).unwrap();
1776
1777 pretty_assertions::assert_eq!(
1784 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
1785 BTreeMap::from_iter([
1786 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
1787 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
1788 (
1789 Nibbles::from_nibbles([0x5, 0x0]),
1790 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
1791 ),
1792 (
1793 Nibbles::from_nibbles([0x5, 0x3]),
1794 SparseNode::new_ext(Nibbles::from_nibbles([0x3]))
1795 ),
1796 (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())),
1797 (
1798 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]),
1799 SparseNode::new_leaf(Nibbles::from_nibbles([0x2]))
1800 ),
1801 (
1802 Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]),
1803 SparseNode::new_leaf(Nibbles::from_nibbles([0x0]))
1804 )
1805 ])
1806 );
1807
1808 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0])).unwrap();
1809
1810 pretty_assertions::assert_eq!(
1815 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
1816 BTreeMap::from_iter([
1817 (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))),
1818 (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())),
1819 (
1820 Nibbles::from_nibbles([0x5, 0x0]),
1821 SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]))
1822 ),
1823 (
1824 Nibbles::from_nibbles([0x5, 0x3]),
1825 SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x0, 0x2]))
1826 ),
1827 ])
1828 );
1829
1830 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3])).unwrap();
1831
1832 pretty_assertions::assert_eq!(
1834 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
1835 BTreeMap::from_iter([(
1836 Nibbles::default(),
1837 SparseNode::new_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]))
1838 ),])
1839 );
1840
1841 sparse.remove_leaf(&Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2])).unwrap();
1842
1843 pretty_assertions::assert_eq!(
1845 sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(),
1846 BTreeMap::from_iter([(Nibbles::default(), SparseNode::Empty)])
1847 );
1848 }
1849
1850 #[test]
1851 fn sparse_trie_remove_leaf_blinded() {
1852 let leaf = LeafNode::new(
1853 Nibbles::default(),
1854 alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(),
1855 );
1856 let branch = TrieNode::Branch(BranchNode::new(
1857 vec![
1858 RlpNode::word_rlp(&B256::repeat_byte(1)),
1859 RlpNode::from_raw_rlp(&alloy_rlp::encode(leaf.clone())).unwrap(),
1860 ],
1861 TrieMask::new(0b11),
1862 ));
1863
1864 let mut sparse =
1865 RevealedSparseTrie::from_root(branch.clone(), Some(TrieMask::new(0b01)), false)
1866 .unwrap();
1867
1868 sparse.reveal_node(Nibbles::default(), branch, Some(TrieMask::new(0b01))).unwrap();
1874 sparse.reveal_node(Nibbles::from_nibbles([0x1]), TrieNode::Leaf(leaf), None).unwrap();
1875
1876 assert_matches!(
1878 sparse.remove_leaf(&Nibbles::from_nibbles([0x0])).map_err(|e| e.into_kind()),
1879 Err(SparseTrieErrorKind::BlindedNode { path, hash }) if path == Nibbles::from_nibbles([0x0]) && hash == B256::repeat_byte(1)
1880 );
1881 }
1882
1883 #[test]
1884 fn sparse_trie_remove_leaf_non_existent() {
1885 let leaf = LeafNode::new(
1886 Nibbles::default(),
1887 alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(),
1888 );
1889 let branch = TrieNode::Branch(BranchNode::new(
1890 vec![
1891 RlpNode::word_rlp(&B256::repeat_byte(1)),
1892 RlpNode::from_raw_rlp(&alloy_rlp::encode(leaf.clone())).unwrap(),
1893 ],
1894 TrieMask::new(0b11),
1895 ));
1896
1897 let mut sparse =
1898 RevealedSparseTrie::from_root(branch.clone(), Some(TrieMask::new(0b01)), false)
1899 .unwrap();
1900
1901 sparse.reveal_node(Nibbles::default(), branch, Some(TrieMask::new(0b01))).unwrap();
1907 sparse.reveal_node(Nibbles::from_nibbles([0x1]), TrieNode::Leaf(leaf), None).unwrap();
1908
1909 let sparse_old = sparse.clone();
1911 assert_matches!(sparse.remove_leaf(&Nibbles::from_nibbles([0x2])), Ok(()));
1912 assert_eq!(sparse, sparse_old);
1913 }
1914
1915 #[allow(clippy::type_complexity)]
1916 #[test]
1917 fn sparse_trie_fuzz() {
1918 const KEY_NIBBLES_LEN: usize = 3;
1922
1923 fn test(updates: Vec<(HashMap<Nibbles, Account>, HashSet<Nibbles>)>) {
1924 {
1925 let mut state = BTreeMap::default();
1926 let mut sparse = RevealedSparseTrie::default().with_updates(true);
1927
1928 for (update, keys_to_delete) in updates {
1929 for (key, account) in update.clone() {
1931 let account = TrieAccount::from((account, EMPTY_ROOT_HASH));
1932 let mut account_rlp = Vec::new();
1933 account.encode(&mut account_rlp);
1934 sparse.update_leaf(key, account_rlp).unwrap();
1935 }
1936 let mut updated_sparse = sparse.clone();
1940 let sparse_root = updated_sparse.root();
1941 let sparse_updates = updated_sparse.take_updates();
1942
1943 state.extend(update);
1945 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _) =
1946 run_hash_builder(
1947 state.clone(),
1948 Default::default(),
1949 state.keys().cloned().collect::<Vec<_>>(),
1950 );
1951
1952 assert_eq!(sparse_root, hash_builder_root);
1954 pretty_assertions::assert_eq!(
1956 sparse_updates.updated_nodes,
1957 hash_builder_updates.account_nodes
1958 );
1959 assert_eq_sparse_trie_proof_nodes(&updated_sparse, hash_builder_proof_nodes);
1961
1962 for key in keys_to_delete {
1965 state.remove(&key).unwrap();
1966 sparse.remove_leaf(&key).unwrap();
1967 }
1968
1969 let mut updated_sparse = sparse.clone();
1973 let sparse_root = updated_sparse.root();
1974 let sparse_updates = updated_sparse.take_updates();
1975
1976 let (hash_builder_root, hash_builder_updates, hash_builder_proof_nodes, _) =
1977 run_hash_builder(
1978 state.clone(),
1979 Default::default(),
1980 state.keys().cloned().collect::<Vec<_>>(),
1981 );
1982
1983 assert_eq!(sparse_root, hash_builder_root);
1985 pretty_assertions::assert_eq!(
1987 sparse_updates.updated_nodes,
1988 hash_builder_updates.account_nodes
1989 );
1990 assert_eq_sparse_trie_proof_nodes(&updated_sparse, hash_builder_proof_nodes);
1992 }
1993 }
1994 }
1995
1996 fn transform_updates(
1997 updates: Vec<HashMap<Nibbles, Account>>,
1998 mut rng: impl Rng,
1999 ) -> Vec<(HashMap<Nibbles, Account>, HashSet<Nibbles>)> {
2000 let mut keys = HashSet::new();
2001 updates
2002 .into_iter()
2003 .map(|update| {
2004 keys.extend(update.keys().cloned());
2005
2006 let keys_to_delete_len = update.len() / 2;
2007 let keys_to_delete = (0..keys_to_delete_len)
2008 .map(|_| {
2009 let key = keys.iter().choose(&mut rng).unwrap().clone();
2010 keys.take(&key).unwrap()
2011 })
2012 .collect();
2013
2014 (update, keys_to_delete)
2015 })
2016 .collect::<Vec<_>>()
2017 }
2018
2019 proptest!(ProptestConfig::with_cases(10), |(
2020 updates in proptest::collection::vec(
2021 proptest::collection::hash_map(
2022 any_with::<Nibbles>(SizeRange::new(KEY_NIBBLES_LEN..=KEY_NIBBLES_LEN)).prop_map(pad_nibbles_right),
2023 arb::<Account>(),
2024 1..100,
2025 ).prop_map(HashMap::from_iter),
2026 1..100,
2027 ).prop_perturb(transform_updates)
2028 )| {
2029 test(updates)
2030 });
2031 }
2032
2033 #[test]
2045 fn sparse_trie_reveal_node_1() {
2046 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00]));
2047 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01]));
2048 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x02]));
2049 let value = || Account::default();
2050 let value_encoded = || {
2051 let mut account_rlp = Vec::new();
2052 TrieAccount::from((value(), EMPTY_ROOT_HASH)).encode(&mut account_rlp);
2053 account_rlp
2054 };
2055
2056 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks) = run_hash_builder(
2058 [(key1(), value()), (key3(), value())],
2059 Default::default(),
2060 [Nibbles::default()],
2061 );
2062 let mut sparse = RevealedSparseTrie::from_root(
2063 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
2064 branch_node_hash_masks.get(&Nibbles::default()).copied(),
2065 false,
2066 )
2067 .unwrap();
2068
2069 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks) =
2071 run_hash_builder([(key1(), value()), (key3(), value())], Default::default(), [key1()]);
2072 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
2073 let hash_mask = branch_node_hash_masks.get(&path).copied();
2074 sparse.reveal_node(path, TrieNode::decode(&mut &node[..]).unwrap(), hash_mask).unwrap();
2075 }
2076
2077 assert_eq!(
2079 sparse.nodes.get(&Nibbles::default()),
2080 Some(&SparseNode::new_branch(0b101.into()))
2081 );
2082
2083 sparse.update_leaf(key2(), value_encoded()).unwrap();
2085
2086 assert_eq!(
2088 sparse.nodes.get(&Nibbles::default()),
2089 Some(&SparseNode::new_branch(0b111.into()))
2090 );
2091
2092 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks) =
2094 run_hash_builder([(key1(), value()), (key3(), value())], Default::default(), [key3()]);
2095 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
2096 let hash_mask = branch_node_hash_masks.get(&path).copied();
2097 sparse.reveal_node(path, TrieNode::decode(&mut &node[..]).unwrap(), hash_mask).unwrap();
2098 }
2099
2100 assert_eq!(
2102 sparse.nodes.get(&Nibbles::default()),
2103 Some(&SparseNode::new_branch(0b111.into()))
2104 );
2105
2106 let (_, _, hash_builder_proof_nodes, _) = run_hash_builder(
2109 [(key1(), value()), (key2(), value()), (key3(), value())],
2110 Default::default(),
2111 [key1(), key2(), key3()],
2112 );
2113
2114 assert_eq_sparse_trie_proof_nodes(&sparse, hash_builder_proof_nodes);
2115 }
2116
2117 #[test]
2128 fn sparse_trie_reveal_node_2() {
2129 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x00]));
2130 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x01]));
2131 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x02]));
2132 let value = || Account::default();
2133
2134 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks) = run_hash_builder(
2136 [(key1(), value()), (key2(), value()), (key3(), value())],
2137 Default::default(),
2138 [Nibbles::default()],
2139 );
2140 let mut sparse = RevealedSparseTrie::from_root(
2141 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
2142 branch_node_hash_masks.get(&Nibbles::default()).copied(),
2143 false,
2144 )
2145 .unwrap();
2146
2147 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks) = run_hash_builder(
2150 [(key1(), value()), (key2(), value()), (key3(), value())],
2151 Default::default(),
2152 [key1(), Nibbles::from_nibbles_unchecked([0x01])],
2153 );
2154 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
2155 let hash_mask = branch_node_hash_masks.get(&path).copied();
2156 sparse.reveal_node(path, TrieNode::decode(&mut &node[..]).unwrap(), hash_mask).unwrap();
2157 }
2158
2159 assert_eq!(
2161 sparse.nodes.get(&Nibbles::default()),
2162 Some(&SparseNode::new_branch(0b11.into()))
2163 );
2164
2165 sparse.remove_leaf(&key1()).unwrap();
2167
2168 assert_eq!(
2170 sparse.nodes.get(&Nibbles::default()),
2171 Some(&SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x01])))
2172 );
2173
2174 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks) = run_hash_builder(
2176 [(key1(), value()), (key2(), value()), (key3(), value())],
2177 Default::default(),
2178 [key2()],
2179 );
2180 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
2181 let hash_mask = branch_node_hash_masks.get(&path).copied();
2182 sparse.reveal_node(path, TrieNode::decode(&mut &node[..]).unwrap(), hash_mask).unwrap();
2183 }
2184
2185 assert_eq!(
2187 sparse.nodes.get(&Nibbles::default()),
2188 Some(&SparseNode::new_ext(Nibbles::from_nibbles_unchecked([0x01])))
2189 );
2190 }
2191
2192 #[test]
2201 fn sparse_trie_reveal_node_3() {
2202 let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x01]));
2203 let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x02]));
2204 let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x00]));
2205 let value = || Account::default();
2206 let value_encoded = || {
2207 let mut account_rlp = Vec::new();
2208 TrieAccount::from((value(), EMPTY_ROOT_HASH)).encode(&mut account_rlp);
2209 account_rlp
2210 };
2211
2212 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks) = run_hash_builder(
2214 [(key1(), value()), (key2(), value())],
2215 Default::default(),
2216 [Nibbles::default()],
2217 );
2218 let mut sparse = RevealedSparseTrie::from_root(
2219 TrieNode::decode(&mut &hash_builder_proof_nodes.nodes_sorted()[0].1[..]).unwrap(),
2220 branch_node_hash_masks.get(&Nibbles::default()).copied(),
2221 false,
2222 )
2223 .unwrap();
2224
2225 assert_matches!(
2227 sparse.nodes.get(&Nibbles::default()),
2228 Some(SparseNode::Extension { key, hash: None }) if *key == Nibbles::from_nibbles([0x00])
2229 );
2230
2231 sparse.update_leaf(key3(), value_encoded()).unwrap();
2233
2234 assert_matches!(
2236 sparse.nodes.get(&Nibbles::default()),
2237 Some(SparseNode::Branch { state_mask, hash: None, store_in_db_trie: None }) if *state_mask == TrieMask::new(0b11)
2238 );
2239
2240 let (_, _, hash_builder_proof_nodes, branch_node_hash_masks) =
2242 run_hash_builder([(key1(), value()), (key2(), value())], Default::default(), [key1()]);
2243 for (path, node) in hash_builder_proof_nodes.nodes_sorted() {
2244 let hash_mask = branch_node_hash_masks.get(&path).copied();
2245 sparse.reveal_node(path, TrieNode::decode(&mut &node[..]).unwrap(), hash_mask).unwrap();
2246 }
2247
2248 assert_matches!(
2250 sparse.nodes.get(&Nibbles::default()),
2251 Some(SparseNode::Branch { state_mask, hash: None, store_in_db_trie: None }) if *state_mask == TrieMask::new(0b11)
2252 );
2253 }
2254
2255 #[test]
2256 fn sparse_trie_get_changed_nodes_at_depth() {
2257 let mut sparse = RevealedSparseTrie::default();
2258
2259 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
2260
2261 sparse
2274 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone())
2275 .unwrap();
2276 sparse
2277 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone())
2278 .unwrap();
2279 sparse
2280 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone())
2281 .unwrap();
2282 sparse
2283 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone())
2284 .unwrap();
2285 sparse
2286 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone())
2287 .unwrap();
2288 sparse.update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value).unwrap();
2289
2290 assert_eq!(
2291 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 0),
2292 vec![Nibbles::default()]
2293 );
2294 assert_eq!(
2295 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 1),
2296 vec![Nibbles::from_nibbles_unchecked([0x5])]
2297 );
2298 assert_eq!(
2299 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 2),
2300 vec![
2301 Nibbles::from_nibbles_unchecked([0x5, 0x0]),
2302 Nibbles::from_nibbles_unchecked([0x5, 0x2]),
2303 Nibbles::from_nibbles_unchecked([0x5, 0x3])
2304 ]
2305 );
2306 assert_eq!(
2307 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 3),
2308 vec![
2309 Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3]),
2310 Nibbles::from_nibbles_unchecked([0x5, 0x2]),
2311 Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x1]),
2312 Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3])
2313 ]
2314 );
2315 assert_eq!(
2316 sparse.get_changed_nodes_at_depth(&mut PrefixSet::default(), 4),
2317 vec![
2318 Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3, 0x1]),
2319 Nibbles::from_nibbles_unchecked([0x5, 0x0, 0x2, 0x3, 0x3]),
2320 Nibbles::from_nibbles_unchecked([0x5, 0x2]),
2321 Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x1]),
2322 Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3, 0x0]),
2323 Nibbles::from_nibbles_unchecked([0x5, 0x3, 0x3, 0x2])
2324 ]
2325 );
2326 }
2327
2328 #[test]
2329 fn hash_builder_branch_hash_mask() {
2330 let key1 = || pad_nibbles_left(Nibbles::from_nibbles_unchecked([0x00]));
2331 let key2 = || pad_nibbles_left(Nibbles::from_nibbles_unchecked([0x01]));
2332 let value = || Account { bytecode_hash: Some(B256::repeat_byte(1)), ..Default::default() };
2333 let value_encoded = || {
2334 let mut account_rlp = Vec::new();
2335 TrieAccount::from((value(), EMPTY_ROOT_HASH)).encode(&mut account_rlp);
2336 account_rlp
2337 };
2338
2339 let (hash_builder_root, hash_builder_updates, _, _) = run_hash_builder(
2340 [(key1(), value()), (key2(), value())],
2341 Default::default(),
2342 [Nibbles::default()],
2343 );
2344 let mut sparse = RevealedSparseTrie::default();
2345 sparse.update_leaf(key1(), value_encoded()).unwrap();
2346 sparse.update_leaf(key2(), value_encoded()).unwrap();
2347 let sparse_root = sparse.root();
2348 let sparse_updates = sparse.take_updates();
2349
2350 assert_eq!(sparse_root, hash_builder_root);
2351 assert_eq!(sparse_updates.updated_nodes, hash_builder_updates.account_nodes);
2352 }
2353
2354 #[test]
2355 fn sparse_trie_wipe() {
2356 let mut sparse = RevealedSparseTrie::default().with_updates(true);
2357
2358 let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();
2359
2360 sparse
2373 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone())
2374 .unwrap();
2375 sparse
2376 .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone())
2377 .unwrap();
2378 sparse
2379 .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone())
2380 .unwrap();
2381 sparse
2382 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone())
2383 .unwrap();
2384 sparse
2385 .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone())
2386 .unwrap();
2387 sparse.update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value).unwrap();
2388
2389 sparse.wipe();
2390
2391 assert_eq!(sparse.root(), EMPTY_ROOT_HASH);
2392 }
2393}