Skip to content
Closed
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions crates/common/types/tx_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
pub type AccessList = Vec<AccessListItem>;
pub type AccessListItem = (Address, Vec<H256>);

/// Authorization list for EIP 7702.
pub type AuthorizationList = Vec<AuthorizationTuple>;
#[derive(Debug, Clone, Default, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
Expand Down
2 changes: 2 additions & 0 deletions crates/vm/levm/src/db/gen_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use super::error::DatabaseError;
use super::CacheDB;
use super::Database;

/// Database of accounts
/// Consists of a permanent store, and a more efficiently accessrd cache
#[derive(Clone)]
pub struct GeneralizedDatabase {
pub store: Arc<dyn Database>,
Expand Down
2 changes: 2 additions & 0 deletions crates/vm/levm/src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ pub struct Environment {
pub tx_nonce: u64,
pub block_gas_limit: u64,
pub transient_storage: TransientStorage,
/// Used to indicate an L2 transaction is privileged.
/// Always false when transaction is L1
pub is_privileged: bool,
}
10 changes: 3 additions & 7 deletions crates/vm/levm/src/opcode_handlers/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ impl<'a> VM<'a> {
self.backups.push(backup);

if is_precompile(&code_address, self.env.config.fork) {
let _report = self.run_execution()?;
let _report = self.vm_main_loop()?;
}
Ok(OpcodeResult::Continue { pc_increment: 0 })
}
Expand All @@ -901,11 +901,7 @@ impl<'a> VM<'a> {
&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);
}
) -> Result<(), VMError> {
let retdata = self
.return_data
.pop()
Expand All @@ -915,7 +911,7 @@ impl<'a> VM<'a> {
} else {
self.handle_return_call(call_frame, tx_report, retdata)?;
}
Ok(true)
Ok(())
}
pub fn handle_return_call(
&mut self,
Expand Down
41 changes: 33 additions & 8 deletions crates/vm/levm/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ use ethrex_common::{
Address, H256, U256,
};
use std::{
collections::{BTreeSet, HashMap, HashSet},
fmt::Debug,
sync::Arc,
collections::{BTreeSet, HashMap, HashSet}, fmt::Debug, sync::Arc
};

#[cfg(not(feature = "l2"))]
Expand All @@ -34,6 +32,12 @@ use crate::hooks::L2Hook;

pub type Storage = HashMap<U256, H256>;

/// Current substate of the transaction. Consists of the state elements to be modified.
/// Consists of:
/// - Accounts to delete due to self-destruct calls
/// - Touched accounts (accounts which were interacted with via a transactions)
/// - Accessed or modified storage slots (touched slots)
/// - Created accounts
#[derive(Debug, Clone, Default)]
pub struct Substate {
pub selfdestruct_set: HashSet<Address>,
Expand Down Expand Up @@ -241,6 +245,7 @@ impl<'a> VM<'a> {
vec![Arc::new(L2Hook { recipient })]
};

// Initialize substate
let mut substate = Substate {
selfdestruct_set: HashSet::new(),
touched_accounts: default_touched_accounts,
Expand Down Expand Up @@ -311,22 +316,29 @@ impl<'a> VM<'a> {
})
}

pub fn run_execution(&mut self) -> Result<ExecutionReport, VMError> {
pub fn vm_main_loop(&mut self) -> Result<ExecutionReport, VMError> {
let fork = self.env.config.fork;

if is_precompile(&self.current_call_frame()?.code_address, fork) {
// Get the current execution context
let mut current_call_frame = self
.call_frames
.pop()
.ok_or(VMError::Internal(InternalError::CouldNotPopCallframe))?;
// Get the result of the execution
let precompile_result = execute_precompile(&mut current_call_frame, fork);
let backup = self
.backups
.pop()
.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)?;
// If call frame is root, put the call frame back in the stack. Else handle return from current context
if current_call_frame.depth == 0 {
self.call_frames.push(current_call_frame.clone());
} else {
self.handle_return(&current_call_frame, &report)?;
}
self.current_call_frame_mut()?.increment_pc_by(1)?;
return Ok(report);
}
Expand All @@ -341,33 +353,46 @@ impl<'a> VM<'a> {
.current_call_frame_mut()?
.increment_pc_by(pc_increment)?,
Ok(OpcodeResult::Halt) => {
// Get the current execution context
let mut current_call_frame = self
.call_frames
.pop()
.ok_or(VMError::Internal(InternalError::CouldNotPopCallframe))?;
// Get the output and other details of the successfully executed transaction
let report = self.handle_opcode_result(&mut current_call_frame)?;
if self.handle_return(&current_call_frame, &report)? {
// If current call frame is root, push the call frame back into the stack and return.
// Else, handle return to prior context and increment the PC
if current_call_frame.depth != 0 {
self.handle_return(&current_call_frame, &report)?;
self.current_call_frame_mut()?.increment_pc_by(1)?;
} else {
self.call_frames.push(current_call_frame.clone());
return Ok(report);
}
}
Err(error) => {
// Get the current execution context
let mut current_call_frame = self
.call_frames
.pop()
.ok_or(VMError::Internal(InternalError::CouldNotPopCallframe))?;
// Get the details of why the transaction reverted
let report = self.handle_opcode_error(error, &mut current_call_frame)?;
if self.handle_return(&current_call_frame, &report)? {
// If current call frame is root, push the call frame back into the stack and return.
// Else, handle return to prior context and increment the PC
if current_call_frame.depth != 0 {
self.handle_return(&current_call_frame, &report)?;
self.current_call_frame_mut()?.increment_pc_by(1)?;
} else {
self.call_frames.push(current_call_frame.clone());
return Ok(report);
}
}
}
}
}

/// Restore state to that of the backups passed as parameter
pub fn restore_state(
&mut self,
backup: StateBackup,
Expand Down Expand Up @@ -437,7 +462,7 @@ impl<'a> VM<'a> {

self.backups.push(backup);

let mut report = self.run_execution()?;
let mut report = self.vm_main_loop()?;

self.finalize_execution(&mut report)?;
Ok(report)
Expand Down
Loading