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, 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
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: U256,
72 value: U256,
73 ) -> Option<StateLoad<SStoreResult>>;
74
75 fn sload(&mut self, address: Address, key: U256) -> Option<StateLoad<U256>>;
77 fn tstore(&mut self, address: Address, key: U256, value: U256);
79 fn tload(&mut self, address: Address, key: U256) -> U256;
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) -> u64 {
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_code_size().saturating_mul(2)
155 }
156
157 fn block_hash(&mut self, requested_number: u64) -> Option<B256> {
160 self.journal()
161 .db()
162 .block_hash(requested_number)
163 .map_err(|e| {
164 *self.error() = Err(e.into());
165 })
166 .ok()
167 }
168
169 fn load_account_delegated(&mut self, address: Address) -> Option<StateLoad<AccountLoad>> {
172 self.journal()
173 .load_account_delegated(address)
174 .map_err(|e| {
175 *self.error() = Err(e.into());
176 })
177 .ok()
178 }
179
180 fn balance(&mut self, address: Address) -> Option<StateLoad<U256>> {
182 self.journal()
183 .load_account(address)
184 .map(|acc| acc.map(|a| a.info.balance))
185 .map_err(|e| {
186 *self.error() = Err(e.into());
187 })
188 .ok()
189 }
190
191 fn load_account_code(&mut self, address: Address) -> Option<StateLoad<Bytes>> {
193 self.journal()
194 .code(address)
195 .map_err(|e| {
196 *self.error() = Err(e.into());
197 })
198 .ok()
199 }
200
201 fn load_account_code_hash(&mut self, address: Address) -> Option<StateLoad<B256>> {
203 self.journal()
204 .code_hash(address)
205 .map_err(|e| {
206 *self.error() = Err(e.into());
207 })
208 .ok()
209 }
210
211 fn sload(&mut self, address: Address, index: U256) -> Option<StateLoad<U256>> {
213 self.journal()
214 .sload(address, index)
215 .map_err(|e| {
216 *self.error() = Err(e.into());
217 })
218 .ok()
219 }
220
221 fn sstore(
225 &mut self,
226 address: Address,
227 index: U256,
228 value: U256,
229 ) -> Option<StateLoad<SStoreResult>> {
230 self.journal()
231 .sstore(address, index, value)
232 .map_err(|e| {
233 *self.error() = Err(e.into());
234 })
235 .ok()
236 }
237
238 fn tload(&mut self, address: Address, index: U256) -> U256 {
240 self.journal().tload(address, index)
241 }
242
243 fn tstore(&mut self, address: Address, index: U256, value: U256) {
245 self.journal().tstore(address, index, value)
246 }
247
248 fn log(&mut self, log: Log) {
250 self.journal().log(log);
251 }
252
253 fn selfdestruct(
255 &mut self,
256 address: Address,
257 target: Address,
258 ) -> Option<StateLoad<SelfDestructResult>> {
259 self.journal()
260 .selfdestruct(address, target)
261 .map_err(|e| {
262 *self.error() = Err(e.into());
263 })
264 .ok()
265 }
266}
267
268pub 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) -> u64 {
293 0
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: U256,
342 _value: U256,
343 ) -> Option<StateLoad<SStoreResult>> {
344 None
345 }
346
347 fn sload(&mut self, _address: Address, _key: U256) -> Option<StateLoad<U256>> {
348 None
349 }
350
351 fn tstore(&mut self, _address: Address, _key: U256, _value: U256) {}
352
353 fn tload(&mut self, _address: Address, _key: U256) -> U256 {
354 U256::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}