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 + Send + Sync,
31 H: HashedCursorFactory + Clone + Send + Sync,
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 tree_mask = proof.branch_node_tree_masks.remove(path);
83 let hash_mask = proof.branch_node_hash_masks.remove(path);
84
85 trace!(
86 target: "trie::proof::blinded",
87 elapsed = ?start.unwrap().elapsed(),
88 ?path,
89 ?node,
90 ?tree_mask,
91 ?hash_mask,
92 "Blinded node for account trie"
93 );
94 Ok(node.map(|node| RevealedNode { node, tree_mask, hash_mask }))
95 }
96}
97
98#[derive(Debug)]
100pub struct ProofBlindedStorageProvider<T, H> {
101 trie_cursor_factory: T,
103 hashed_cursor_factory: H,
105 account: B256,
107}
108
109impl<T, H> ProofBlindedStorageProvider<T, H> {
110 pub const fn new(trie_cursor_factory: T, hashed_cursor_factory: H, account: B256) -> Self {
112 Self { trie_cursor_factory, hashed_cursor_factory, account }
113 }
114}
115
116impl<T, H> TrieNodeProvider for ProofBlindedStorageProvider<T, H>
117where
118 T: TrieCursorFactory,
119 H: HashedCursorFactory,
120{
121 fn trie_node(&self, path: &Nibbles) -> Result<Option<RevealedNode>, SparseTrieError> {
122 let start = enabled!(target: "trie::proof::blinded", Level::TRACE).then(Instant::now);
123
124 let targets = HashSet::from_iter([pad_path_to_key(path)]);
125 let mut proof = StorageProof::new_hashed(
126 &self.trie_cursor_factory,
127 &self.hashed_cursor_factory,
128 self.account,
129 )
130 .with_branch_node_masks(true)
131 .storage_multiproof(targets)
132 .map_err(|error| SparseTrieErrorKind::Other(Box::new(error)))?;
133 let node = proof.subtree.into_inner().remove(path);
134 let tree_mask = proof.branch_node_tree_masks.remove(path);
135 let hash_mask = proof.branch_node_hash_masks.remove(path);
136
137 trace!(
138 target: "trie::proof::blinded",
139 account = ?self.account,
140 elapsed = ?start.unwrap().elapsed(),
141 ?path,
142 ?node,
143 ?tree_mask,
144 ?hash_mask,
145 "Blinded node for storage trie"
146 );
147 Ok(node.map(|node| RevealedNode { node, tree_mask, hash_mask }))
148 }
149}