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 ColdLoadSkipped,
18 DBError,
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 is_amsterdam_eip8037_enabled(&self) -> bool;
71
72 fn cpsb(&self) -> u64;
78
79 fn block_hash(&mut self, number: u64) -> Option<B256>;
83
84 fn selfdestruct(
88 &mut self,
89 address: Address,
90 target: Address,
91 skip_cold_load: bool,
92 ) -> Result<StateLoad<SelfDestructResult>, LoadError>;
93
94 fn log(&mut self, log: Log);
96
97 fn sstore_skip_cold_load(
99 &mut self,
100 address: Address,
101 key: StorageKey,
102 value: StorageValue,
103 skip_cold_load: bool,
104 ) -> Result<StateLoad<SStoreResult>, LoadError>;
105
106 fn sstore(
108 &mut self,
109 address: Address,
110 key: StorageKey,
111 value: StorageValue,
112 ) -> Option<StateLoad<SStoreResult>> {
113 self.sstore_skip_cold_load(address, key, value, false).ok()
114 }
115
116 fn sload_skip_cold_load(
118 &mut self,
119 address: Address,
120 key: StorageKey,
121 skip_cold_load: bool,
122 ) -> Result<StateLoad<StorageValue>, LoadError>;
123
124 fn sload(&mut self, address: Address, key: StorageKey) -> Option<StateLoad<StorageValue>> {
126 self.sload_skip_cold_load(address, key, false).ok()
127 }
128
129 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue);
131
132 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue;
134
135 fn load_account_info_skip_cold_load(
144 &mut self,
145 address: Address,
146 load_code: bool,
147 skip_cold_load: bool,
148 ) -> Result<AccountInfoLoad<'_>, LoadError>;
149
150 #[inline]
152 fn balance(&mut self, address: Address) -> Option<StateLoad<U256>> {
153 self.load_account_info_skip_cold_load(address, false, false)
154 .ok()
155 .map(|load| load.into_state_load(|i| i.balance))
156 }
157
158 #[inline]
160 fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>> {
161 let account = self
162 .load_account_info_skip_cold_load(address, true, false)
163 .ok()?;
164
165 let mut account_load = StateLoad::new(
166 AccountLoad {
167 is_delegate_account_cold: None,
168 is_empty: account.is_empty,
169 },
170 account.is_cold,
171 );
172
173 if let Some(address) = account.code.as_ref().and_then(Bytecode::eip7702_address) {
175 let delegate_account = self
176 .load_account_info_skip_cold_load(address, true, false)
177 .ok()?;
178 account_load.data.is_delegate_account_cold = Some(delegate_account.is_cold);
179 account_load.data.is_empty = delegate_account.is_empty;
180 }
181
182 Some(account_load)
183 }
184
185 #[inline]
187 fn load_account_code(&mut self, address: Address) -> Option<StateLoad<Bytes>> {
188 self.load_account_info_skip_cold_load(address, true, false)
189 .ok()
190 .map(|load| {
191 load.into_state_load(|i| {
192 i.code
193 .as_ref()
194 .map(|b| b.original_bytes())
195 .unwrap_or_default()
196 })
197 })
198 }
199
200 #[inline]
202 fn load_account_code_hash(&mut self, address: Address) -> Option<StateLoad<B256>> {
203 self.load_account_info_skip_cold_load(address, false, false)
204 .ok()
205 .map(|load| {
206 load.into_state_load(|i| {
207 if i.is_empty() {
208 B256::ZERO
209 } else {
210 i.code_hash
211 }
212 })
213 })
214 }
215}
216
217#[derive(Default, Debug)]
219pub struct DummyHost {
220 gas_params: GasParams,
221}
222
223impl DummyHost {
224 pub fn new(spec: SpecId) -> Self {
226 Self {
227 gas_params: GasParams::new_spec(spec),
228 }
229 }
230}
231
232impl Host for DummyHost {
233 fn basefee(&self) -> U256 {
234 U256::ZERO
235 }
236
237 fn blob_gasprice(&self) -> U256 {
238 U256::ZERO
239 }
240
241 fn gas_limit(&self) -> U256 {
242 U256::ZERO
243 }
244
245 fn gas_params(&self) -> &GasParams {
246 &self.gas_params
247 }
248
249 fn is_amsterdam_eip8037_enabled(&self) -> bool {
250 false
251 }
252
253 fn cpsb(&self) -> u64 {
254 0
255 }
256
257 fn difficulty(&self) -> U256 {
258 U256::ZERO
259 }
260
261 fn prevrandao(&self) -> Option<U256> {
262 None
263 }
264
265 fn block_number(&self) -> U256 {
266 U256::ZERO
267 }
268
269 fn timestamp(&self) -> U256 {
270 U256::ZERO
271 }
272
273 fn beneficiary(&self) -> Address {
274 Address::ZERO
275 }
276
277 fn slot_num(&self) -> U256 {
278 U256::ZERO
279 }
280
281 fn chain_id(&self) -> U256 {
282 U256::ZERO
283 }
284
285 fn effective_gas_price(&self) -> U256 {
286 U256::ZERO
287 }
288
289 fn caller(&self) -> Address {
290 Address::ZERO
291 }
292
293 fn blob_hash(&self, _number: usize) -> Option<U256> {
294 None
295 }
296
297 fn max_initcode_size(&self) -> usize {
298 0
299 }
300
301 fn block_hash(&mut self, _number: u64) -> Option<B256> {
302 None
303 }
304
305 fn selfdestruct(
306 &mut self,
307 _address: Address,
308 _target: Address,
309 _skip_cold_load: bool,
310 ) -> Result<StateLoad<SelfDestructResult>, LoadError> {
311 Ok(Default::default())
312 }
313
314 fn log(&mut self, _log: Log) {}
315
316 fn tstore(&mut self, _address: Address, _key: StorageKey, _value: StorageValue) {}
317
318 fn tload(&mut self, _address: Address, _key: StorageKey) -> StorageValue {
319 StorageValue::ZERO
320 }
321
322 fn load_account_info_skip_cold_load(
323 &mut self,
324 _address: Address,
325 _load_code: bool,
326 _skip_cold_load: bool,
327 ) -> Result<AccountInfoLoad<'_>, LoadError> {
328 Ok(Default::default())
329 }
330
331 fn sstore_skip_cold_load(
332 &mut self,
333 _address: Address,
334 _key: StorageKey,
335 _value: StorageValue,
336 _skip_cold_load: bool,
337 ) -> Result<StateLoad<SStoreResult>, LoadError> {
338 Ok(Default::default())
339 }
340
341 fn sload_skip_cold_load(
342 &mut self,
343 _address: Address,
344 _key: StorageKey,
345 _skip_cold_load: bool,
346 ) -> Result<StateLoad<StorageValue>, LoadError> {
347 Ok(Default::default())
348 }
349}