1use revm::{
21 context::{BlockEnv, CfgEnv, TxEnv},
22 database::CacheDB,
23 database_interface::DBErrorMarker,
24 primitives::{Address, HashMap, B256, U256},
25 state::{Account, AccountInfo, Bytecode},
26 Context, Database, DatabaseCommit, DatabaseRef,
27};
28use std::{fmt, sync::Arc};
29
30pub type EdbContext<DB> = Context<BlockEnv, TxEnv, CfgEnv, CacheDB<DB>>;
32
33pub type DerivedContext<DB> = EdbContext<CacheDB<Arc<CacheDB<DB>>>>;
36
37pub fn relax_evm_constraints<DB: Database + DatabaseRef>(
39 context: &mut EdbContext<DB>,
40 tx: &mut TxEnv,
41) {
42 relax_evm_context_constraints(context);
43 relax_evm_tx_constraints(tx);
44}
45
46pub fn relax_evm_context_constraints<DB: Database + DatabaseRef>(context: &mut EdbContext<DB>) {
48 let cfg = &mut context.cfg;
49 cfg.disable_base_fee = true;
50 cfg.disable_block_gas_limit = true;
51 cfg.tx_gas_limit_cap = Some(u64::MAX);
52 cfg.limit_contract_initcode_size = Some(usize::MAX);
53 cfg.limit_contract_code_size = Some(usize::MAX);
54}
55
56pub fn disable_nonce_check<DB: Database + DatabaseRef>(context: &mut EdbContext<DB>) {
58 context.cfg.disable_nonce_check = true;
59}
60
61pub fn relax_evm_tx_constraints(tx: &mut TxEnv) {
63 tx.gas_limit = u64::MAX; tx.gas_price = 0; tx.gas_priority_fee = Some(0); }
67
68#[derive(Clone, Debug)]
70pub struct EdbDBError {
71 message: String,
72}
73
74impl EdbDBError {
75 pub fn new(message: impl Into<String>) -> Self {
77 Self { message: message.into() }
78 }
79
80 pub fn from_error<E: std::error::Error>(err: E) -> Self {
82 Self::new(err.to_string())
83 }
84}
85
86impl fmt::Display for EdbDBError {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 write!(f, "EdbDB Error: {}", self.message)
89 }
90}
91
92impl std::error::Error for EdbDBError {}
93
94impl DBErrorMarker for EdbDBError {}
95
96#[derive(Clone)]
99pub struct EdbDB<DB> {
100 inner: DB,
101}
102
103impl<DB> EdbDB<DB> {
104 pub fn new(inner: DB) -> Self {
106 Self { inner }
107 }
108
109 pub fn inner(&self) -> &DB {
111 &self.inner
112 }
113
114 pub fn inner_mut(&mut self) -> &mut DB {
116 &mut self.inner
117 }
118
119 pub fn into_inner(self) -> DB {
121 self.inner
122 }
123}
124
125impl<DB> Database for EdbDB<DB>
126where
127 DB: Database,
128 <DB as Database>::Error: std::error::Error,
129{
130 type Error = EdbDBError;
131
132 fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
133 self.inner.basic(address).map_err(EdbDBError::from_error)
134 }
135
136 fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
137 self.inner.code_by_hash(code_hash).map_err(EdbDBError::from_error)
138 }
139
140 fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
141 self.inner.storage(address, index).map_err(EdbDBError::from_error)
142 }
143
144 fn block_hash(&mut self, block: u64) -> Result<B256, Self::Error> {
145 self.inner.block_hash(block).map_err(EdbDBError::from_error)
146 }
147}
148
149impl<DB> DatabaseCommit for EdbDB<DB>
150where
151 DB: DatabaseCommit + Database,
152 <DB as Database>::Error: std::error::Error,
153{
154 fn commit(&mut self, changes: HashMap<Address, Account>) {
155 self.inner.commit(changes)
156 }
157}
158
159impl<DB> DatabaseRef for EdbDB<DB>
160where
161 DB: DatabaseRef + Database,
162 <DB as Database>::Error: std::error::Error,
163{
164 type Error = EdbDBError;
165
166 fn basic_ref(&self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
167 self.inner.basic_ref(address).map_err(EdbDBError::from_error)
168 }
169
170 fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error> {
171 self.inner.code_by_hash_ref(code_hash).map_err(EdbDBError::from_error)
172 }
173
174 fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error> {
175 self.inner.storage_ref(address, index).map_err(EdbDBError::from_error)
176 }
177
178 fn block_hash_ref(&self, number: u64) -> Result<B256, Self::Error> {
179 self.inner.block_hash_ref(number).map_err(EdbDBError::from_error)
180 }
181}