1use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory};
2use alloy_primitives::{keccak256, map::HashMap, Address, B256};
3use reth_db_api::transaction::DbTx;
4use reth_execution_errors::StateProofError;
5use reth_trie::{
6 hashed_cursor::HashedPostStateCursorFactory,
7 proof::{Proof, StorageProof},
8 trie_cursor::InMemoryTrieCursorFactory,
9 AccountProof, HashedPostStateSorted, HashedStorage, MultiProof, MultiProofTargets,
10 StorageMultiProof, TrieInput,
11};
12
13pub trait DatabaseProof<'a> {
15 type Tx;
17
18 fn from_tx(tx: &'a Self::Tx) -> Self;
20
21 fn overlay_account_proof(
23 &self,
24 input: TrieInput,
25 address: Address,
26 slots: &[B256],
27 ) -> Result<AccountProof, StateProofError>;
28
29 fn overlay_multiproof(
31 &self,
32 input: TrieInput,
33 targets: MultiProofTargets,
34 ) -> Result<MultiProof, StateProofError>;
35}
36
37impl<'a, TX: DbTx> DatabaseProof<'a>
38 for Proof<DatabaseTrieCursorFactory<&'a TX>, DatabaseHashedCursorFactory<&'a TX>>
39{
40 type Tx = TX;
41
42 fn from_tx(tx: &'a Self::Tx) -> Self {
43 Self::new(DatabaseTrieCursorFactory::new(tx), DatabaseHashedCursorFactory::new(tx))
44 }
45 fn overlay_account_proof(
46 &self,
47 input: TrieInput,
48 address: Address,
49 slots: &[B256],
50 ) -> Result<AccountProof, StateProofError> {
51 let nodes_sorted = input.nodes.into_sorted();
52 let state_sorted = input.state.into_sorted();
53 Proof::new(
54 InMemoryTrieCursorFactory::new(self.trie_cursor_factory().clone(), &nodes_sorted),
55 HashedPostStateCursorFactory::new(self.hashed_cursor_factory().clone(), &state_sorted),
56 )
57 .with_prefix_sets_mut(input.prefix_sets)
58 .account_proof(address, slots)
59 }
60
61 fn overlay_multiproof(
62 &self,
63 input: TrieInput,
64 targets: MultiProofTargets,
65 ) -> Result<MultiProof, StateProofError> {
66 let nodes_sorted = input.nodes.into_sorted();
67 let state_sorted = input.state.into_sorted();
68 Proof::new(
69 InMemoryTrieCursorFactory::new(self.trie_cursor_factory().clone(), &nodes_sorted),
70 HashedPostStateCursorFactory::new(self.hashed_cursor_factory().clone(), &state_sorted),
71 )
72 .with_prefix_sets_mut(input.prefix_sets)
73 .multiproof(targets)
74 }
75}
76
77pub trait DatabaseStorageProof<'a, TX> {
79 fn from_tx(tx: &'a TX, address: Address) -> Self;
81
82 fn overlay_storage_proof(
84 tx: &'a TX,
85 address: Address,
86 slot: B256,
87 storage: HashedStorage,
88 ) -> Result<reth_trie::StorageProof, StateProofError>;
89
90 fn overlay_storage_multiproof(
92 tx: &'a TX,
93 address: Address,
94 slots: &[B256],
95 storage: HashedStorage,
96 ) -> Result<StorageMultiProof, StateProofError>;
97}
98
99impl<'a, TX: DbTx> DatabaseStorageProof<'a, TX>
100 for StorageProof<DatabaseTrieCursorFactory<&'a TX>, DatabaseHashedCursorFactory<&'a TX>>
101{
102 fn from_tx(tx: &'a TX, address: Address) -> Self {
103 Self::new(DatabaseTrieCursorFactory::new(tx), DatabaseHashedCursorFactory::new(tx), address)
104 }
105
106 fn overlay_storage_proof(
107 tx: &'a TX,
108 address: Address,
109 slot: B256,
110 storage: HashedStorage,
111 ) -> Result<reth_trie::StorageProof, StateProofError> {
112 let hashed_address = keccak256(address);
113 let prefix_set = storage.construct_prefix_set();
114 let state_sorted = HashedPostStateSorted::new(
115 Default::default(),
116 HashMap::from_iter([(hashed_address, storage.into_sorted())]),
117 );
118 Self::from_tx(tx, address)
119 .with_hashed_cursor_factory(HashedPostStateCursorFactory::new(
120 DatabaseHashedCursorFactory::new(tx),
121 &state_sorted,
122 ))
123 .with_prefix_set_mut(prefix_set)
124 .storage_proof(slot)
125 }
126
127 fn overlay_storage_multiproof(
128 tx: &'a TX,
129 address: Address,
130 slots: &[B256],
131 storage: HashedStorage,
132 ) -> Result<StorageMultiProof, StateProofError> {
133 let hashed_address = keccak256(address);
134 let targets = slots.iter().map(keccak256).collect();
135 let prefix_set = storage.construct_prefix_set();
136 let state_sorted = HashedPostStateSorted::new(
137 Default::default(),
138 HashMap::from_iter([(hashed_address, storage.into_sorted())]),
139 );
140 Self::from_tx(tx, address)
141 .with_hashed_cursor_factory(HashedPostStateCursorFactory::new(
142 DatabaseHashedCursorFactory::new(tx),
143 &state_sorted,
144 ))
145 .with_prefix_set_mut(prefix_set)
146 .storage_multiproof(targets)
147 }
148}