1use context_interface::{
2 context::{ContextTr, SStoreResult, SelfDestructResult, StateLoad},
3 journaled_state::AccountLoad,
4 Block, Cfg, Database, JournalTr, LocalContextTr, Transaction, TransactionType,
5};
6use primitives::{Address, Bytes, Log, StorageKey, StorageValue, B256, U256};
7
8use crate::instructions::utility::IntoU256;
9
10pub trait Host {
16 fn basefee(&self) -> U256;
20 fn blob_gasprice(&self) -> U256;
22 fn gas_limit(&self) -> U256;
24 fn difficulty(&self) -> U256;
26 fn prevrandao(&self) -> Option<U256>;
28 fn block_number(&self) -> U256;
30 fn timestamp(&self) -> U256;
32 fn beneficiary(&self) -> Address;
34 fn chain_id(&self) -> U256;
36
37 fn effective_gas_price(&self) -> U256;
41 fn caller(&self) -> Address;
43 fn blob_hash(&self, number: usize) -> Option<U256>;
45 fn initcode_by_hash(&mut self, hash: B256) -> Option<Bytes>;
47
48 fn max_initcode_size(&self) -> usize;
52
53 fn block_hash(&mut self, number: u64) -> Option<B256>;
57
58 fn selfdestruct(
62 &mut self,
63 address: Address,
64 target: Address,
65 ) -> Option<StateLoad<SelfDestructResult>>;
66
67 fn log(&mut self, log: Log);
69 fn sstore(
71 &mut self,
72 address: Address,
73 key: StorageKey,
74 value: StorageValue,
75 ) -> Option<StateLoad<SStoreResult>>;
76
77 fn sload(&mut self, address: Address, key: StorageKey) -> Option<StateLoad<StorageValue>>;
79 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue);
81 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue;
83 fn balance(&mut self, address: Address) -> Option<StateLoad<U256>>;
85 fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>>;
87 fn load_account_code(&mut self, address: Address) -> Option<StateLoad<Bytes>>;
89 fn load_account_code_hash(&mut self, address: Address) -> Option<StateLoad<B256>>;
91}
92
93impl<CTX: ContextTr> Host for CTX {
94 fn basefee(&self) -> U256 {
97 U256::from(self.block().basefee())
98 }
99
100 fn blob_gasprice(&self) -> U256 {
101 U256::from(self.block().blob_gasprice().unwrap_or(0))
102 }
103
104 fn gas_limit(&self) -> U256 {
105 U256::from(self.block().gas_limit())
106 }
107
108 fn difficulty(&self) -> U256 {
109 self.block().difficulty()
110 }
111
112 fn prevrandao(&self) -> Option<U256> {
113 self.block().prevrandao().map(|r| r.into_u256())
114 }
115
116 fn block_number(&self) -> U256 {
117 self.block().number()
118 }
119
120 fn timestamp(&self) -> U256 {
121 U256::from(self.block().timestamp())
122 }
123
124 fn beneficiary(&self) -> Address {
125 self.block().beneficiary()
126 }
127
128 fn chain_id(&self) -> U256 {
129 U256::from(self.cfg().chain_id())
130 }
131
132 fn effective_gas_price(&self) -> U256 {
135 let basefee = self.block().basefee();
136 U256::from(self.tx().effective_gas_price(basefee as u128))
137 }
138
139 fn caller(&self) -> Address {
140 self.tx().caller()
141 }
142
143 fn blob_hash(&self, number: usize) -> Option<U256> {
144 let tx = &self.tx();
145 if tx.tx_type() != TransactionType::Eip4844 {
146 return None;
147 }
148 tx.blob_versioned_hashes()
149 .get(number)
150 .map(|t| U256::from_be_bytes(t.0))
151 }
152
153 fn initcode_by_hash(&mut self, hash: B256) -> Option<Bytes> {
154 self.local_mut().get_validated_initcode(hash)
155 }
156
157 fn max_initcode_size(&self) -> usize {
160 self.cfg().max_code_size().saturating_mul(2)
161 }
162
163 fn block_hash(&mut self, requested_number: u64) -> Option<B256> {
166 self.db_mut()
167 .block_hash(requested_number)
168 .map_err(|e| {
169 *self.error() = Err(e.into());
170 })
171 .ok()
172 }
173
174 fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>> {
177 self.journal_mut()
178 .load_account_delegated(address)
179 .map_err(|e| {
180 *self.error() = Err(e.into());
181 })
182 .ok()
183 }
184
185 fn balance(&mut self, address: Address) -> Option<StateLoad<U256>> {
187 self.journal_mut()
188 .load_account(address)
189 .map(|acc| acc.map(|a| a.info.balance))
190 .map_err(|e| {
191 *self.error() = Err(e.into());
192 })
193 .ok()
194 }
195
196 fn load_account_code(&mut self, address: Address) -> Option<StateLoad<Bytes>> {
198 self.journal_mut()
199 .code(address)
200 .map_err(|e| {
201 *self.error() = Err(e.into());
202 })
203 .ok()
204 }
205
206 fn load_account_code_hash(&mut self, address: Address) -> Option<StateLoad<B256>> {
208 self.journal_mut()
209 .code_hash(address)
210 .map_err(|e| {
211 *self.error() = Err(e.into());
212 })
213 .ok()
214 }
215
216 fn sload(&mut self, address: Address, index: StorageKey) -> Option<StateLoad<StorageValue>> {
218 self.journal_mut()
219 .sload(address, index)
220 .map_err(|e| {
221 *self.error() = Err(e.into());
222 })
223 .ok()
224 }
225
226 fn sstore(
230 &mut self,
231 address: Address,
232 index: StorageKey,
233 value: StorageValue,
234 ) -> Option<StateLoad<SStoreResult>> {
235 self.journal_mut()
236 .sstore(address, index, value)
237 .map_err(|e| {
238 *self.error() = Err(e.into());
239 })
240 .ok()
241 }
242
243 fn tload(&mut self, address: Address, index: StorageKey) -> StorageValue {
245 self.journal_mut().tload(address, index)
246 }
247
248 fn tstore(&mut self, address: Address, index: StorageKey, value: StorageValue) {
250 self.journal_mut().tstore(address, index, value)
251 }
252
253 fn log(&mut self, log: Log) {
255 self.journal_mut().log(log);
256 }
257
258 fn selfdestruct(
260 &mut self,
261 address: Address,
262 target: Address,
263 ) -> Option<StateLoad<SelfDestructResult>> {
264 self.journal_mut()
265 .selfdestruct(address, target)
266 .map_err(|e| {
267 *self.error() = Err(e.into());
268 })
269 .ok()
270 }
271}
272
273pub struct DummyHost;
275
276impl Host for DummyHost {
277 fn basefee(&self) -> U256 {
278 U256::ZERO
279 }
280
281 fn blob_gasprice(&self) -> U256 {
282 U256::ZERO
283 }
284
285 fn gas_limit(&self) -> U256 {
286 U256::ZERO
287 }
288
289 fn difficulty(&self) -> U256 {
290 U256::ZERO
291 }
292
293 fn prevrandao(&self) -> Option<U256> {
294 None
295 }
296
297 fn block_number(&self) -> U256 {
298 U256::ZERO
299 }
300
301 fn timestamp(&self) -> U256 {
302 U256::ZERO
303 }
304
305 fn beneficiary(&self) -> Address {
306 Address::ZERO
307 }
308
309 fn chain_id(&self) -> U256 {
310 U256::ZERO
311 }
312
313 fn effective_gas_price(&self) -> U256 {
314 U256::ZERO
315 }
316
317 fn caller(&self) -> Address {
318 Address::ZERO
319 }
320
321 fn initcode_by_hash(&mut self, _hash: B256) -> Option<Bytes> {
322 None
323 }
324
325 fn blob_hash(&self, _number: usize) -> Option<U256> {
326 None
327 }
328
329 fn max_initcode_size(&self) -> usize {
330 0
331 }
332
333 fn block_hash(&mut self, _number: u64) -> Option<B256> {
334 None
335 }
336
337 fn selfdestruct(
338 &mut self,
339 _address: Address,
340 _target: Address,
341 ) -> Option<StateLoad<SelfDestructResult>> {
342 None
343 }
344
345 fn log(&mut self, _log: Log) {}
346
347 fn sstore(
348 &mut self,
349 _address: Address,
350 _key: StorageKey,
351 _value: StorageValue,
352 ) -> Option<StateLoad<SStoreResult>> {
353 None
354 }
355
356 fn sload(&mut self, _address: Address, _key: StorageKey) -> Option<StateLoad<StorageValue>> {
357 None
358 }
359
360 fn tstore(&mut self, _address: Address, _key: StorageKey, _value: StorageValue) {}
361
362 fn tload(&mut self, _address: Address, _key: StorageKey) -> StorageValue {
363 StorageValue::ZERO
364 }
365
366 fn balance(&mut self, _address: Address) -> Option<StateLoad<U256>> {
367 None
368 }
369
370 fn load_account_delegated(&mut self, _address: Address) -> Option<StateLoad<AccountLoad>> {
371 None
372 }
373
374 fn load_account_code(&mut self, _address: Address) -> Option<StateLoad<Bytes>> {
375 None
376 }
377
378 fn load_account_code_hash(&mut self, _address: Address) -> Option<StateLoad<B256>> {
379 None
380 }
381}