From 9b9721fafc4f588fb9f4ab82e6583ec095eff981 Mon Sep 17 00:00:00 2001 From: Tomas Fabrizio Orsi Date: Thu, 30 Jan 2025 17:52:44 -0300 Subject: [PATCH] refactor(levm): make `increase_consumed_gas` a callframe method instead of a VM method. (#1843) **Motivation** `increase_consumed_gas` currently is a VM method. However, it receives a mutable reference to a Callframe, modifies it and does not use any information provided by the VM. **Description** Make `increase_consumed_gas` a Callframe, thus removing methods from the VM itself. Closes #1842 --------- Co-authored-by: fborello-lambda --- crates/vm/levm/src/call_frame.rs | 25 ++++++- crates/vm/levm/src/execution_handlers.rs | 4 +- .../vm/levm/src/opcode_handlers/arithmetic.rs | 22 +++--- .../src/opcode_handlers/bitwise_comparison.rs | 28 +++---- crates/vm/levm/src/opcode_handlers/block.rs | 22 +++--- crates/vm/levm/src/opcode_handlers/dup.rs | 2 +- .../levm/src/opcode_handlers/environment.rs | 66 ++++++++--------- .../vm/levm/src/opcode_handlers/exchange.rs | 2 +- crates/vm/levm/src/opcode_handlers/keccak.rs | 9 ++- crates/vm/levm/src/opcode_handlers/logging.rs | 15 ++-- crates/vm/levm/src/opcode_handlers/push.rs | 4 +- .../stack_memory_storage_flow.rs | 66 ++++++++--------- crates/vm/levm/src/opcode_handlers/system.rs | 73 ++++++++----------- crates/vm/levm/src/vm.rs | 25 +------ 14 files changed, 175 insertions(+), 188 deletions(-) diff --git a/crates/vm/levm/src/call_frame.rs b/crates/vm/levm/src/call_frame.rs index d87b309bdd..33c36ce021 100644 --- a/crates/vm/levm/src/call_frame.rs +++ b/crates/vm/levm/src/call_frame.rs @@ -1,6 +1,6 @@ use crate::{ constants::STACK_LIMIT, - errors::{InternalError, VMError}, + errors::{InternalError, OutOfGasError, VMError}, memory::Memory, opcodes::Opcode, utils::get_valid_jump_destinations, @@ -144,4 +144,27 @@ impl CallFrame { .ok_or(VMError::Internal(InternalError::PCOverflowed))?; Ok(()) } + + pub fn increment_pc(&mut self) -> Result<(), VMError> { + self.increment_pc_by(1) + } + + pub fn pc(&self) -> usize { + self.pc + } + + /// Increases gas consumption of CallFrame and Environment, returning an error if the callframe gas limit is reached. + pub fn increase_consumed_gas(&mut self, gas: u64) -> Result<(), VMError> { + let potential_consumed_gas = self + .gas_used + .checked_add(gas) + .ok_or(OutOfGasError::ConsumedGasOverflow)?; + if potential_consumed_gas > self.gas_limit { + return Err(VMError::OutOfGas(OutOfGasError::MaxGasLimitExceeded)); + } + + self.gas_used = potential_consumed_gas; + + Ok(()) + } } diff --git a/crates/vm/levm/src/execution_handlers.rs b/crates/vm/levm/src/execution_handlers.rs index 2ccdc41e4d..0079f2adc8 100644 --- a/crates/vm/levm/src/execution_handlers.rs +++ b/crates/vm/levm/src/execution_handlers.rs @@ -193,8 +193,8 @@ impl VM { Err(VMError::ContractOutputTooBig) } else if contract_code.first().unwrap_or(&0) == &INVALID_CONTRACT_PREFIX { Err(VMError::InvalidContractPrefix) - } else if self - .increase_consumed_gas(current_call_frame, code_deposit_cost) + } else if current_call_frame + .increase_consumed_gas(code_deposit_cost) .is_err() { Err(VMError::OutOfGas(OutOfGasError::MaxGasLimitExceeded)) diff --git a/crates/vm/levm/src/opcode_handlers/arithmetic.rs b/crates/vm/levm/src/opcode_handlers/arithmetic.rs index ab71ffaec5..1598b98653 100644 --- a/crates/vm/levm/src/opcode_handlers/arithmetic.rs +++ b/crates/vm/levm/src/opcode_handlers/arithmetic.rs @@ -15,7 +15,7 @@ use super::bitwise_comparison::checked_shift_right; impl VM { // ADD operation pub fn op_add(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::ADD)?; + current_call_frame.increase_consumed_gas(gas_cost::ADD)?; let augend = current_call_frame.stack.pop()?; let addend = current_call_frame.stack.pop()?; @@ -27,7 +27,7 @@ impl VM { // SUB operation pub fn op_sub(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SUB)?; + current_call_frame.increase_consumed_gas(gas_cost::SUB)?; let minuend = current_call_frame.stack.pop()?; let subtrahend = current_call_frame.stack.pop()?; @@ -39,7 +39,7 @@ impl VM { // MUL operation pub fn op_mul(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::MUL)?; + current_call_frame.increase_consumed_gas(gas_cost::MUL)?; let multiplicand = current_call_frame.stack.pop()?; let multiplier = current_call_frame.stack.pop()?; @@ -51,7 +51,7 @@ impl VM { // DIV operation pub fn op_div(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::DIV)?; + current_call_frame.increase_consumed_gas(gas_cost::DIV)?; let dividend = current_call_frame.stack.pop()?; let divisor = current_call_frame.stack.pop()?; @@ -66,7 +66,7 @@ impl VM { // SDIV operation pub fn op_sdiv(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SDIV)?; + current_call_frame.increase_consumed_gas(gas_cost::SDIV)?; let dividend = current_call_frame.stack.pop()?; let divisor = current_call_frame.stack.pop()?; @@ -97,7 +97,7 @@ impl VM { // MOD operation pub fn op_mod(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::MOD)?; + current_call_frame.increase_consumed_gas(gas_cost::MOD)?; let dividend = current_call_frame.stack.pop()?; let divisor = current_call_frame.stack.pop()?; @@ -111,7 +111,7 @@ impl VM { // SMOD operation pub fn op_smod(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SMOD)?; + current_call_frame.increase_consumed_gas(gas_cost::SMOD)?; let unchecked_dividend = current_call_frame.stack.pop()?; let unchecked_divisor = current_call_frame.stack.pop()?; @@ -148,7 +148,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::ADDMOD)?; + current_call_frame.increase_consumed_gas(gas_cost::ADDMOD)?; let augend = current_call_frame.stack.pop()?; let addend = current_call_frame.stack.pop()?; @@ -184,7 +184,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::MULMOD)?; + current_call_frame.increase_consumed_gas(gas_cost::MULMOD)?; let multiplicand = current_call_frame.stack.pop()?; let multiplier = current_call_frame.stack.pop()?; @@ -223,7 +223,7 @@ impl VM { let gas_cost = gas_cost::exp(exponent)?; - self.increase_consumed_gas(current_call_frame, gas_cost)?; + current_call_frame.increase_consumed_gas(gas_cost)?; let power = base.overflowing_pow(exponent).0; current_call_frame.stack.push(power)?; @@ -236,7 +236,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SIGNEXTEND)?; + current_call_frame.increase_consumed_gas(gas_cost::SIGNEXTEND)?; let byte_size_minus_one = current_call_frame.stack.pop()?; let value_to_extend = current_call_frame.stack.pop()?; diff --git a/crates/vm/levm/src/opcode_handlers/bitwise_comparison.rs b/crates/vm/levm/src/opcode_handlers/bitwise_comparison.rs index a79879beda..114a413752 100644 --- a/crates/vm/levm/src/opcode_handlers/bitwise_comparison.rs +++ b/crates/vm/levm/src/opcode_handlers/bitwise_comparison.rs @@ -13,7 +13,7 @@ use ethrex_core::U256; impl VM { // LT operation pub fn op_lt(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::LT)?; + current_call_frame.increase_consumed_gas(gas_cost::LT)?; let lho = current_call_frame.stack.pop()?; let rho = current_call_frame.stack.pop()?; let result = u256_from_bool(lho < rho); @@ -24,7 +24,7 @@ impl VM { // GT operation pub fn op_gt(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::GT)?; + current_call_frame.increase_consumed_gas(gas_cost::GT)?; let lho = current_call_frame.stack.pop()?; let rho = current_call_frame.stack.pop()?; let result = u256_from_bool(lho > rho); @@ -35,7 +35,7 @@ impl VM { // SLT operation (signed less than) pub fn op_slt(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SLT)?; + current_call_frame.increase_consumed_gas(gas_cost::SLT)?; let lho = current_call_frame.stack.pop()?; let rho = current_call_frame.stack.pop()?; let lho_is_negative = lho.bit(255); @@ -54,7 +54,7 @@ impl VM { // SGT operation (signed greater than) pub fn op_sgt(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SGT)?; + current_call_frame.increase_consumed_gas(gas_cost::SGT)?; let lho = current_call_frame.stack.pop()?; let rho = current_call_frame.stack.pop()?; let lho_is_negative = lho.bit(255); @@ -73,7 +73,7 @@ impl VM { // EQ operation (equality check) pub fn op_eq(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::EQ)?; + current_call_frame.increase_consumed_gas(gas_cost::EQ)?; let lho = current_call_frame.stack.pop()?; let rho = current_call_frame.stack.pop()?; let result = u256_from_bool(lho == rho); @@ -88,7 +88,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::ISZERO)?; + current_call_frame.increase_consumed_gas(gas_cost::ISZERO)?; let operand = current_call_frame.stack.pop()?; let result = u256_from_bool(operand.is_zero()); @@ -100,7 +100,7 @@ impl VM { // AND operation pub fn op_and(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::AND)?; + current_call_frame.increase_consumed_gas(gas_cost::AND)?; let a = current_call_frame.stack.pop()?; let b = current_call_frame.stack.pop()?; current_call_frame.stack.push(a & b)?; @@ -110,7 +110,7 @@ impl VM { // OR operation pub fn op_or(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::OR)?; + current_call_frame.increase_consumed_gas(gas_cost::OR)?; let a = current_call_frame.stack.pop()?; let b = current_call_frame.stack.pop()?; current_call_frame.stack.push(a | b)?; @@ -120,7 +120,7 @@ impl VM { // XOR operation pub fn op_xor(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::XOR)?; + current_call_frame.increase_consumed_gas(gas_cost::XOR)?; let a = current_call_frame.stack.pop()?; let b = current_call_frame.stack.pop()?; current_call_frame.stack.push(a ^ b)?; @@ -130,7 +130,7 @@ impl VM { // NOT operation pub fn op_not(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::NOT)?; + current_call_frame.increase_consumed_gas(gas_cost::NOT)?; let a = current_call_frame.stack.pop()?; current_call_frame.stack.push(!a)?; @@ -139,7 +139,7 @@ impl VM { // BYTE operation pub fn op_byte(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::BYTE)?; + current_call_frame.increase_consumed_gas(gas_cost::BYTE)?; let op1 = current_call_frame.stack.pop()?; let op2 = current_call_frame.stack.pop()?; let byte_index = match op1.try_into() { @@ -173,7 +173,7 @@ impl VM { // SHL operation (shift left) pub fn op_shl(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SHL)?; + current_call_frame.increase_consumed_gas(gas_cost::SHL)?; let shift = current_call_frame.stack.pop()?; let value = current_call_frame.stack.pop()?; @@ -190,7 +190,7 @@ impl VM { // SHR operation (shift right) pub fn op_shr(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SHR)?; + current_call_frame.increase_consumed_gas(gas_cost::SHR)?; let shift = current_call_frame.stack.pop()?; let value = current_call_frame.stack.pop()?; @@ -207,7 +207,7 @@ impl VM { // SAR operation (arithmetic shift right) pub fn op_sar(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SAR)?; + current_call_frame.increase_consumed_gas(gas_cost::SAR)?; let shift = current_call_frame.stack.pop()?; let value = current_call_frame.stack.pop()?; let res = if shift < U256::from(256) { diff --git a/crates/vm/levm/src/opcode_handlers/block.rs b/crates/vm/levm/src/opcode_handlers/block.rs index 3f131857e6..6638d33767 100644 --- a/crates/vm/levm/src/opcode_handlers/block.rs +++ b/crates/vm/levm/src/opcode_handlers/block.rs @@ -20,7 +20,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::BLOCKHASH)?; + current_call_frame.increase_consumed_gas(gas_cost::BLOCKHASH)?; let block_number = current_call_frame.stack.pop()?; @@ -56,7 +56,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::COINBASE)?; + current_call_frame.increase_consumed_gas(gas_cost::COINBASE)?; current_call_frame .stack @@ -70,7 +70,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::TIMESTAMP)?; + current_call_frame.increase_consumed_gas(gas_cost::TIMESTAMP)?; current_call_frame.stack.push(self.env.timestamp)?; @@ -82,7 +82,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::NUMBER)?; + current_call_frame.increase_consumed_gas(gas_cost::NUMBER)?; current_call_frame.stack.push(self.env.block_number)?; @@ -94,7 +94,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::PREVRANDAO)?; + current_call_frame.increase_consumed_gas(gas_cost::PREVRANDAO)?; let randao = self.env.prev_randao.unwrap_or_default(); // Assuming block_env has been integrated current_call_frame @@ -109,7 +109,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::GASLIMIT)?; + current_call_frame.increase_consumed_gas(gas_cost::GASLIMIT)?; current_call_frame .stack @@ -123,7 +123,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::CHAINID)?; + current_call_frame.increase_consumed_gas(gas_cost::CHAINID)?; current_call_frame.stack.push(self.env.chain_id)?; @@ -135,7 +135,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SELFBALANCE)?; + current_call_frame.increase_consumed_gas(gas_cost::SELFBALANCE)?; let balance = get_account(&mut self.cache, &self.db, current_call_frame.to) .info @@ -150,7 +150,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::BASEFEE)?; + current_call_frame.increase_consumed_gas(gas_cost::BASEFEE)?; current_call_frame.stack.push(self.env.base_fee_per_gas)?; @@ -168,7 +168,7 @@ impl VM { return Err(VMError::InvalidOpcode); } - self.increase_consumed_gas(current_call_frame, gas_cost::BLOBHASH)?; + current_call_frame.increase_consumed_gas(gas_cost::BLOBHASH)?; let index = current_call_frame.stack.pop()?; @@ -214,7 +214,7 @@ impl VM { if self.env.fork < Fork::Cancun { return Err(VMError::InvalidOpcode); } - self.increase_consumed_gas(current_call_frame, gas_cost::BLOBBASEFEE)?; + current_call_frame.increase_consumed_gas(gas_cost::BLOBBASEFEE)?; let blob_base_fee = self.get_blob_gasprice()?; diff --git a/crates/vm/levm/src/opcode_handlers/dup.rs b/crates/vm/levm/src/opcode_handlers/dup.rs index 5b8fdf9286..beaeec0d60 100644 --- a/crates/vm/levm/src/opcode_handlers/dup.rs +++ b/crates/vm/levm/src/opcode_handlers/dup.rs @@ -16,7 +16,7 @@ impl VM { depth: usize, ) -> Result { // Increase the consumed gas - self.increase_consumed_gas(current_call_frame, gas_cost::DUPN)?; + current_call_frame.increase_consumed_gas(gas_cost::DUPN)?; // Ensure the stack has enough elements to duplicate if current_call_frame.stack.len() < depth { diff --git a/crates/vm/levm/src/opcode_handlers/environment.rs b/crates/vm/levm/src/opcode_handlers/environment.rs index a1fcb887f9..2b713fd5aa 100644 --- a/crates/vm/levm/src/opcode_handlers/environment.rs +++ b/crates/vm/levm/src/opcode_handlers/environment.rs @@ -19,7 +19,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::ADDRESS)?; + current_call_frame.increase_consumed_gas(gas_cost::ADDRESS)?; let addr = current_call_frame.to; // The recipient of the current call. @@ -39,7 +39,7 @@ impl VM { let (account_info, address_was_cold) = self.access_account(address); - self.increase_consumed_gas(current_call_frame, gas_cost::balance(address_was_cold)?)?; + current_call_frame.increase_consumed_gas(gas_cost::balance(address_was_cold)?)?; current_call_frame.stack.push(account_info.balance)?; @@ -51,7 +51,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::ORIGIN)?; + current_call_frame.increase_consumed_gas(gas_cost::ORIGIN)?; let origin = self.env.origin; current_call_frame @@ -66,7 +66,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::CALLER)?; + current_call_frame.increase_consumed_gas(gas_cost::CALLER)?; let caller = current_call_frame.msg_sender; current_call_frame @@ -81,7 +81,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::CALLVALUE)?; + current_call_frame.increase_consumed_gas(gas_cost::CALLVALUE)?; let callvalue = current_call_frame.msg_value; @@ -95,7 +95,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::CALLDATALOAD)?; + current_call_frame.increase_consumed_gas(gas_cost::CALLDATALOAD)?; let calldata_size: U256 = current_call_frame.calldata.len().into(); @@ -136,7 +136,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::CALLDATASIZE)?; + current_call_frame.increase_consumed_gas(gas_cost::CALLDATASIZE)?; current_call_frame .stack @@ -160,10 +160,11 @@ impl VM { let new_memory_size = calculate_memory_size(dest_offset, size)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::calldatacopy(new_memory_size, current_call_frame.memory.len(), size)?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::calldatacopy( + new_memory_size, + current_call_frame.memory.len(), + size, + )?)?; if size == 0 { return Ok(OpcodeResult::Continue { pc_increment: 1 }); @@ -201,7 +202,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::CODESIZE)?; + current_call_frame.increase_consumed_gas(gas_cost::CODESIZE)?; current_call_frame .stack @@ -227,10 +228,11 @@ impl VM { let new_memory_size = calculate_memory_size(destination_offset, size)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::codecopy(new_memory_size, current_call_frame.memory.len(), size)?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::codecopy( + new_memory_size, + current_call_frame.memory.len(), + size, + )?)?; if size == 0 { return Ok(OpcodeResult::Continue { pc_increment: 1 }); @@ -265,7 +267,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::GASPRICE)?; + current_call_frame.increase_consumed_gas(gas_cost::GASPRICE)?; current_call_frame.stack.push(self.env.gas_price)?; @@ -284,7 +286,7 @@ impl VM { // https://eips.ethereum.org/EIPS/eip-7702#delegation-designation let is_delegation = has_delegation(&account_info)?; - self.increase_consumed_gas(current_call_frame, gas_cost::extcodesize(address_was_cold)?)?; + current_call_frame.increase_consumed_gas(gas_cost::extcodesize(address_was_cold)?)?; current_call_frame.stack.push(if is_delegation { SET_CODE_DELEGATION_BYTES[..2].len().into() @@ -316,15 +318,12 @@ impl VM { // https://eips.ethereum.org/EIPS/eip-7702#delegation-designation let is_delegation = has_delegation(&account_info)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::extcodecopy( - size, - new_memory_size, - current_call_frame.memory.len(), - address_was_cold, - )?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::extcodecopy( + size, + new_memory_size, + current_call_frame.memory.len(), + address_was_cold, + )?)?; if size == 0 { return Ok(OpcodeResult::Continue { pc_increment: 1 }); @@ -358,7 +357,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::RETURNDATASIZE)?; + current_call_frame.increase_consumed_gas(gas_cost::RETURNDATASIZE)?; current_call_frame .stack @@ -386,10 +385,11 @@ impl VM { let new_memory_size = calculate_memory_size(dest_offset, size)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::returndatacopy(new_memory_size, current_call_frame.memory.len(), size)?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::returndatacopy( + new_memory_size, + current_call_frame.memory.len(), + size, + )?)?; if size == 0 && returndata_offset == 0 { return Ok(OpcodeResult::Continue { pc_increment: 1 }); @@ -437,7 +437,7 @@ impl VM { // https://eips.ethereum.org/EIPS/eip-7702#delegation-designation let is_delegation = has_delegation(&account_info)?; - self.increase_consumed_gas(current_call_frame, gas_cost::extcodehash(address_was_cold)?)?; + current_call_frame.increase_consumed_gas(gas_cost::extcodehash(address_was_cold)?)?; if is_delegation { let hash = diff --git a/crates/vm/levm/src/opcode_handlers/exchange.rs b/crates/vm/levm/src/opcode_handlers/exchange.rs index db2c3fd014..6e0185c510 100644 --- a/crates/vm/levm/src/opcode_handlers/exchange.rs +++ b/crates/vm/levm/src/opcode_handlers/exchange.rs @@ -15,7 +15,7 @@ impl VM { current_call_frame: &mut CallFrame, depth: usize, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::SWAPN)?; + current_call_frame.increase_consumed_gas(gas_cost::SWAPN)?; let stack_top_index = current_call_frame .stack diff --git a/crates/vm/levm/src/opcode_handlers/keccak.rs b/crates/vm/levm/src/opcode_handlers/keccak.rs index 8d6dbe98ae..1b43b63452 100644 --- a/crates/vm/levm/src/opcode_handlers/keccak.rs +++ b/crates/vm/levm/src/opcode_handlers/keccak.rs @@ -25,10 +25,11 @@ impl VM { let new_memory_size = calculate_memory_size(offset, size)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::keccak256(new_memory_size, current_call_frame.memory.len(), size)?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::keccak256( + new_memory_size, + current_call_frame.memory.len(), + size, + )?)?; let mut hasher = Keccak256::new(); hasher.update(memory::load_range( diff --git a/crates/vm/levm/src/opcode_handlers/logging.rs b/crates/vm/levm/src/opcode_handlers/logging.rs index 1a026f8d2a..24f1bbc4ea 100644 --- a/crates/vm/levm/src/opcode_handlers/logging.rs +++ b/crates/vm/levm/src/opcode_handlers/logging.rs @@ -36,15 +36,12 @@ impl VM { let new_memory_size = calculate_memory_size(offset, size)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::log( - new_memory_size, - current_call_frame.memory.len(), - size, - number_of_topics, - )?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::log( + new_memory_size, + current_call_frame.memory.len(), + size, + number_of_topics, + )?)?; let log = Log { address: current_call_frame.to, diff --git a/crates/vm/levm/src/opcode_handlers/push.rs b/crates/vm/levm/src/opcode_handlers/push.rs index f7442d4e0c..7a66a39110 100644 --- a/crates/vm/levm/src/opcode_handlers/push.rs +++ b/crates/vm/levm/src/opcode_handlers/push.rs @@ -17,7 +17,7 @@ impl VM { current_call_frame: &mut CallFrame, n_bytes: usize, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::PUSHN)?; + current_call_frame.increase_consumed_gas(gas_cost::PUSHN)?; let read_n_bytes = read_bytcode_slice(current_call_frame, n_bytes)?; let value_to_push = bytes_to_word(read_n_bytes, n_bytes)?; @@ -44,7 +44,7 @@ impl VM { return Err(VMError::InvalidOpcode); } - self.increase_consumed_gas(current_call_frame, gas_cost::PUSH0)?; + current_call_frame.increase_consumed_gas(gas_cost::PUSH0)?; current_call_frame.stack.push(U256::zero())?; diff --git a/crates/vm/levm/src/opcode_handlers/stack_memory_storage_flow.rs b/crates/vm/levm/src/opcode_handlers/stack_memory_storage_flow.rs index 5ac395ae8d..2c76c1edfa 100644 --- a/crates/vm/levm/src/opcode_handlers/stack_memory_storage_flow.rs +++ b/crates/vm/levm/src/opcode_handlers/stack_memory_storage_flow.rs @@ -14,7 +14,7 @@ use ethrex_core::{types::Fork, H256, U256}; impl VM { // POP operation pub fn op_pop(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::POP)?; + current_call_frame.increase_consumed_gas(gas_cost::POP)?; current_call_frame.stack.pop()?; Ok(OpcodeResult::Continue { pc_increment: 1 }) } @@ -29,7 +29,7 @@ impl VM { return Err(VMError::InvalidOpcode); } - self.increase_consumed_gas(current_call_frame, gas_cost::TLOAD)?; + current_call_frame.increase_consumed_gas(gas_cost::TLOAD)?; let key = current_call_frame.stack.pop()?; let value = self @@ -53,7 +53,7 @@ impl VM { return Err(VMError::InvalidOpcode); } - self.increase_consumed_gas(current_call_frame, gas_cost::TSTORE)?; + current_call_frame.increase_consumed_gas(gas_cost::TSTORE)?; if current_call_frame.is_static { return Err(VMError::OpcodeNotAllowedInStaticContext); @@ -77,10 +77,10 @@ impl VM { let new_memory_size = calculate_memory_size(offset, WORD_SIZE_IN_BYTES_USIZE)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::mload(new_memory_size, current_call_frame.memory.len())?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::mload( + new_memory_size, + current_call_frame.memory.len(), + )?)?; current_call_frame .stack @@ -98,10 +98,10 @@ impl VM { let new_memory_size = calculate_memory_size(offset, WORD_SIZE_IN_BYTES_USIZE)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::mstore(new_memory_size, current_call_frame.memory.len())?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::mstore( + new_memory_size, + current_call_frame.memory.len(), + )?)?; let value = current_call_frame.stack.pop()?; @@ -124,10 +124,10 @@ impl VM { let new_memory_size = calculate_memory_size(offset, 1)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::mstore8(new_memory_size, current_call_frame.memory.len())?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::mstore8( + new_memory_size, + current_call_frame.memory.len(), + )?)?; let value = current_call_frame.stack.pop()?; @@ -153,7 +153,7 @@ impl VM { let (storage_slot, storage_slot_was_cold) = self.access_storage_slot(address, storage_slot_key)?; - self.increase_consumed_gas(current_call_frame, gas_cost::sload(storage_slot_was_cold)?)?; + current_call_frame.increase_consumed_gas(gas_cost::sload(storage_slot_was_cold)?)?; current_call_frame.stack.push(storage_slot.current_value)?; Ok(OpcodeResult::Continue { pc_increment: 1 }) @@ -222,10 +222,11 @@ impl VM { self.env.refunded_gas = gas_refunds; - self.increase_consumed_gas( - current_call_frame, - gas_cost::sstore(&storage_slot, new_storage_slot_value, storage_slot_was_cold)?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::sstore( + &storage_slot, + new_storage_slot_value, + storage_slot_was_cold, + )?)?; self.update_account_storage(current_call_frame.to, key, new_storage_slot_value)?; Ok(OpcodeResult::Continue { pc_increment: 1 }) @@ -236,7 +237,7 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::MSIZE)?; + current_call_frame.increase_consumed_gas(gas_cost::MSIZE)?; current_call_frame .stack .push(current_call_frame.memory.len().into())?; @@ -245,7 +246,7 @@ impl VM { // GAS operation pub fn op_gas(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::GAS)?; + current_call_frame.increase_consumed_gas(gas_cost::GAS)?; let remaining_gas = current_call_frame .gas_limit @@ -279,14 +280,11 @@ impl VM { let new_memory_size_for_src = calculate_memory_size(src_offset, size)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::mcopy( - new_memory_size_for_dest.max(new_memory_size_for_src), - current_call_frame.memory.len(), - size, - )?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::mcopy( + new_memory_size_for_dest.max(new_memory_size_for_src), + current_call_frame.memory.len(), + size, + )?)?; memory::try_copy_within( &mut current_call_frame.memory, @@ -300,7 +298,7 @@ impl VM { // JUMP operation pub fn op_jump(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::JUMP)?; + current_call_frame.increase_consumed_gas(gas_cost::JUMP)?; let jump_address = current_call_frame.stack.pop()?; Self::jump(current_call_frame, jump_address)?; @@ -343,7 +341,7 @@ impl VM { let jump_address = current_call_frame.stack.pop()?; let condition = current_call_frame.stack.pop()?; - self.increase_consumed_gas(current_call_frame, gas_cost::JUMPI)?; + current_call_frame.increase_consumed_gas(gas_cost::JUMPI)?; let pc_increment = if !condition.is_zero() { // Move the PC but don't increment it afterwards @@ -360,13 +358,13 @@ impl VM { &mut self, current_call_frame: &mut CallFrame, ) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::JUMPDEST)?; + current_call_frame.increase_consumed_gas(gas_cost::JUMPDEST)?; Ok(OpcodeResult::Continue { pc_increment: 1 }) } // PC operation pub fn op_pc(&mut self, current_call_frame: &mut CallFrame) -> Result { - self.increase_consumed_gas(current_call_frame, gas_cost::PC)?; + current_call_frame.increase_consumed_gas(gas_cost::PC)?; current_call_frame .stack diff --git a/crates/vm/levm/src/opcode_handlers/system.rs b/crates/vm/levm/src/opcode_handlers/system.rs index cdba7c5ad9..20a4127d1f 100644 --- a/crates/vm/levm/src/opcode_handlers/system.rs +++ b/crates/vm/levm/src/opcode_handlers/system.rs @@ -74,8 +74,8 @@ impl VM { self.env.fork, )?; - self.increase_consumed_gas(current_call_frame, cost)?; - self.increase_consumed_gas(current_call_frame, eip7702_gas_consumed)?; + current_call_frame.increase_consumed_gas(cost)?; + current_call_frame.increase_consumed_gas(eip7702_gas_consumed)?; // OPERATION let msg_sender = current_call_frame.to; // The new sender will be the current contract. @@ -155,8 +155,8 @@ impl VM { gas_left, )?; - self.increase_consumed_gas(current_call_frame, cost)?; - self.increase_consumed_gas(current_call_frame, eip7702_gas_consumed)?; + current_call_frame.increase_consumed_gas(cost)?; + current_call_frame.increase_consumed_gas(eip7702_gas_consumed)?; // Sender and recipient are the same in this case. But the code executed is from another account. let msg_sender = current_call_frame.to; @@ -200,10 +200,8 @@ impl VM { let new_memory_size = calculate_memory_size(offset, size)?; let current_memory_size = current_call_frame.memory.len(); - self.increase_consumed_gas( - current_call_frame, - gas_cost::exit_opcode(new_memory_size, current_memory_size)?, - )?; + current_call_frame + .increase_consumed_gas(gas_cost::exit_opcode(new_memory_size, current_memory_size)?)?; current_call_frame.output = memory::load_range(&mut current_call_frame.memory, offset, size)? @@ -265,8 +263,8 @@ impl VM { gas_left, )?; - self.increase_consumed_gas(current_call_frame, cost)?; - self.increase_consumed_gas(current_call_frame, eip7702_gas_consumed)?; + current_call_frame.increase_consumed_gas(cost)?; + current_call_frame.increase_consumed_gas(eip7702_gas_consumed)?; // OPERATION let msg_sender = current_call_frame.msg_sender; @@ -344,8 +342,8 @@ impl VM { gas_left, )?; - self.increase_consumed_gas(current_call_frame, cost)?; - self.increase_consumed_gas(current_call_frame, eip7702_gas_consumed)?; + current_call_frame.increase_consumed_gas(cost)?; + current_call_frame.increase_consumed_gas(eip7702_gas_consumed)?; // OPERATION let value = U256::zero(); @@ -385,15 +383,12 @@ impl VM { let new_size = calculate_memory_size(code_offset_in_memory, code_size_in_memory)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::create( - new_size, - current_call_frame.memory.len(), - code_size_in_memory, - self.env.fork, - )?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::create( + new_size, + current_call_frame.memory.len(), + code_size_in_memory, + self.env.fork, + )?)?; self.generic_create( value_in_wei_to_send, @@ -420,15 +415,12 @@ impl VM { let new_size = calculate_memory_size(code_offset_in_memory, code_size_in_memory)?; - self.increase_consumed_gas( - current_call_frame, - gas_cost::create_2( - new_size, - current_call_frame.memory.len(), - code_size_in_memory, - self.env.fork, - )?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::create_2( + new_size, + current_call_frame.memory.len(), + code_size_in_memory, + self.env.fork, + )?)?; self.generic_create( value_in_wei_to_send, @@ -460,10 +452,8 @@ impl VM { let new_memory_size = calculate_memory_size(offset, size)?; let current_memory_size = current_call_frame.memory.len(); - self.increase_consumed_gas( - current_call_frame, - gas_cost::exit_opcode(new_memory_size, current_memory_size)?, - )?; + current_call_frame + .increase_consumed_gas(gas_cost::exit_opcode(new_memory_size, current_memory_size)?)?; current_call_frame.output = memory::load_range(&mut current_call_frame.memory, offset, size)? @@ -506,14 +496,11 @@ impl VM { self.access_account(current_call_frame.to); let balance_to_transfer = current_account_info.balance; - self.increase_consumed_gas( - current_call_frame, - gas_cost::selfdestruct( - target_account_is_cold, - target_account_info.is_empty(), - balance_to_transfer, - )?, - )?; + current_call_frame.increase_consumed_gas(gas_cost::selfdestruct( + target_account_is_cold, + target_account_info.is_empty(), + balance_to_transfer, + )?)?; // [EIP-6780] - SELFDESTRUCT only in same transaction from CANCUN if self.env.fork >= Fork::Cancun { @@ -585,7 +572,7 @@ impl VM { // Reserve gas for subcall let max_message_call_gas = max_message_call_gas(current_call_frame)?; - self.increase_consumed_gas(current_call_frame, max_message_call_gas)?; + current_call_frame.increase_consumed_gas(max_message_call_gas)?; // Clear callframe subreturn data current_call_frame.sub_return_data = Bytes::new(); diff --git a/crates/vm/levm/src/vm.rs b/crates/vm/levm/src/vm.rs index 67363dcfc8..983b70df02 100644 --- a/crates/vm/levm/src/vm.rs +++ b/crates/vm/levm/src/vm.rs @@ -8,8 +8,7 @@ use crate::{ }, environment::Environment, errors::{ - InternalError, OpcodeResult, OutOfGasError, TransactionReport, TxResult, TxValidationError, - VMError, + InternalError, OpcodeResult, TransactionReport, TxResult, TxValidationError, VMError, }, gas_cost::{self, STANDARD_TOKEN_COST, TOTAL_COST_FLOOR_PER_TOKEN}, precompiles::{ @@ -285,7 +284,8 @@ impl VM { initial_call_frame, )?; - self.increase_consumed_gas(initial_call_frame, intrinsic_gas) + initial_call_frame + .increase_consumed_gas(intrinsic_gas) .map_err(|_| TxValidationError::IntrinsicGasTooLow)?; Ok(()) @@ -750,25 +750,6 @@ impl VM { )) } - /// Increases gas consumption of CallFrame and Environment, returning an error if the callframe gas limit is reached. - pub fn increase_consumed_gas( - &mut self, - current_call_frame: &mut CallFrame, - gas: u64, - ) -> Result<(), VMError> { - let potential_consumed_gas = current_call_frame - .gas_used - .checked_add(gas) - .ok_or(OutOfGasError::ConsumedGasOverflow)?; - if potential_consumed_gas > current_call_frame.gas_limit { - return Err(VMError::OutOfGas(OutOfGasError::MaxGasLimitExceeded)); - } - - current_call_frame.gas_used = potential_consumed_gas; - - Ok(()) - } - /// Accesses to an account's information. /// /// Accessed accounts are stored in the `touched_accounts` set.