1use crate::{
4 context::{SStoreResult, SelfDestructResult, StateLoad},
5 journaled_state::{AccountInfoLoad, AccountLoad},
6};
7use auto_impl::auto_impl;
8use primitives::{Address, Bytes, Log, StorageKey, StorageValue, B256, U256};
9use state::Bytecode;
10
11#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14pub enum LoadError {
15 DBError,
17 ColdLoadSkipped,
19}
20
21#[auto_impl(&mut, Box)]
27pub trait Host {
28 fn basefee(&self) -> U256;
32 fn blob_gasprice(&self) -> U256;
34 fn gas_limit(&self) -> U256;
36 fn difficulty(&self) -> U256;
38 fn prevrandao(&self) -> Option<U256>;
40 fn block_number(&self) -> U256;
42 fn timestamp(&self) -> U256;
44 fn beneficiary(&self) -> Address;
46 fn chain_id(&self) -> U256;
48
49 fn effective_gas_price(&self) -> U256;
53 fn caller(&self) -> Address;
55 fn blob_hash(&self, number: usize) -> Option<U256>;
57
58 fn max_initcode_size(&self) -> usize;
62
63 fn block_hash(&mut self, number: u64) -> Option<B256>;
67
68 fn selfdestruct(
72 &mut self,
73 address: Address,
74 target: Address,
75 skip_cold_load: bool,
76 ) -> Result<StateLoad<SelfDestructResult>, LoadError>;
77
78 fn log(&mut self, log: Log);
80
81 fn sstore_skip_cold_load(
83 &mut self,
84 address: Address,
85 key: StorageKey,
86 value: StorageValue,
87 skip_cold_load: bool,
88 ) -> Result<StateLoad<SStoreResult>, LoadError>;
89
90 fn sstore(
92 &mut self,
93 address: Address,
94 key: StorageKey,
95 value: StorageValue,
96 ) -> Option<StateLoad<SStoreResult>> {
97 self.sstore_skip_cold_load(address, key, value, false).ok()
98 }
99
100 fn sload_skip_cold_load(
102 &mut self,
103 address: Address,
104 key: StorageKey,
105 skip_cold_load: bool,
106 ) -> Result<StateLoad<StorageValue>, LoadError>;
107
108 fn sload(&mut self, address: Address, key: StorageKey) -> Option<StateLoad<StorageValue>> {
110 self.sload_skip_cold_load(address, key, false).ok()
111 }
112
113 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue);
115
116 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue;
118
119 fn load_account_info_skip_cold_load(
128 &mut self,
129 address: Address,
130 load_code: bool,
131 skip_cold_load: bool,
132 ) -> Result<AccountInfoLoad<'_>, LoadError>;
133
134 #[inline]
136 fn balance(&mut self, address: Address) -> Option<StateLoad<U256>> {
137 self.load_account_info_skip_cold_load(address, false, false)
138 .ok()
139 .map(|load| load.into_state_load(|i| i.balance))
140 }
141
142 #[inline]
144 fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>> {
145 let account = self
146 .load_account_info_skip_cold_load(address, true, false)
147 .ok()?;
148
149 let mut account_load = StateLoad::new(
150 AccountLoad {
151 is_delegate_account_cold: None,
152 is_empty: account.is_empty,
153 },
154 account.is_cold,
155 );
156
157 if let Some(Bytecode::Eip7702(code)) = &account.code {
159 let address = code.address();
160 let delegate_account = self
161 .load_account_info_skip_cold_load(address, true, false)
162 .ok()?;
163 account_load.data.is_delegate_account_cold = Some(delegate_account.is_cold);
164 account_load.data.is_empty = delegate_account.is_empty;
165 }
166
167 Some(account_load)
168 }
169
170 #[inline]
172 fn load_account_code(&mut self, address: Address) -> Option<StateLoad<Bytes>> {
173 self.load_account_info_skip_cold_load(address, true, false)
174 .ok()
175 .map(|load| {
176 load.into_state_load(|i| {
177 i.code
178 .as_ref()
179 .map(|b| b.original_bytes())
180 .unwrap_or_default()
181 })
182 })
183 }
184
185 #[inline]
187 fn load_account_code_hash(&mut self, address: Address) -> Option<StateLoad<B256>> {
188 self.load_account_info_skip_cold_load(address, false, false)
189 .ok()
190 .map(|load| {
191 load.into_state_load(|i| {
192 if i.is_empty() {
193 B256::ZERO
194 } else {
195 i.code_hash
196 }
197 })
198 })
199 }
200}
201
202#[derive(Debug)]
204pub struct DummyHost;
205
206impl Host for DummyHost {
207 fn basefee(&self) -> U256 {
208 U256::ZERO
209 }
210
211 fn blob_gasprice(&self) -> U256 {
212 U256::ZERO
213 }
214
215 fn gas_limit(&self) -> U256 {
216 U256::ZERO
217 }
218
219 fn difficulty(&self) -> U256 {
220 U256::ZERO
221 }
222
223 fn prevrandao(&self) -> Option<U256> {
224 None
225 }
226
227 fn block_number(&self) -> U256 {
228 U256::ZERO
229 }
230
231 fn timestamp(&self) -> U256 {
232 U256::ZERO
233 }
234
235 fn beneficiary(&self) -> Address {
236 Address::ZERO
237 }
238
239 fn chain_id(&self) -> U256 {
240 U256::ZERO
241 }
242
243 fn effective_gas_price(&self) -> U256 {
244 U256::ZERO
245 }
246
247 fn caller(&self) -> Address {
248 Address::ZERO
249 }
250
251 fn blob_hash(&self, _number: usize) -> Option<U256> {
252 None
253 }
254
255 fn max_initcode_size(&self) -> usize {
256 0
257 }
258
259 fn block_hash(&mut self, _number: u64) -> Option<B256> {
260 None
261 }
262
263 fn selfdestruct(
264 &mut self,
265 _address: Address,
266 _target: Address,
267 _skip_cold_load: bool,
268 ) -> Result<StateLoad<SelfDestructResult>, LoadError> {
269 Err(LoadError::ColdLoadSkipped)
270 }
271
272 fn log(&mut self, _log: Log) {}
273
274 fn tstore(&mut self, _address: Address, _key: StorageKey, _value: StorageValue) {}
275
276 fn tload(&mut self, _address: Address, _key: StorageKey) -> StorageValue {
277 StorageValue::ZERO
278 }
279
280 fn load_account_info_skip_cold_load(
281 &mut self,
282 _address: Address,
283 _load_code: bool,
284 _skip_cold_load: bool,
285 ) -> Result<AccountInfoLoad<'_>, LoadError> {
286 Err(LoadError::DBError)
287 }
288
289 fn sstore_skip_cold_load(
290 &mut self,
291 _address: Address,
292 _key: StorageKey,
293 _value: StorageValue,
294 _skip_cold_load: bool,
295 ) -> Result<StateLoad<SStoreResult>, LoadError> {
296 Err(LoadError::DBError)
297 }
298
299 fn sload_skip_cold_load(
300 &mut self,
301 _address: Address,
302 _key: StorageKey,
303 _skip_cold_load: bool,
304 ) -> Result<StateLoad<StorageValue>, LoadError> {
305 Err(LoadError::DBError)
306 }
307}