1use primitive_types::{H160, U256};
2
3pub trait StateInterface {
5 fn read_register(&self, register: u8) -> (U256, bool);
7 fn set_register(&mut self, register: u8, value: U256, is_pointer: bool);
9
10 fn current_frame(&mut self) -> impl CallframeInterface + '_;
12 fn number_of_callframes(&self) -> usize;
14 fn callframe(&mut self, n: usize) -> impl CallframeInterface + '_;
17
18 fn read_heap_byte(&self, heap: HeapId, offset: u32) -> u8;
20 fn read_heap_u256(&self, heap: HeapId, offset: u32) -> U256;
23 fn write_heap_u256(&mut self, heap: HeapId, offset: u32, value: U256);
26
27 fn flags(&self) -> Flags;
29 fn set_flags(&mut self, flags: Flags);
31
32 fn transaction_number(&self) -> u16;
34 fn set_transaction_number(&mut self, value: u16);
36
37 fn context_u128_register(&self) -> u128;
39 fn set_context_u128_register(&mut self, value: u128);
41
42 fn get_storage_state(&self) -> impl Iterator<Item = ((H160, U256), U256)>;
44
45 fn get_transient_storage_state(&self) -> impl Iterator<Item = ((H160, U256), U256)>;
47 fn get_transient_storage(&self, address: H160, slot: U256) -> U256;
49 fn write_transient_storage(&mut self, address: H160, slot: U256, value: U256);
51
52 fn events(&self) -> impl Iterator<Item = Event>;
54 fn l2_to_l1_logs(&self) -> impl Iterator<Item = L2ToL1Log>;
56
57 fn pubdata(&self) -> i32;
59 fn set_pubdata(&mut self, value: i32);
61}
62
63pub trait GlobalStateInterface: StateInterface {
65 fn get_storage(&mut self, address: H160, slot: U256) -> U256;
67}
68
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
71pub struct Flags {
72 pub less_than: bool,
74 pub equal: bool,
76 pub greater: bool,
78}
79
80pub trait CallframeInterface {
82 fn address(&self) -> H160;
85 fn set_address(&mut self, address: H160);
87 fn code_address(&self) -> H160;
89 fn set_code_address(&mut self, address: H160);
92 fn caller(&self) -> H160;
94 fn set_caller(&mut self, address: H160);
96
97 fn program_counter(&self) -> Option<u16>;
100 fn set_program_counter(&mut self, value: u16);
103
104 fn exception_handler(&self) -> u16;
106 fn set_exception_handler(&mut self, value: u16);
108
109 fn is_static(&self) -> bool;
111 fn is_kernel(&self) -> bool;
113
114 fn gas(&self) -> u32;
116 fn set_gas(&mut self, new_gas: u32);
118
119 fn context_u128(&self) -> u128;
121 fn set_context_u128(&mut self, value: u128);
123
124 fn is_near_call(&self) -> bool;
126
127 fn read_stack(&self, index: u16) -> (U256, bool);
129 fn write_stack(&mut self, index: u16, value: U256, is_pointer: bool);
131
132 fn stack_pointer(&self) -> u16;
134 fn set_stack_pointer(&mut self, value: u16);
136
137 fn heap(&self) -> HeapId;
139 fn heap_bound(&self) -> u32;
141 fn set_heap_bound(&mut self, value: u32);
143
144 fn aux_heap(&self) -> HeapId;
146 fn aux_heap_bound(&self) -> u32;
148 fn set_aux_heap_bound(&mut self, value: u32);
150
151 fn read_contract_code(&self, slot: u16) -> U256;
153}
154
155#[derive(Copy, Clone, PartialEq, Debug)]
159pub struct HeapId(u32);
160
161impl HeapId {
162 pub const FIRST_CALLDATA: Self = Self(1);
164 pub const FIRST: Self = Self(2);
166 pub const FIRST_AUX: Self = Self(3);
168
169 #[doc(hidden)]
171 pub const fn from_u32_unchecked(value: u32) -> Self {
172 Self(value)
173 }
174
175 pub const fn as_u32(self) -> u32 {
177 self.0
178 }
179}
180
181#[derive(Debug, Clone, Copy, PartialEq)]
186pub struct Event {
187 pub key: U256,
189 pub value: U256,
191 pub is_first: bool,
193 pub shard_id: u8,
195 pub tx_number: u16,
197}
198
199#[derive(Debug, Clone, Copy, PartialEq)]
201pub struct L2ToL1Log {
202 pub key: U256,
204 pub value: U256,
206 pub is_service: bool,
208 pub address: H160,
210 pub shard_id: u8,
212 pub tx_number: u16,
214}
215
216#[cfg(test)]
217pub(crate) mod testonly {
218 use primitive_types::{H160, U256};
219
220 use super::{
221 CallframeInterface, Event, Flags, GlobalStateInterface, HeapId, L2ToL1Log, StateInterface,
222 };
223
224 #[derive(Debug)]
225 pub(crate) struct DummyState;
226
227 impl StateInterface for DummyState {
228 fn read_register(&self, _: u8) -> (U256, bool) {
229 unimplemented!()
230 }
231
232 fn set_register(&mut self, _: u8, _: U256, _: bool) {
233 unimplemented!()
234 }
235
236 fn current_frame(&mut self) -> impl CallframeInterface + '_ {
237 DummyState
238 }
239
240 fn number_of_callframes(&self) -> usize {
241 unimplemented!()
242 }
243
244 fn callframe(&mut self, _: usize) -> impl CallframeInterface + '_ {
245 DummyState
246 }
247
248 fn read_heap_byte(&self, _: HeapId, _: u32) -> u8 {
249 unimplemented!()
250 }
251
252 fn read_heap_u256(&self, _: HeapId, _: u32) -> U256 {
253 unimplemented!()
254 }
255
256 fn write_heap_u256(&mut self, _: HeapId, _: u32, _: U256) {
257 unimplemented!()
258 }
259
260 fn flags(&self) -> Flags {
261 unimplemented!()
262 }
263
264 fn set_flags(&mut self, _: Flags) {
265 unimplemented!()
266 }
267
268 fn transaction_number(&self) -> u16 {
269 unimplemented!()
270 }
271
272 fn set_transaction_number(&mut self, _: u16) {
273 unimplemented!()
274 }
275
276 fn context_u128_register(&self) -> u128 {
277 unimplemented!()
278 }
279
280 fn set_context_u128_register(&mut self, _: u128) {
281 unimplemented!()
282 }
283
284 fn get_storage_state(&self) -> impl Iterator<Item = ((H160, U256), U256)> {
285 std::iter::empty()
286 }
287
288 fn get_transient_storage_state(&self) -> impl Iterator<Item = ((H160, U256), U256)> {
289 std::iter::empty()
290 }
291
292 fn get_transient_storage(&self, _: H160, _: U256) -> U256 {
293 unimplemented!()
294 }
295
296 fn write_transient_storage(&mut self, _: H160, _: U256, _: U256) {
297 unimplemented!()
298 }
299
300 fn events(&self) -> impl Iterator<Item = Event> {
301 std::iter::empty()
302 }
303
304 fn l2_to_l1_logs(&self) -> impl Iterator<Item = L2ToL1Log> {
305 std::iter::empty()
306 }
307
308 fn pubdata(&self) -> i32 {
309 unimplemented!()
310 }
311
312 fn set_pubdata(&mut self, _: i32) {
313 unimplemented!()
314 }
315 }
316
317 impl GlobalStateInterface for DummyState {
318 fn get_storage(&mut self, _: H160, _: U256) -> U256 {
319 unimplemented!()
320 }
321 }
322
323 impl CallframeInterface for DummyState {
324 fn address(&self) -> H160 {
325 unimplemented!()
326 }
327
328 fn set_address(&mut self, _: H160) {
329 unimplemented!()
330 }
331
332 fn code_address(&self) -> H160 {
333 unimplemented!()
334 }
335
336 fn set_code_address(&mut self, _: H160) {
337 unimplemented!()
338 }
339
340 fn caller(&self) -> H160 {
341 unimplemented!()
342 }
343
344 fn set_caller(&mut self, _: H160) {
345 unimplemented!()
346 }
347
348 fn program_counter(&self) -> Option<u16> {
349 unimplemented!()
350 }
351
352 fn set_program_counter(&mut self, _: u16) {
353 unimplemented!()
354 }
355
356 fn exception_handler(&self) -> u16 {
357 unimplemented!()
358 }
359
360 fn set_exception_handler(&mut self, _: u16) {
361 unimplemented!()
362 }
363
364 fn is_static(&self) -> bool {
365 unimplemented!()
366 }
367
368 fn is_kernel(&self) -> bool {
369 unimplemented!()
370 }
371
372 fn gas(&self) -> u32 {
373 unimplemented!()
374 }
375
376 fn set_gas(&mut self, _: u32) {
377 unimplemented!()
378 }
379
380 fn context_u128(&self) -> u128 {
381 unimplemented!()
382 }
383
384 fn set_context_u128(&mut self, _: u128) {
385 unimplemented!()
386 }
387
388 fn is_near_call(&self) -> bool {
389 unimplemented!()
390 }
391
392 fn read_stack(&self, _: u16) -> (U256, bool) {
393 unimplemented!()
394 }
395
396 fn write_stack(&mut self, _: u16, _: U256, _: bool) {
397 unimplemented!()
398 }
399
400 fn stack_pointer(&self) -> u16 {
401 unimplemented!()
402 }
403
404 fn set_stack_pointer(&mut self, _: u16) {
405 unimplemented!()
406 }
407
408 fn heap(&self) -> HeapId {
409 unimplemented!()
410 }
411
412 fn heap_bound(&self) -> u32 {
413 unimplemented!()
414 }
415
416 fn set_heap_bound(&mut self, _: u32) {
417 unimplemented!()
418 }
419
420 fn aux_heap(&self) -> HeapId {
421 unimplemented!()
422 }
423
424 fn aux_heap_bound(&self) -> u32 {
425 unimplemented!()
426 }
427
428 fn set_aux_heap_bound(&mut self, _: u32) {
429 unimplemented!()
430 }
431
432 fn read_contract_code(&self, _: u16) -> U256 {
433 unimplemented!()
434 }
435 }
436}