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)]
159#[repr(transparent)] pub struct HeapId(u32);
161
162impl HeapId {
163 pub const FIRST_CALLDATA: Self = Self(7);
165 pub const FIRST: Self = Self(10);
167 pub const FIRST_AUX: Self = Self(11);
169
170 #[doc(hidden)]
172 pub const fn from_u32_unchecked(value: u32) -> Self {
173 Self(value)
174 }
175
176 pub const fn as_u32(self) -> u32 {
178 self.0
179 }
180}
181
182#[derive(Debug, Clone, Copy, PartialEq)]
190pub struct Event {
191 pub key: U256,
193 pub value: U256,
195 pub is_first: bool,
197 pub shard_id: u8,
199 pub tx_number: u16,
201}
202
203#[derive(Debug, Clone, Copy, PartialEq)]
205pub struct L2ToL1Log {
206 pub key: U256,
208 pub value: U256,
210 pub is_service: bool,
212 pub address: H160,
214 pub shard_id: u8,
216 pub tx_number: u16,
218}
219
220#[cfg(test)]
221pub(crate) mod testonly {
222 use primitive_types::{H160, U256};
223
224 use super::{
225 CallframeInterface, Event, Flags, GlobalStateInterface, HeapId, L2ToL1Log, StateInterface,
226 };
227
228 #[derive(Debug)]
229 pub(crate) struct DummyState;
230
231 impl StateInterface for DummyState {
232 fn read_register(&self, _: u8) -> (U256, bool) {
233 unimplemented!()
234 }
235
236 fn set_register(&mut self, _: u8, _: U256, _: bool) {
237 unimplemented!()
238 }
239
240 fn current_frame(&mut self) -> impl CallframeInterface + '_ {
241 DummyState
242 }
243
244 fn number_of_callframes(&self) -> usize {
245 unimplemented!()
246 }
247
248 fn callframe(&mut self, _: usize) -> impl CallframeInterface + '_ {
249 DummyState
250 }
251
252 fn read_heap_byte(&self, _: HeapId, _: u32) -> u8 {
253 unimplemented!()
254 }
255
256 fn read_heap_u256(&self, _: HeapId, _: u32) -> U256 {
257 unimplemented!()
258 }
259
260 fn write_heap_u256(&mut self, _: HeapId, _: u32, _: U256) {
261 unimplemented!()
262 }
263
264 fn flags(&self) -> Flags {
265 unimplemented!()
266 }
267
268 fn set_flags(&mut self, _: Flags) {
269 unimplemented!()
270 }
271
272 fn transaction_number(&self) -> u16 {
273 unimplemented!()
274 }
275
276 fn set_transaction_number(&mut self, _: u16) {
277 unimplemented!()
278 }
279
280 fn context_u128_register(&self) -> u128 {
281 unimplemented!()
282 }
283
284 fn set_context_u128_register(&mut self, _: u128) {
285 unimplemented!()
286 }
287
288 fn get_storage_state(&self) -> impl Iterator<Item = ((H160, U256), U256)> {
289 std::iter::empty()
290 }
291
292 fn get_transient_storage_state(&self) -> impl Iterator<Item = ((H160, U256), U256)> {
293 std::iter::empty()
294 }
295
296 fn get_transient_storage(&self, _: H160, _: U256) -> U256 {
297 unimplemented!()
298 }
299
300 fn write_transient_storage(&mut self, _: H160, _: U256, _: U256) {
301 unimplemented!()
302 }
303
304 fn events(&self) -> impl Iterator<Item = Event> {
305 std::iter::empty()
306 }
307
308 fn l2_to_l1_logs(&self) -> impl Iterator<Item = L2ToL1Log> {
309 std::iter::empty()
310 }
311
312 fn pubdata(&self) -> i32 {
313 unimplemented!()
314 }
315
316 fn set_pubdata(&mut self, _: i32) {
317 unimplemented!()
318 }
319 }
320
321 impl GlobalStateInterface for DummyState {
322 fn get_storage(&mut self, _: H160, _: U256) -> U256 {
323 unimplemented!()
324 }
325 }
326
327 impl CallframeInterface for DummyState {
328 fn address(&self) -> H160 {
329 unimplemented!()
330 }
331
332 fn set_address(&mut self, _: H160) {
333 unimplemented!()
334 }
335
336 fn code_address(&self) -> H160 {
337 unimplemented!()
338 }
339
340 fn set_code_address(&mut self, _: H160) {
341 unimplemented!()
342 }
343
344 fn caller(&self) -> H160 {
345 unimplemented!()
346 }
347
348 fn set_caller(&mut self, _: H160) {
349 unimplemented!()
350 }
351
352 fn program_counter(&self) -> Option<u16> {
353 unimplemented!()
354 }
355
356 fn set_program_counter(&mut self, _: u16) {
357 unimplemented!()
358 }
359
360 fn exception_handler(&self) -> u16 {
361 unimplemented!()
362 }
363
364 fn set_exception_handler(&mut self, _: u16) {
365 unimplemented!()
366 }
367
368 fn is_static(&self) -> bool {
369 unimplemented!()
370 }
371
372 fn is_kernel(&self) -> bool {
373 unimplemented!()
374 }
375
376 fn gas(&self) -> u32 {
377 unimplemented!()
378 }
379
380 fn set_gas(&mut self, _: u32) {
381 unimplemented!()
382 }
383
384 fn context_u128(&self) -> u128 {
385 unimplemented!()
386 }
387
388 fn set_context_u128(&mut self, _: u128) {
389 unimplemented!()
390 }
391
392 fn is_near_call(&self) -> bool {
393 unimplemented!()
394 }
395
396 fn read_stack(&self, _: u16) -> (U256, bool) {
397 unimplemented!()
398 }
399
400 fn write_stack(&mut self, _: u16, _: U256, _: bool) {
401 unimplemented!()
402 }
403
404 fn stack_pointer(&self) -> u16 {
405 unimplemented!()
406 }
407
408 fn set_stack_pointer(&mut self, _: u16) {
409 unimplemented!()
410 }
411
412 fn heap(&self) -> HeapId {
413 unimplemented!()
414 }
415
416 fn heap_bound(&self) -> u32 {
417 unimplemented!()
418 }
419
420 fn set_heap_bound(&mut self, _: u32) {
421 unimplemented!()
422 }
423
424 fn aux_heap(&self) -> HeapId {
425 unimplemented!()
426 }
427
428 fn aux_heap_bound(&self) -> u32 {
429 unimplemented!()
430 }
431
432 fn set_aux_heap_bound(&mut self, _: u32) {
433 unimplemented!()
434 }
435
436 fn read_contract_code(&self, _: u16) -> U256 {
437 unimplemented!()
438 }
439 }
440}