reth_trie/proof/
trie_node.rs1use super::{Proof, StorageProof};
2use crate::{hashed_cursor::HashedCursorFactory, trie_cursor::TrieCursorFactory};
3use alloy_primitives::{map::HashSet, B256};
4use reth_execution_errors::{SparseTrieError, SparseTrieErrorKind};
5use reth_trie_common::{MultiProofTargets, Nibbles};
6use reth_trie_sparse::provider::{
7 pad_path_to_key, RevealedNode, TrieNodeProvider, TrieNodeProviderFactory,
8};
9use std::time::Instant;
10use tracing::{enabled, trace, Level};
11
12#[derive(Debug, Clone)]
14pub struct ProofTrieNodeProviderFactory<T, H> {
15 trie_cursor_factory: T,
17 hashed_cursor_factory: H,
19}
20
21impl<T, H> ProofTrieNodeProviderFactory<T, H> {
22 pub const fn new(trie_cursor_factory: T, hashed_cursor_factory: H) -> Self {
24 Self { trie_cursor_factory, hashed_cursor_factory }
25 }
26}
27
28impl<T, H> TrieNodeProviderFactory for ProofTrieNodeProviderFactory<T, H>
29where
30 T: TrieCursorFactory + Clone,
31 H: HashedCursorFactory + Clone,
32{
33 type AccountNodeProvider = ProofBlindedAccountProvider<T, H>;
34 type StorageNodeProvider = ProofBlindedStorageProvider<T, H>;
35
36 fn account_node_provider(&self) -> Self::AccountNodeProvider {
37 ProofBlindedAccountProvider {
38 trie_cursor_factory: self.trie_cursor_factory.clone(),
39 hashed_cursor_factory: self.hashed_cursor_factory.clone(),
40 }
41 }
42
43 fn storage_node_provider(&self, account: B256) -> Self::StorageNodeProvider {
44 ProofBlindedStorageProvider {
45 trie_cursor_factory: self.trie_cursor_factory.clone(),
46 hashed_cursor_factory: self.hashed_cursor_factory.clone(),
47 account,
48 }
49 }
50}
51
52#[derive(Debug)]
54pub struct ProofBlindedAccountProvider<T, H> {
55 trie_cursor_factory: T,
57 hashed_cursor_factory: H,
59}
60
61impl<T, H> ProofBlindedAccountProvider<T, H> {
62 pub const fn new(trie_cursor_factory: T, hashed_cursor_factory: H) -> Self {
64 Self { trie_cursor_factory, hashed_cursor_factory }
65 }
66}
67
68impl<T, H> TrieNodeProvider for ProofBlindedAccountProvider<T, H>
69where
70 T: TrieCursorFactory,
71 H: HashedCursorFactory,
72{
73 fn trie_node(&self, path: &Nibbles) -> Result<Option<RevealedNode>, SparseTrieError> {
74 let start = enabled!(target: "trie::proof::blinded", Level::TRACE).then(Instant::now);
75
76 let targets = MultiProofTargets::from_iter([(pad_path_to_key(path), HashSet::default())]);
77 let mut proof = Proof::new(&self.trie_cursor_factory, &self.hashed_cursor_factory)
78 .with_branch_node_masks(true)
79 .multiproof(targets)
80 .map_err(|error| SparseTrieErrorKind::Other(Box::new(error)))?;
81 let node = proof.account_subtree.into_inner().remove(path);
82 let masks = proof.branch_node_masks.remove(path);
83 let hash_mask = masks.map(|m| m.hash_mask);
84 let tree_mask = masks.map(|m| m.tree_mask);
85
86 trace!(
87 target: "trie::proof::blinded",
88 elapsed = ?start.unwrap().elapsed(),
89 ?path,
90 ?node,
91 ?tree_mask,
92 ?hash_mask,
93 "Blinded node for account trie"
94 );
95 Ok(node.map(|node| RevealedNode { node, tree_mask, hash_mask }))
96 }
97}
98
99#[derive(Debug)]
101pub struct ProofBlindedStorageProvider<T, H> {
102 trie_cursor_factory: T,
104 hashed_cursor_factory: H,
106 account: B256,
108}
109
110impl<T, H> ProofBlindedStorageProvider<T, H> {
111 pub const fn new(trie_cursor_factory: T, hashed_cursor_factory: H, account: B256) -> Self {
113 Self { trie_cursor_factory, hashed_cursor_factory, account }
114 }
115}
116
117impl<T, H> TrieNodeProvider for ProofBlindedStorageProvider<T, H>
118where
119 T: TrieCursorFactory,
120 H: HashedCursorFactory,
121{
122 fn trie_node(&self, path: &Nibbles) -> Result<Option<RevealedNode>, SparseTrieError> {
123 let start = enabled!(target: "trie::proof::blinded", Level::TRACE).then(Instant::now);
124
125 let targets = HashSet::from_iter([pad_path_to_key(path)]);
126 let mut proof = StorageProof::new_hashed(
127 &self.trie_cursor_factory,
128 &self.hashed_cursor_factory,
129 self.account,
130 )
131 .with_branch_node_masks(true)
132 .storage_multiproof(targets)
133 .map_err(|error| SparseTrieErrorKind::Other(Box::new(error)))?;
134 let node = proof.subtree.into_inner().remove(path);
135 let masks = proof.branch_node_masks.remove(path);
136 let hash_mask = masks.map(|m| m.hash_mask);
137 let tree_mask = masks.map(|m| m.tree_mask);
138
139 trace!(
140 target: "trie::proof::blinded",
141 account = ?self.account,
142 elapsed = ?start.unwrap().elapsed(),
143 ?path,
144 ?node,
145 ?tree_mask,
146 ?hash_mask,
147 "Blinded node for storage trie"
148 );
149 Ok(node.map(|node| RevealedNode { node, tree_mask, hash_mask }))
150 }
151}