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<
101 'static,
102 DatabaseTrieCursorFactory<&'a TX>,
103 DatabaseHashedCursorFactory<&'a TX>,
104 >
105{
106 fn from_tx(tx: &'a TX, address: Address) -> Self {
107 Self::new(DatabaseTrieCursorFactory::new(tx), DatabaseHashedCursorFactory::new(tx), address)
108 }
109
110 fn overlay_storage_proof(
111 tx: &'a TX,
112 address: Address,
113 slot: B256,
114 storage: HashedStorage,
115 ) -> Result<reth_trie::StorageProof, StateProofError> {
116 let hashed_address = keccak256(address);
117 let prefix_set = storage.construct_prefix_set();
118 let state_sorted = HashedPostStateSorted::new(
119 Default::default(),
120 HashMap::from_iter([(hashed_address, storage.into_sorted())]),
121 );
122 StorageProof::new(
123 DatabaseTrieCursorFactory::new(tx),
124 HashedPostStateCursorFactory::new(DatabaseHashedCursorFactory::new(tx), &state_sorted),
125 address,
126 )
127 .with_prefix_set_mut(prefix_set)
128 .storage_proof(slot)
129 }
130
131 fn overlay_storage_multiproof(
132 tx: &'a TX,
133 address: Address,
134 slots: &[B256],
135 storage: HashedStorage,
136 ) -> Result<StorageMultiProof, StateProofError> {
137 let hashed_address = keccak256(address);
138 let targets = slots.iter().map(keccak256).collect();
139 let prefix_set = storage.construct_prefix_set();
140 let state_sorted = HashedPostStateSorted::new(
141 Default::default(),
142 HashMap::from_iter([(hashed_address, storage.into_sorted())]),
143 );
144 StorageProof::new(
145 DatabaseTrieCursorFactory::new(tx),
146 HashedPostStateCursorFactory::new(DatabaseHashedCursorFactory::new(tx), &state_sorted),
147 address,
148 )
149 .with_prefix_set_mut(prefix_set)
150 .storage_multiproof(targets)
151 }
152}