From 34ec535b64c42ec12bb0a8ae54e7759d1cbbab6f Mon Sep 17 00:00:00 2001
From: Alex Ostrovski <aov@matterlabs.dev>
Date: Fri, 24 Jan 2025 11:59:07 +0200
Subject: [PATCH] Add memory stipend for EVM interpreter calls

---
 crates/vm2/src/callframe.rs                     | 6 ++++++
 crates/vm2/src/instruction_handlers/far_call.rs | 5 +++--
 crates/vm2/src/state.rs                         | 1 +
 crates/vm2/src/tracing.rs                       | 1 +
 crates/vm2/src/vm.rs                            | 2 ++
 5 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/crates/vm2/src/callframe.rs b/crates/vm2/src/callframe.rs
index 9142cc8..f9f5175 100644
--- a/crates/vm2/src/callframe.rs
+++ b/crates/vm2/src/callframe.rs
@@ -13,6 +13,9 @@ use crate::{
     Instruction, World,
 };
 
+// FIXME: use `zkevm_opcode_defs::system_params` once it's released
+const NEW_EVM_FRAME_MEMORY_STIPEND: u32 = 56 << 10;
+
 #[derive(Debug)]
 pub(crate) struct Callframe<T, W> {
     pub(crate) address: H160,
@@ -70,11 +73,14 @@ impl<T, W> Callframe<T, W> {
         exception_handler: u16,
         context_u128: u128,
         is_static: bool,
+        is_evm_interpreter: bool,
         world_before_this_frame: Snapshot,
     ) -> Self {
         let is_kernel = is_kernel(address);
         let heap_size = if is_kernel {
             NEW_KERNEL_FRAME_MEMORY_STIPEND
+        } else if is_evm_interpreter {
+            NEW_EVM_FRAME_MEMORY_STIPEND
         } else {
             NEW_FRAME_MEMORY_STIPEND
         };
diff --git a/crates/vm2/src/instruction_handlers/far_call.rs b/crates/vm2/src/instruction_handlers/far_call.rs
index dc46a70..9796469 100644
--- a/crates/vm2/src/instruction_handlers/far_call.rs
+++ b/crates/vm2/src/instruction_handlers/far_call.rs
@@ -59,7 +59,7 @@ where
                 0
             };
 
-        let failing_part = (|| {
+        let fallible_part = (|| {
             let decommit_result = vm.world_diff.decommit(
                 world,
                 tracer,
@@ -105,7 +105,7 @@ where
 
         // A far call pushes a new frame and returns from it in the next instruction if it panics.
         let (calldata, program, is_evm_interpreter) =
-            failing_part.unwrap_or_else(|| (U256::zero().into(), Program::new_panicking(), false));
+            fallible_part.unwrap_or_else(|| (U256::zero().into(), Program::new_panicking(), false));
 
         let new_frame_is_static = IS_STATIC || vm.state.current_frame.is_static;
         vm.push_frame::<M>(
@@ -114,6 +114,7 @@ where
             new_frame_gas,
             exception_handler,
             new_frame_is_static && !is_evm_interpreter,
+            is_evm_interpreter,
             calldata.memory_page,
             vm.world_diff.snapshot(),
         );
diff --git a/crates/vm2/src/state.rs b/crates/vm2/src/state.rs
index 8494c49..cd6faab 100644
--- a/crates/vm2/src/state.rs
+++ b/crates/vm2/src/state.rs
@@ -64,6 +64,7 @@ impl<T, W> State<T, W> {
                 0,
                 0,
                 false,
+                false,
                 world_before_this_frame,
             ),
             previous_frames: vec![],
diff --git a/crates/vm2/src/tracing.rs b/crates/vm2/src/tracing.rs
index 790efb4..03bdbda 100644
--- a/crates/vm2/src/tracing.rs
+++ b/crates/vm2/src/tracing.rs
@@ -474,6 +474,7 @@ mod test {
                 (*counter).into(),
                 *counter,
                 false,
+                false,
                 HeapId::from_u32_unchecked(5),
                 vm.world_diff.snapshot(),
             );
diff --git a/crates/vm2/src/vm.rs b/crates/vm2/src/vm.rs
index 9dcc486..ef1f7bc 100644
--- a/crates/vm2/src/vm.rs
+++ b/crates/vm2/src/vm.rs
@@ -199,6 +199,7 @@ impl<T: Tracer, W> VirtualMachine<T, W> {
         gas: u32,
         exception_handler: u16,
         is_static: bool,
+        is_evm_interpreter: bool,
         calldata_heap: HeapId,
         world_before_this_frame: Snapshot,
     ) {
@@ -227,6 +228,7 @@ impl<T: Tracer, W> VirtualMachine<T, W> {
                 self.state.context_u128
             },
             is_static,
+            is_evm_interpreter,
             world_before_this_frame,
         );
         self.state.context_u128 = 0;