1use crate::{
4 cfg::GasParams,
5 context::{SStoreResult, SelfDestructResult, StateLoad},
6 journaled_state::{AccountInfoLoad, AccountLoad},
7};
8use auto_impl::auto_impl;
9use primitives::{hardfork::SpecId, Address, Bytes, Log, StorageKey, StorageValue, B256, U256};
10use state::Bytecode;
11
12#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub enum LoadError {
16 DBError,
18 ColdLoadSkipped,
20}
21
22#[auto_impl(&mut, Box)]
28pub trait Host {
29 fn basefee(&self) -> U256;
33 fn blob_gasprice(&self) -> U256;
35 fn gas_limit(&self) -> U256;
37 fn difficulty(&self) -> U256;
39 fn prevrandao(&self) -> Option<U256>;
41 fn block_number(&self) -> U256;
43 fn timestamp(&self) -> U256;
45 fn beneficiary(&self) -> Address;
47 fn slot_num(&self) -> U256;
49 fn chain_id(&self) -> U256;
51
52 fn effective_gas_price(&self) -> U256;
56 fn caller(&self) -> Address;
58 fn blob_hash(&self, number: usize) -> Option<U256>;
60
61 fn max_initcode_size(&self) -> usize;
65
66 fn gas_params(&self) -> &GasParams;
68
69 fn block_hash(&mut self, number: u64) -> Option<B256>;
73
74 fn selfdestruct(
78 &mut self,
79 address: Address,
80 target: Address,
81 skip_cold_load: bool,
82 ) -> Result<StateLoad<SelfDestructResult>, LoadError>;
83
84 fn log(&mut self, log: Log);
86
87 fn sstore_skip_cold_load(
89 &mut self,
90 address: Address,
91 key: StorageKey,
92 value: StorageValue,
93 skip_cold_load: bool,
94 ) -> Result<StateLoad<SStoreResult>, LoadError>;
95
96 fn sstore(
98 &mut self,
99 address: Address,
100 key: StorageKey,
101 value: StorageValue,
102 ) -> Option<StateLoad<SStoreResult>> {
103 self.sstore_skip_cold_load(address, key, value, false).ok()
104 }
105
106 fn sload_skip_cold_load(
108 &mut self,
109 address: Address,
110 key: StorageKey,
111 skip_cold_load: bool,
112 ) -> Result<StateLoad<StorageValue>, LoadError>;
113
114 fn sload(&mut self, address: Address, key: StorageKey) -> Option<StateLoad<StorageValue>> {
116 self.sload_skip_cold_load(address, key, false).ok()
117 }
118
119 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue);
121
122 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue;
124
125 fn load_account_info_skip_cold_load(
134 &mut self,
135 address: Address,
136 load_code: bool,
137 skip_cold_load: bool,
138 ) -> Result<AccountInfoLoad<'_>, LoadError>;
139
140 #[inline]
142 fn balance(&mut self, address: Address) -> Option<StateLoad<U256>> {
143 self.load_account_info_skip_cold_load(address, false, false)
144 .ok()
145 .map(|load| load.into_state_load(|i| i.balance))
146 }
147
148 #[inline]
150 fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>> {
151 let account = self
152 .load_account_info_skip_cold_load(address, true, false)
153 .ok()?;
154
155 let mut account_load = StateLoad::new(
156 AccountLoad {
157 is_delegate_account_cold: None,
158 is_empty: account.is_empty,
159 },
160 account.is_cold,
161 );
162
163 if let Some(address) = account.code.as_ref().and_then(Bytecode::eip7702_address) {
165 let delegate_account = self
166 .load_account_info_skip_cold_load(address, true, false)
167 .ok()?;
168 account_load.data.is_delegate_account_cold = Some(delegate_account.is_cold);
169 account_load.data.is_empty = delegate_account.is_empty;
170 }
171
172 Some(account_load)
173 }
174
175 #[inline]
177 fn load_account_code(&mut self, address: Address) -> Option<StateLoad<Bytes>> {
178 self.load_account_info_skip_cold_load(address, true, false)
179 .ok()
180 .map(|load| {
181 load.into_state_load(|i| {
182 i.code
183 .as_ref()
184 .map(|b| b.original_bytes())
185 .unwrap_or_default()
186 })
187 })
188 }
189
190 #[inline]
192 fn load_account_code_hash(&mut self, address: Address) -> Option<StateLoad<B256>> {
193 self.load_account_info_skip_cold_load(address, false, false)
194 .ok()
195 .map(|load| {
196 load.into_state_load(|i| {
197 if i.is_empty() {
198 B256::ZERO
199 } else {
200 i.code_hash
201 }
202 })
203 })
204 }
205}
206
207#[derive(Default, Debug)]
209pub struct DummyHost {
210 gas_params: GasParams,
211}
212
213impl DummyHost {
214 pub fn new(spec: SpecId) -> Self {
216 Self {
217 gas_params: GasParams::new_spec(spec),
218 }
219 }
220}
221
222impl Host for DummyHost {
223 fn basefee(&self) -> U256 {
224 U256::ZERO
225 }
226
227 fn blob_gasprice(&self) -> U256 {
228 U256::ZERO
229 }
230
231 fn gas_limit(&self) -> U256 {
232 U256::ZERO
233 }
234
235 fn gas_params(&self) -> &GasParams {
236 &self.gas_params
237 }
238
239 fn difficulty(&self) -> U256 {
240 U256::ZERO
241 }
242
243 fn prevrandao(&self) -> Option<U256> {
244 None
245 }
246
247 fn block_number(&self) -> U256 {
248 U256::ZERO
249 }
250
251 fn timestamp(&self) -> U256 {
252 U256::ZERO
253 }
254
255 fn beneficiary(&self) -> Address {
256 Address::ZERO
257 }
258
259 fn slot_num(&self) -> U256 {
260 U256::ZERO
261 }
262
263 fn chain_id(&self) -> U256 {
264 U256::ZERO
265 }
266
267 fn effective_gas_price(&self) -> U256 {
268 U256::ZERO
269 }
270
271 fn caller(&self) -> Address {
272 Address::ZERO
273 }
274
275 fn blob_hash(&self, _number: usize) -> Option<U256> {
276 None
277 }
278
279 fn max_initcode_size(&self) -> usize {
280 0
281 }
282
283 fn block_hash(&mut self, _number: u64) -> Option<B256> {
284 None
285 }
286
287 fn selfdestruct(
288 &mut self,
289 _address: Address,
290 _target: Address,
291 _skip_cold_load: bool,
292 ) -> Result<StateLoad<SelfDestructResult>, LoadError> {
293 Err(LoadError::ColdLoadSkipped)
294 }
295
296 fn log(&mut self, _log: Log) {}
297
298 fn tstore(&mut self, _address: Address, _key: StorageKey, _value: StorageValue) {}
299
300 fn tload(&mut self, _address: Address, _key: StorageKey) -> StorageValue {
301 StorageValue::ZERO
302 }
303
304 fn load_account_info_skip_cold_load(
305 &mut self,
306 _address: Address,
307 _load_code: bool,
308 _skip_cold_load: bool,
309 ) -> Result<AccountInfoLoad<'_>, LoadError> {
310 Err(LoadError::DBError)
311 }
312
313 fn sstore_skip_cold_load(
314 &mut self,
315 _address: Address,
316 _key: StorageKey,
317 _value: StorageValue,
318 _skip_cold_load: bool,
319 ) -> Result<StateLoad<SStoreResult>, LoadError> {
320 Err(LoadError::DBError)
321 }
322
323 fn sload_skip_cold_load(
324 &mut self,
325 _address: Address,
326 _key: StorageKey,
327 _skip_cold_load: bool,
328 ) -> Result<StateLoad<StorageValue>, LoadError> {
329 Err(LoadError::DBError)
330 }
331}