1use context_interface::{
2 context::{ContextTr, SStoreResult, SelfDestructResult, StateLoad},
3 journaled_state::AccountLoad,
4 Block, Cfg, Database, JournalTr, 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
46 fn max_initcode_size(&self) -> usize;
50
51 fn block_hash(&mut self, number: u64) -> Option<B256>;
55
56 fn selfdestruct(
60 &mut self,
61 address: Address,
62 target: Address,
63 ) -> Option<StateLoad<SelfDestructResult>>;
64
65 fn log(&mut self, log: Log);
67 fn sstore(
69 &mut self,
70 address: Address,
71 key: StorageKey,
72 value: StorageValue,
73 ) -> Option<StateLoad<SStoreResult>>;
74
75 fn sload(&mut self, address: Address, key: StorageKey) -> Option<StateLoad<StorageValue>>;
77 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue);
79 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue;
81 fn balance(&mut self, address: Address) -> Option<StateLoad<U256>>;
83 fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>>;
85 fn load_account_code(&mut self, address: Address) -> Option<StateLoad<Bytes>>;
87 fn load_account_code_hash(&mut self, address: Address) -> Option<StateLoad<B256>>;
89}
90
91impl<CTX: ContextTr> Host for CTX {
92 fn basefee(&self) -> U256 {
95 U256::from(self.block().basefee())
96 }
97
98 fn blob_gasprice(&self) -> U256 {
99 U256::from(self.block().blob_gasprice().unwrap_or(0))
100 }
101
102 fn gas_limit(&self) -> U256 {
103 U256::from(self.block().gas_limit())
104 }
105
106 fn difficulty(&self) -> U256 {
107 self.block().difficulty()
108 }
109
110 fn prevrandao(&self) -> Option<U256> {
111 self.block().prevrandao().map(|r| r.into_u256())
112 }
113
114 fn block_number(&self) -> U256 {
115 self.block().number()
116 }
117
118 fn timestamp(&self) -> U256 {
119 U256::from(self.block().timestamp())
120 }
121
122 fn beneficiary(&self) -> Address {
123 self.block().beneficiary()
124 }
125
126 fn chain_id(&self) -> U256 {
127 U256::from(self.cfg().chain_id())
128 }
129
130 fn effective_gas_price(&self) -> U256 {
133 let basefee = self.block().basefee();
134 U256::from(self.tx().effective_gas_price(basefee as u128))
135 }
136
137 fn caller(&self) -> Address {
138 self.tx().caller()
139 }
140
141 fn blob_hash(&self, number: usize) -> Option<U256> {
142 let tx = &self.tx();
143 if tx.tx_type() != TransactionType::Eip4844 {
144 return None;
145 }
146 tx.blob_versioned_hashes()
147 .get(number)
148 .map(|t| U256::from_be_bytes(t.0))
149 }
150
151 fn max_initcode_size(&self) -> usize {
154 self.cfg().max_initcode_size()
155 }
156
157 fn block_hash(&mut self, requested_number: u64) -> Option<B256> {
160 self.db_mut()
161 .block_hash(requested_number)
162 .map_err(|e| {
163 *self.error() = Err(e.into());
164 })
165 .ok()
166 }
167
168 fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>> {
171 self.journal_mut()
172 .load_account_delegated(address)
173 .map_err(|e| {
174 *self.error() = Err(e.into());
175 })
176 .ok()
177 }
178
179 fn balance(&mut self, address: Address) -> Option<StateLoad<U256>> {
181 self.journal_mut()
182 .load_account(address)
183 .map(|acc| acc.map(|a| a.info.balance))
184 .map_err(|e| {
185 *self.error() = Err(e.into());
186 })
187 .ok()
188 }
189
190 fn load_account_code(&mut self, address: Address) -> Option<StateLoad<Bytes>> {
192 self.journal_mut()
193 .code(address)
194 .map_err(|e| {
195 *self.error() = Err(e.into());
196 })
197 .ok()
198 }
199
200 fn load_account_code_hash(&mut self, address: Address) -> Option<StateLoad<B256>> {
202 self.journal_mut()
203 .code_hash(address)
204 .map_err(|e| {
205 *self.error() = Err(e.into());
206 })
207 .ok()
208 }
209
210 fn sload(&mut self, address: Address, index: StorageKey) -> Option<StateLoad<StorageValue>> {
212 self.journal_mut()
213 .sload(address, index)
214 .map_err(|e| {
215 *self.error() = Err(e.into());
216 })
217 .ok()
218 }
219
220 fn sstore(
224 &mut self,
225 address: Address,
226 index: StorageKey,
227 value: StorageValue,
228 ) -> Option<StateLoad<SStoreResult>> {
229 self.journal_mut()
230 .sstore(address, index, value)
231 .map_err(|e| {
232 *self.error() = Err(e.into());
233 })
234 .ok()
235 }
236
237 fn tload(&mut self, address: Address, index: StorageKey) -> StorageValue {
239 self.journal_mut().tload(address, index)
240 }
241
242 fn tstore(&mut self, address: Address, index: StorageKey, value: StorageValue) {
244 self.journal_mut().tstore(address, index, value)
245 }
246
247 fn log(&mut self, log: Log) {
249 self.journal_mut().log(log);
250 }
251
252 fn selfdestruct(
254 &mut self,
255 address: Address,
256 target: Address,
257 ) -> Option<StateLoad<SelfDestructResult>> {
258 self.journal_mut()
259 .selfdestruct(address, target)
260 .map_err(|e| {
261 *self.error() = Err(e.into());
262 })
263 .ok()
264 }
265}
266
267#[derive(Debug)]
269pub struct DummyHost;
270
271impl Host for DummyHost {
272 fn basefee(&self) -> U256 {
273 U256::ZERO
274 }
275
276 fn blob_gasprice(&self) -> U256 {
277 U256::ZERO
278 }
279
280 fn gas_limit(&self) -> U256 {
281 U256::ZERO
282 }
283
284 fn difficulty(&self) -> U256 {
285 U256::ZERO
286 }
287
288 fn prevrandao(&self) -> Option<U256> {
289 None
290 }
291
292 fn block_number(&self) -> U256 {
293 U256::ZERO
294 }
295
296 fn timestamp(&self) -> U256 {
297 U256::ZERO
298 }
299
300 fn beneficiary(&self) -> Address {
301 Address::ZERO
302 }
303
304 fn chain_id(&self) -> U256 {
305 U256::ZERO
306 }
307
308 fn effective_gas_price(&self) -> U256 {
309 U256::ZERO
310 }
311
312 fn caller(&self) -> Address {
313 Address::ZERO
314 }
315
316 fn blob_hash(&self, _number: usize) -> Option<U256> {
317 None
318 }
319
320 fn max_initcode_size(&self) -> usize {
321 0
322 }
323
324 fn block_hash(&mut self, _number: u64) -> Option<B256> {
325 None
326 }
327
328 fn selfdestruct(
329 &mut self,
330 _address: Address,
331 _target: Address,
332 ) -> Option<StateLoad<SelfDestructResult>> {
333 None
334 }
335
336 fn log(&mut self, _log: Log) {}
337
338 fn sstore(
339 &mut self,
340 _address: Address,
341 _key: StorageKey,
342 _value: StorageValue,
343 ) -> Option<StateLoad<SStoreResult>> {
344 None
345 }
346
347 fn sload(&mut self, _address: Address, _key: StorageKey) -> Option<StateLoad<StorageValue>> {
348 None
349 }
350
351 fn tstore(&mut self, _address: Address, _key: StorageKey, _value: StorageValue) {}
352
353 fn tload(&mut self, _address: Address, _key: StorageKey) -> StorageValue {
354 StorageValue::ZERO
355 }
356
357 fn balance(&mut self, _address: Address) -> Option<StateLoad<U256>> {
358 None
359 }
360
361 fn load_account_delegated(&mut self, _address: Address) -> Option<StateLoad<AccountLoad>> {
362 None
363 }
364
365 fn load_account_code(&mut self, _address: Address) -> Option<StateLoad<Bytes>> {
366 None
367 }
368
369 fn load_account_code_hash(&mut self, _address: Address) -> Option<StateLoad<B256>> {
370 None
371 }
372}