Skip to content

Commit

Permalink
fix!: Remove EVM emulator gas stipend (#82)
Browse files Browse the repository at this point in the history
# What ❔

Removes the EVM emulator gas stipend and replaces it with a memory
stipend.

## Why ❔

Aligns with the changes in the legacy VM.
  • Loading branch information
slowli authored Jan 27, 2025
1 parent 70a6e30 commit bf63339
Show file tree
Hide file tree
Showing 11 changed files with 17 additions and 197 deletions.
6 changes: 0 additions & 6 deletions crates/vm2-interface/src/state_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ pub trait CallframeInterface {
fn gas(&self) -> u32;
/// Sets the remaining amount of gas.
fn set_gas(&mut self, new_gas: u32);
/// Additional gas provided for the duration of this callframe.
fn stipend(&self) -> u32;

/// Returns the context value for this call. This context is accessible via [`ContextU128`](crate::opcodes::ContextU128) opcode.
fn context_u128(&self) -> u128;
Expand Down Expand Up @@ -379,10 +377,6 @@ pub(crate) mod testonly {
unimplemented!()
}

fn stipend(&self) -> u32 {
unimplemented!()
}

fn context_u128(&self) -> u128 {
unimplemented!()
}
Expand Down
11 changes: 6 additions & 5 deletions crates/vm2/src/callframe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -25,7 +28,6 @@ pub(crate) struct Callframe<T, W> {
pub(crate) stack: Box<Stack>,
pub(crate) sp: u16,
pub(crate) gas: u32,
pub(crate) stipend: u32,
pub(crate) near_calls: Vec<NearCallFrame>,
pub(crate) pc: *const Instruction<T, W>,
pub(crate) program: Program<T, W>,
Expand Down Expand Up @@ -68,15 +70,17 @@ impl<T, W> Callframe<T, W> {
aux_heap: HeapId,
calldata_heap: HeapId,
gas: u32,
stipend: u32,
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
};
Expand All @@ -99,7 +103,6 @@ impl<T, W> Callframe<T, W> {
heaps_i_am_keeping_alive: vec![],
sp: 0,
gas,
stipend,
exception_handler,
near_calls: vec![],
world_before_this_frame,
Expand Down Expand Up @@ -253,7 +256,6 @@ impl<T, W> Clone for Callframe<T, W> {
stack: self.stack.clone(),
sp: self.sp,
gas: self.gas,
stipend: self.stipend,
near_calls: self.near_calls.clone(),
pc: self.pc,
program: self.program.clone(),
Expand All @@ -279,7 +281,6 @@ impl<T, W> PartialEq for Callframe<T, W> {
&& self.stack == other.stack
&& self.sp == other.sp
&& self.gas == other.gas
&& self.stipend == other.stipend
&& self.near_calls == other.near_calls
&& self.pc == other.pc
&& self.program == other.program
Expand Down
20 changes: 4 additions & 16 deletions crates/vm2/src/instruction_handlers/far_call.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use primitive_types::U256;
use zkevm_opcode_defs::{
system_params::{EVM_SIMULATOR_STIPEND, MSG_VALUE_SIMULATOR_ADDITIVE_COST},
ADDRESS_MSG_VALUE,
};
use zkevm_opcode_defs::{system_params::MSG_VALUE_SIMULATOR_ADDITIVE_COST, ADDRESS_MSG_VALUE};
use zksync_vm2_interface::{
opcodes::{FarCall, TypeLevelCallingMode},
Tracer,
Expand Down Expand Up @@ -62,7 +59,7 @@ where
0
};

let failing_part = (|| {
let fallible_part = (|| {
let decommit_result = vm.world_diff.decommit(
world,
tracer,
Expand Down Expand Up @@ -108,25 +105,16 @@ 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));

let stipend = if is_evm_interpreter {
EVM_SIMULATOR_STIPEND
} else {
0
};
let new_frame_gas = new_frame_gas
.checked_add(stipend)
.expect("stipend must not cause overflow");
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>(
u256_into_address(destination_address),
program,
new_frame_gas,
stipend,
exception_handler,
new_frame_is_static && !is_evm_interpreter,
is_evm_interpreter,
calldata.memory_page,
vm.world_diff.snapshot(),
);
Expand Down
6 changes: 1 addition & 5 deletions crates/vm2/src/instruction_handlers/ret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,7 @@ fn naked_ret<T: Tracer, W: World<T>, RT: TypeLevelReturnType, const TO_LABEL: bo
result
};

let leftover_gas = vm
.state
.current_frame
.gas
.saturating_sub(vm.state.current_frame.stipend);
let leftover_gas = vm.state.current_frame.gas;

let Some(FrameRemnant {
exception_handler,
Expand Down
6 changes: 1 addition & 5 deletions crates/vm2/src/single_instruction_test/callframe.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use arbitrary::Arbitrary;
use primitive_types::H160;
use zkevm_opcode_defs::EVM_SIMULATOR_STIPEND;
use zksync_vm2_interface::{HeapId, Tracer};

use super::stack::{Stack, StackPool};
Expand Down Expand Up @@ -40,9 +39,7 @@ impl<'a, T: Tracer, W: World<T>> Arbitrary<'a> for Callframe<T, W> {
is_kernel: is_kernel(address),
stack: Box::new(Stack::new_arbitrary(u, calldata_heap, base_page)?),
sp: u.arbitrary()?,
// It is assumed that it is always possible to add the stipend
gas: u.int_in_range(0..=u32::MAX - EVM_SIMULATOR_STIPEND)?,
stipend: u.arbitrary()?,
gas: u.arbitrary()?,
near_calls: vec![],
pc: program.instruction(0).unwrap(),
program,
Expand Down Expand Up @@ -78,7 +75,6 @@ impl<T: Tracer, W: World<T>> Callframe<T, W> {
stack: StackPool {}.get(),
sp: 0,
gas: 0,
stipend: 0,
near_calls: vec![],
pc: std::ptr::null(),
program: Program::for_decommit(),
Expand Down
2 changes: 1 addition & 1 deletion crates/vm2/src/single_instruction_test/state_to_zk_evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn vm2_frame_to_zk_evm_frames<T, W>(
heap_bound: frame.heap_size,
aux_heap_bound: frame.aux_heap_size,
total_pubdata_spent: PubdataCost(0),
stipend: frame.stipend,
stipend: 0,
};

let mut result = vec![far_frame];
Expand Down
2 changes: 1 addition & 1 deletion crates/vm2/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl<T, W> State<T, W> {
gas,
0,
0,
0,
false,
false,
world_before_this_frame,
),
Expand Down
1 change: 0 additions & 1 deletion crates/vm2/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@
mod bytecode_behaviour;
mod far_call_decommitment;
mod panic;
mod stipend;
mod trace_failing_far_call;
150 changes: 0 additions & 150 deletions crates/vm2/src/tests/stipend.rs

This file was deleted.

6 changes: 1 addition & 5 deletions crates/vm2/src/tracing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,6 @@ impl<T: Tracer, W: World<T>> CallframeInterface for CallframeWrapper<'_, T, W> {
self.frame.is_kernel
}

fn stipend(&self) -> u32 {
self.frame.stipend
}

fn context_u128(&self) -> u128 {
self.frame.context_u128
}
Expand Down Expand Up @@ -472,9 +468,9 @@ mod test {
H160::from_low_u64_be(1),
program.clone(),
(*counter).into(),
0,
*counter,
false,
false,
HeapId::from_u32_unchecked(5),
vm.world_diff.snapshot(),
);
Expand Down
4 changes: 2 additions & 2 deletions crates/vm2/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ impl<T: Tracer, W> VirtualMachine<T, W> {
code_address: H160,
program: Program<T, W>,
gas: u32,
stipend: u32,
exception_handler: u16,
is_static: bool,
is_evm_interpreter: bool,
calldata_heap: HeapId,
world_before_this_frame: Snapshot,
) {
Expand All @@ -221,14 +221,14 @@ impl<T: Tracer, W> VirtualMachine<T, W> {
self.state.heaps.allocate(),
calldata_heap,
gas,
stipend,
exception_handler,
if M::VALUE == CallingMode::Delegate {
self.state.current_frame.context_u128
} else {
self.state.context_u128
},
is_static,
is_evm_interpreter,
world_before_this_frame,
);
self.state.context_u128 = 0;
Expand Down

0 comments on commit bf63339

Please sign in to comment.