Skip to content

Commit

Permalink
Remove finalize_execution from VM and move it to DefaultHook
Browse files Browse the repository at this point in the history
  • Loading branch information
lima-limon-inc committed Feb 6, 2025
1 parent 03d3436 commit 8511eed
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 114 deletions.
5 changes: 5 additions & 0 deletions crates/vm/levm/src/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,11 @@ impl Hook for DefaultHook {
Ok(())
}

/// ## Changes post execution
/// 1. Undo value transfer if the transaction was reverted
/// 2. Return unused gas + gas refunds to the sender.
/// 3. Pay coinbase fee
/// 4. Destruct addresses in selfdestruct set.
fn finalize_execution(
&self,
vm: &mut VM,
Expand Down
118 changes: 4 additions & 114 deletions crates/vm/levm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
call_frame::CallFrame,
constants::*,
db::{
cache::{self, remove_account},
cache::{self},
CacheDB, Database,
},
environment::Environment,
Expand Down Expand Up @@ -390,118 +390,6 @@ impl VM {
}
}

/// ## Changes post execution
/// 1. Undo value transfer if the transaction was reverted
/// 2. Return unused gas + gas refunds to the sender.
/// 3. Pay coinbase fee
/// 4. Destruct addresses in selfdestruct set.
fn finalize_execution(
&mut self,
initial_call_frame: &CallFrame,
report: &mut ExecutionReport,
) -> Result<(), VMError> {
// POST-EXECUTION Changes
let sender_address = initial_call_frame.msg_sender;
let receiver_address = initial_call_frame.to;

// 1. Undo value transfer if the transaction has reverted
if let TxResult::Revert(_) = report.result {
let existing_account = get_account(&mut self.cache, self.db.clone(), receiver_address); //TO Account

if has_delegation(&existing_account.info)? {
// This is the case where the "to" address and the
// "signer" address are the same. We are setting the code
// and sending some balance to the "to"/"signer"
// address.
// See https://eips.ethereum.org/EIPS/eip-7702#behavior (last sentence).

// If transaction execution results in failure (any
// exceptional condition or code reverting), setting
// delegation designations is not rolled back.
decrease_account_balance(
&mut self.cache,
self.db.clone(),
receiver_address,
initial_call_frame.msg_value,
)?;
} else {
// We remove the receiver account from the cache, like nothing changed in it's state.
remove_account(&mut self.cache, &receiver_address);
}

increase_account_balance(
&mut self.cache,
self.db.clone(),
sender_address,
initial_call_frame.msg_value,
)?;
}

// 2. Return unused gas + gas refunds to the sender.
let max_gas = self.env.gas_limit;
let consumed_gas = report.gas_used;
let refunded_gas = report.gas_refunded.min(
consumed_gas
.checked_div(5)
.ok_or(VMError::Internal(InternalError::UndefinedState(-1)))?,
);
// "The max refundable proportion of gas was reduced from one half to one fifth by EIP-3529 by Buterin and Swende [2021] in the London release"
report.gas_refunded = refunded_gas;

let gas_to_return = max_gas
.checked_sub(consumed_gas)
.and_then(|gas| gas.checked_add(refunded_gas))
.ok_or(VMError::Internal(InternalError::UndefinedState(0)))?;

let wei_return_amount = self
.env
.gas_price
.checked_mul(U256::from(gas_to_return))
.ok_or(VMError::Internal(InternalError::UndefinedState(1)))?;

increase_account_balance(
&mut self.cache,
self.db.clone(),
sender_address,
wei_return_amount,
)?;

// 3. Pay coinbase fee
let coinbase_address = self.env.coinbase;

let gas_to_pay_coinbase = consumed_gas
.checked_sub(refunded_gas)
.ok_or(VMError::Internal(InternalError::UndefinedState(2)))?;

let priority_fee_per_gas = self
.env
.gas_price
.checked_sub(self.env.base_fee_per_gas)
.ok_or(VMError::GasPriceIsLowerThanBaseFee)?;
let coinbase_fee = U256::from(gas_to_pay_coinbase)
.checked_mul(priority_fee_per_gas)
.ok_or(VMError::BalanceOverflow)?;

if coinbase_fee != U256::zero() {
increase_account_balance(
&mut self.cache,
self.db.clone(),
coinbase_address,
coinbase_fee,
)?;
};

// 4. Destruct addresses in selfdestruct set.
// In Cancun the only addresses destroyed are contracts created in this transaction
let selfdestruct_set = self.accrued_substate.selfdestruct_set.clone();
for address in selfdestruct_set {
let account_to_remove = get_account_mut_vm(&mut self.cache, self.db.clone(), address)?;
*account_to_remove = Account::default();
}

Ok(())
}

pub fn execute(&mut self) -> Result<ExecutionReport, VMError> {
let mut initial_call_frame = self
.call_frames
Expand Down Expand Up @@ -634,7 +522,9 @@ impl VM {
output: Bytes::new(),
};

self.finalize_execution(initial_call_frame, &mut report)?;
for hook in self.hooks.clone() {
hook.finalize_execution(self, initial_call_frame, &mut report)?;
}
report.new_state.clone_from(&self.cache);

Ok(report)
Expand Down

0 comments on commit 8511eed

Please sign in to comment.