Skip to content

refactor(levm): Call frame refactor #2583

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions crates/vm/levm/src/hooks/default_hook.rs
Original file line number Diff line number Diff line change
@@ -324,9 +324,10 @@ impl Hook for DefaultHook {
fn finalize_execution(
&self,
vm: &mut VM<'_>,
initial_call_frame: &CallFrame,
report: &mut ExecutionReport,
) -> Result<(), VMError> {
let initial_call_frame = vm.current_call_frame()?.clone();

// POST-EXECUTION Changes
let sender_address = initial_call_frame.msg_sender;
let receiver_address = initial_call_frame.to;
@@ -383,7 +384,7 @@ impl Hook for DefaultHook {
.ok_or(VMError::Internal(InternalError::UndefinedState(-2)))?;

let actual_gas_used = if vm.env.config.fork >= Fork::Prague {
let minimum_gas_consumed = vm.get_min_gas_used(initial_call_frame)?;
let minimum_gas_consumed = vm.get_min_gas_used(&initial_call_frame)?;
exec_gas_consumed.max(minimum_gas_consumed)
} else {
exec_gas_consumed
1 change: 0 additions & 1 deletion crates/vm/levm/src/hooks/hook.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@ pub trait Hook {
fn finalize_execution(
&self,
vm: &mut VM<'_>,
initial_call_frame: &CallFrame,
report: &mut ExecutionReport,
) -> Result<(), VMError>;
}
5 changes: 3 additions & 2 deletions crates/vm/levm/src/hooks/l2_hook.rs
Original file line number Diff line number Diff line change
@@ -220,9 +220,10 @@ impl Hook for L2Hook {
fn finalize_execution(
&self,
vm: &mut crate::vm::VM<'_>,
initial_call_frame: &crate::call_frame::CallFrame,
report: &mut crate::errors::ExecutionReport,
) -> Result<(), crate::errors::VMError> {
let initial_call_frame = vm.current_call_frame()?.clone();

// POST-EXECUTION Changes
let receiver_address = initial_call_frame.to;

@@ -263,7 +264,7 @@ impl Hook for L2Hook {
report.gas_refunded = refunded_gas;

if vm.env.config.fork >= Fork::Prague {
let floor_gas_price = vm.get_min_gas_used(initial_call_frame)?;
let floor_gas_price = vm.get_min_gas_used(&initial_call_frame)?;
let execution_gas_used = consumed_gas.saturating_sub(refunded_gas);
if floor_gas_price > execution_gas_used {
consumed_gas = floor_gas_price;
17 changes: 5 additions & 12 deletions crates/vm/levm/src/opcode_handlers/system.rs
Original file line number Diff line number Diff line change
@@ -900,34 +900,27 @@ impl<'a> VM<'a> {
Ok(OpcodeResult::Continue { pc_increment: 0 })
}

pub fn handle_return(
&mut self,
call_frame: &CallFrame,
tx_report: &ExecutionReport,
) -> Result<bool, VMError> {
if call_frame.depth == 0 {
self.call_frames.push(call_frame.clone());
return Ok(false);
}
pub fn handle_return(&mut self, tx_report: &ExecutionReport) -> Result<bool, VMError> {
let retdata = self
.return_data
.pop()
.ok_or(VMError::Internal(InternalError::CouldNotPopCallframe))?;
if retdata.is_create {
self.handle_return_create(tx_report, retdata)?;
} else {
self.handle_return_call(call_frame, tx_report, retdata)?;
self.handle_return_call(tx_report, retdata)?;
}
Ok(true)
}

pub fn handle_return_call(
&mut self,
call_frame: &CallFrame,
tx_report: &ExecutionReport,
retdata: RetData,
) -> Result<(), VMError> {
// Return gas left from subcontext
let gas_left_from_new_call_frame = call_frame
let gas_left_from_new_call_frame = self
.current_call_frame_mut()?
.gas_limit
.checked_sub(tx_report.gas_used)
.ok_or(InternalError::GasOverflow)?;
26 changes: 9 additions & 17 deletions crates/vm/levm/src/vm.rs
Original file line number Diff line number Diff line change
@@ -359,7 +359,7 @@ impl<'a> VM<'a> {
.ok_or(VMError::Internal(InternalError::CouldNotPopCallframe))?;
let report =
self.handle_precompile_result(precompile_result, backup, &mut current_call_frame)?;
self.handle_return(&current_call_frame, &report)?;
self.handle_return(&report)?;
self.current_call_frame_mut()?.increment_pc_by(1)?;
return Ok(report);
}
@@ -369,29 +369,26 @@ impl<'a> VM<'a> {

let op_result = self.handle_current_opcode(opcode);

let mut current_call_frame = self
.call_frames
.pop()
.ok_or(VMError::Internal(InternalError::CouldNotPopCallframe))?;

match op_result {
Ok(OpcodeResult::Continue { pc_increment }) => self
.current_call_frame_mut()?
.increment_pc_by(pc_increment)?,
Ok(OpcodeResult::Halt) => {
let mut current_call_frame = self
.call_frames
.pop()
.ok_or(VMError::Internal(InternalError::CouldNotPopCallframe))?;
let report = self.handle_opcode_result(&mut current_call_frame)?;
if self.handle_return(&current_call_frame, &report)? {
if self.handle_return(&report)? {
self.current_call_frame_mut()?.increment_pc_by(1)?;
} else {
return Ok(report);
}
}
Err(error) => {
let mut current_call_frame = self
.call_frames
.pop()
.ok_or(VMError::Internal(InternalError::CouldNotPopCallframe))?;
let report = self.handle_opcode_error(error, &mut current_call_frame)?;
if self.handle_return(&current_call_frame, &report)? {
if self.handle_return(&report)? {
self.current_call_frame_mut()?.increment_pc_by(1)?;
} else {
return Ok(report);
@@ -616,14 +613,9 @@ impl<'a> VM<'a> {
// NOTE: ATTOW the default hook is created in VM::new(), so
// (in theory) _at least_ the default finalize execution should
// run
let call_frame = self
.call_frames
.pop()
.ok_or(VMError::Internal(InternalError::CouldNotPopCallframe))?;
for hook in self.hooks.clone() {
hook.finalize_execution(self, &call_frame, report)?;
hook.finalize_execution(self, report)?;
}
self.call_frames.push(call_frame);

Ok(())
}