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, 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) -> u64;
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: U256,
74 value: U256,
75 ) -> Option<StateLoad<SStoreResult>>;
76
77 fn sload(&mut self, address: Address, key: U256) -> Option<StateLoad<U256>>;
79 fn tstore(&mut self, address: Address, key: U256, value: U256);
81 fn tload(&mut self, address: Address, key: U256) -> U256;
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) -> u64 {
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().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.journal()
167 .db()
168 .block_hash(requested_number)
169 .map_err(|e| {
170 *self.error() = Err(e.into());
171 })
172 .ok()
173 }
174
175 fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>> {
178 self.journal()
179 .load_account_delegated(address)
180 .map_err(|e| {
181 *self.error() = Err(e.into());
182 })
183 .ok()
184 }
185
186 fn balance(&mut self, address: Address) -> Option<StateLoad<U256>> {
188 self.journal()
189 .load_account(address)
190 .map(|acc| acc.map(|a| a.info.balance))
191 .map_err(|e| {
192 *self.error() = Err(e.into());
193 })
194 .ok()
195 }
196
197 fn load_account_code(&mut self, address: Address) -> Option<StateLoad<Bytes>> {
199 self.journal()
200 .code(address)
201 .map_err(|e| {
202 *self.error() = Err(e.into());
203 })
204 .ok()
205 }
206
207 fn load_account_code_hash(&mut self, address: Address) -> Option<StateLoad<B256>> {
209 self.journal()
210 .code_hash(address)
211 .map_err(|e| {
212 *self.error() = Err(e.into());
213 })
214 .ok()
215 }
216
217 fn sload(&mut self, address: Address, index: U256) -> Option<StateLoad<U256>> {
219 self.journal()
220 .sload(address, index)
221 .map_err(|e| {
222 *self.error() = Err(e.into());
223 })
224 .ok()
225 }
226
227 fn sstore(
231 &mut self,
232 address: Address,
233 index: U256,
234 value: U256,
235 ) -> Option<StateLoad<SStoreResult>> {
236 self.journal()
237 .sstore(address, index, value)
238 .map_err(|e| {
239 *self.error() = Err(e.into());
240 })
241 .ok()
242 }
243
244 fn tload(&mut self, address: Address, index: U256) -> U256 {
246 self.journal().tload(address, index)
247 }
248
249 fn tstore(&mut self, address: Address, index: U256, value: U256) {
251 self.journal().tstore(address, index, value)
252 }
253
254 fn log(&mut self, log: Log) {
256 self.journal().log(log);
257 }
258
259 fn selfdestruct(
261 &mut self,
262 address: Address,
263 target: Address,
264 ) -> Option<StateLoad<SelfDestructResult>> {
265 self.journal()
266 .selfdestruct(address, target)
267 .map_err(|e| {
268 *self.error() = Err(e.into());
269 })
270 .ok()
271 }
272}
273
274pub struct DummyHost;
276
277impl Host for DummyHost {
278 fn basefee(&self) -> U256 {
279 U256::ZERO
280 }
281
282 fn blob_gasprice(&self) -> U256 {
283 U256::ZERO
284 }
285
286 fn gas_limit(&self) -> U256 {
287 U256::ZERO
288 }
289
290 fn difficulty(&self) -> U256 {
291 U256::ZERO
292 }
293
294 fn prevrandao(&self) -> Option<U256> {
295 None
296 }
297
298 fn block_number(&self) -> u64 {
299 0
300 }
301
302 fn timestamp(&self) -> U256 {
303 U256::ZERO
304 }
305
306 fn beneficiary(&self) -> Address {
307 Address::ZERO
308 }
309
310 fn chain_id(&self) -> U256 {
311 U256::ZERO
312 }
313
314 fn effective_gas_price(&self) -> U256 {
315 U256::ZERO
316 }
317
318 fn caller(&self) -> Address {
319 Address::ZERO
320 }
321
322 fn initcode_by_hash(&mut self, _hash: B256) -> Option<Bytes> {
323 None
324 }
325
326 fn blob_hash(&self, _number: usize) -> Option<U256> {
327 None
328 }
329
330 fn max_initcode_size(&self) -> usize {
331 0
332 }
333
334 fn block_hash(&mut self, _number: u64) -> Option<B256> {
335 None
336 }
337
338 fn selfdestruct(
339 &mut self,
340 _address: Address,
341 _target: Address,
342 ) -> Option<StateLoad<SelfDestructResult>> {
343 None
344 }
345
346 fn log(&mut self, _log: Log) {}
347
348 fn sstore(
349 &mut self,
350 _address: Address,
351 _key: U256,
352 _value: U256,
353 ) -> Option<StateLoad<SStoreResult>> {
354 None
355 }
356
357 fn sload(&mut self, _address: Address, _key: U256) -> Option<StateLoad<U256>> {
358 None
359 }
360
361 fn tstore(&mut self, _address: Address, _key: U256, _value: U256) {}
362
363 fn tload(&mut self, _address: Address, _key: U256) -> U256 {
364 U256::ZERO
365 }
366
367 fn balance(&mut self, _address: Address) -> Option<StateLoad<U256>> {
368 None
369 }
370
371 fn load_account_delegated(&mut self, _address: Address) -> Option<StateLoad<AccountLoad>> {
372 None
373 }
374
375 fn load_account_code(&mut self, _address: Address) -> Option<StateLoad<Bytes>> {
376 None
377 }
378
379 fn load_account_code_hash(&mut self, _address: Address) -> Option<StateLoad<B256>> {
380 None
381 }
382}