Skip to main content

zksync_vm2/instruction_handlers/
event.rs

1use primitive_types::H160;
2use zkevm_opcode_defs::ADDRESS_EVENT_WRITER;
3use zksync_vm2_interface::{opcodes, Event, L2ToL1Log, Tracer};
4
5use super::common::boilerplate_ext;
6use crate::{
7    addressing_modes::{Arguments, Immediate1, Register1, Register2, Source},
8    instruction::ExecutionStatus,
9    Instruction, VirtualMachine, World,
10};
11
12fn event<T: Tracer, W: World<T>>(
13    vm: &mut VirtualMachine<T, W>,
14    world: &mut W,
15    tracer: &mut T,
16) -> ExecutionStatus {
17    boilerplate_ext::<opcodes::Event, _, _>(vm, world, tracer, |vm, args, _, _| {
18        if vm.state.current_frame.address == H160::from_low_u64_be(ADDRESS_EVENT_WRITER.into()) {
19            let key = Register1::get(args, &mut vm.state);
20            let value = Register2::get(args, &mut vm.state);
21            let is_first = Immediate1::get(args, &mut vm.state).low_u32() == 1;
22
23            vm.world_diff.record_event(Event {
24                key,
25                value,
26                is_first,
27                shard_id: 0, // shards currently aren't supported
28                tx_number: vm.state.transaction_number,
29            });
30        }
31    })
32}
33
34fn l2_to_l1<T: Tracer, W: World<T>>(
35    vm: &mut VirtualMachine<T, W>,
36    world: &mut W,
37    tracer: &mut T,
38) -> ExecutionStatus {
39    boilerplate_ext::<opcodes::L2ToL1Message, _, _>(vm, world, tracer, |vm, args, _, _| {
40        let key = Register1::get(args, &mut vm.state);
41        let value = Register2::get(args, &mut vm.state);
42        let is_service = Immediate1::get(args, &mut vm.state).low_u32() == 1;
43        vm.world_diff.record_l2_to_l1_log(L2ToL1Log {
44            key,
45            value,
46            is_service,
47            address: vm.state.current_frame.address,
48            shard_id: 0,
49            tx_number: vm.state.transaction_number,
50        });
51    })
52}
53
54impl<T: Tracer, W: World<T>> Instruction<T, W> {
55    /// Creates an [`Event`](opcodes::Event) instruction with the provided params.
56    pub fn from_event(
57        key: Register1,
58        value: Register2,
59        is_first: bool,
60        arguments: Arguments,
61    ) -> Self {
62        Self {
63            handler: event,
64            arguments: arguments
65                .write_source(&key)
66                .write_source(&value)
67                .write_source(&Immediate1(is_first.into())),
68        }
69    }
70
71    /// Creates an [`L2ToL1Message`](opcodes::L2ToL1Message) instruction with the provided params.
72    pub fn from_l2_to_l1_message(
73        key: Register1,
74        value: Register2,
75        is_service: bool,
76        arguments: Arguments,
77    ) -> Self {
78        Self {
79            handler: l2_to_l1,
80            arguments: arguments
81                .write_source(&key)
82                .write_source(&value)
83                .write_source(&Immediate1(is_service.into())),
84        }
85    }
86}