Skip to content
Draft
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
2 changes: 1 addition & 1 deletion crates/common/types/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct Account {
pub storage: BTreeMap<H256, U256>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Eq)]
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq)]
pub struct AccountInfo {
pub code_hash: H256,
pub balance: U256,
Expand Down
2 changes: 1 addition & 1 deletion crates/common/types/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ impl RLPDecode for Transaction {
}

/// The transaction's kind: call or create.
#[derive(Clone, Debug, PartialEq, Eq, Default, RSerialize, RDeserialize, Archive)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default, RSerialize, RDeserialize, Archive)]
pub enum TxKind {
Call(#[rkyv(with=crate::rkyv_utils::H160Wrapper)] Address),
#[default]
Expand Down
3 changes: 2 additions & 1 deletion crates/networking/rpc/eth/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
},
utils::RpcErr,
};
use bytes::Bytes;
use ethrex_blockchain::{Blockchain, vm::StoreVmDatabase};
use ethrex_common::{
H256, U256,
Expand Down Expand Up @@ -113,7 +114,7 @@ impl RpcHandler for CallRequest {
context.storage,
context.blockchain,
)?;
serde_json::to_value(format!("0x{:#x}", result.output()))
serde_json::to_value(format!("0x{:#x}", result.output().unwrap_or(&Bytes::new())))
.map_err(|error| RpcErr::Internal(error.to_string()))
}
}
Expand Down
6 changes: 3 additions & 3 deletions crates/networking/rpc/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ pub async fn start_api(
let service_context = RpcApiContext {
storage,
blockchain,
active_filters: active_filters.clone(),
active_filters: active_filters.clone(), // ok-clone: increasing arc reference count
syncer: Arc::new(syncer),
peer_handler,
node_data: NodeData {
Expand All @@ -235,11 +235,11 @@ pub async fn start_api(
// Periodically clean up the active filters for the filters endpoints.
tokio::task::spawn(async move {
let mut interval = tokio::time::interval(FILTER_DURATION);
let filters = active_filters.clone();
let filters = active_filters.clone(); // ok-clone: increasing arc reference count
loop {
interval.tick().await;
tracing::debug!("Running filter clean task");
filter::clean_outdated_filters(filters.clone(), FILTER_DURATION);
filter::clean_outdated_filters(filters.clone(), FILTER_DURATION); // ok-clone: increasing arc reference count
tracing::debug!("Filter clean task complete");
}
});
Expand Down
23 changes: 14 additions & 9 deletions crates/vm/backends/levm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use ethrex_levm::{
vm::VM,
};
use std::cmp::min;
use std::sync::Arc;

/// The struct implements the following functions:
/// [LEVM::execute_block]
Expand Down Expand Up @@ -56,9 +57,9 @@ impl LEVM {
cumulative_gas_used += report.gas_used;
let receipt = Receipt::new(
tx.tx_type(),
matches!(report.result.clone(), TxResult::Success),
matches!(report.result, TxResult::Success),
cumulative_gas_used,
report.logs.clone(),
report.logs,
);

receipts.push(receipt);
Expand Down Expand Up @@ -130,7 +131,7 @@ impl LEVM {
db: &mut GeneralizedDatabase,
vm_type: VMType,
) -> Result<ExecutionReport, EvmError> {
let env = Self::setup_env(tx, tx_sender, block_header, db)?;
let env = Arc::new(Self::setup_env(tx, tx_sender, block_header, db)?);
let mut vm = VM::new(env, db, tx, LevmCallTracer::disabled(), vm_type)?;

vm.execute().map_err(VMError::into)
Expand All @@ -155,6 +156,8 @@ impl LEVM {

adjust_disabled_base_fee(&mut env);

let env = Arc::new(env);

let mut vm = vm_from_generic(tx, env, db, vm_type)?;

vm.execute()
Expand Down Expand Up @@ -303,13 +306,15 @@ impl LEVM {

adjust_disabled_base_fee(&mut env);

let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type)?;
let env = Arc::new(env);

let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type)?; // ok-clone: increasing arc reference count

vm.stateless_execute()?;

// Execute the tx again, now with the created access list.
tx.access_list = vm.substate.make_access_list();
let mut vm = vm_from_generic(&tx, env.clone(), db, vm_type)?;
let mut vm = vm_from_generic(&tx, env, db, vm_type)?;

let report = vm.stateless_execute()?;

Expand Down Expand Up @@ -363,7 +368,7 @@ pub fn generic_system_contract_levm(
.current_accounts_state
.get(&block_header.coinbase)
.cloned();
let env = Environment {
let env = Arc::new(Environment {
origin: system_address,
// EIPs 2935, 4788, 7002 and 7251 dictate that the system calls have a gas limit of 30 million and they do not use intrinsic gas.
// So we add the base cost that will be taken in the execution.
Expand All @@ -379,7 +384,7 @@ pub fn generic_system_contract_levm(
block_gas_limit: i64::MAX as u64, // System calls, have no constraint on the block's gas limit.
config,
..Default::default()
};
});

let tx = &Transaction::EIP1559Transaction(EIP1559Transaction {
to: TxKind::Call(contract_address),
Expand Down Expand Up @@ -512,7 +517,7 @@ fn env_from_generic(

fn vm_from_generic<'a>(
tx: &GenericTransaction,
env: Environment,
env: Arc<Environment>,
db: &'a mut GeneralizedDatabase,
vm_type: VMType,
) -> Result<VM<'a>, VMError> {
Expand All @@ -538,7 +543,7 @@ fn vm_from_generic<'a>(
..Default::default()
}),
None => Transaction::EIP1559Transaction(EIP1559Transaction {
to: tx.to.clone(),
to: tx.to,
value: tx.value,
data: tx.input.clone(),
access_list: tx
Expand Down
6 changes: 4 additions & 2 deletions crates/vm/backends/levm/tracing.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::sync::Arc;

use ethrex_common::types::{Block, Transaction};
use ethrex_common::{tracing::CallTrace, types::BlockHeader};
use ethrex_levm::vm::VMType;
Expand Down Expand Up @@ -50,14 +52,14 @@ impl LEVM {
with_log: bool,
vm_type: VMType,
) -> Result<CallTrace, EvmError> {
let env = Self::setup_env(
let env = Arc::new(Self::setup_env(
tx,
tx.sender().map_err(|error| {
EvmError::Transaction(format!("Couldn't recover addresses with error: {error}"))
})?,
block_header,
db,
)?;
)?);
let mut vm = VM::new(
env,
db,
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/backends/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl Evm {
tx.tx_type(),
execution_report.is_success(),
block_header.gas_limit - *remaining_gas,
execution_report.logs.clone(),
execution_report.logs,
);

Ok((receipt, execution_report.gas_used))
Expand Down
15 changes: 7 additions & 8 deletions crates/vm/execution_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ impl ExecutionResult {
ExecutionResult::Halt { gas_used, .. } => *gas_used,
}
}
pub fn logs(&self) -> Vec<Log> {
pub fn logs(&self) -> Option<&Vec<Log>> {
match self {
ExecutionResult::Success { logs, .. } => logs.clone(),
_ => vec![],
ExecutionResult::Success { logs, .. } => Some(&logs),
_ => None,
}
}
pub fn gas_refunded(&self) -> u64 {
Expand All @@ -43,12 +43,11 @@ impl ExecutionResult {
_ => 0,
}
}

pub fn output(&self) -> Bytes {
pub fn output(&self) -> Option<&Bytes> {
match self {
ExecutionResult::Success { output, .. } => output.clone(),
ExecutionResult::Revert { output, .. } => output.clone(),
ExecutionResult::Halt { .. } => Bytes::new(),
ExecutionResult::Success { output, .. } => Some(&output),
ExecutionResult::Revert { output, .. } => Some(&output),
ExecutionResult::Halt { .. } => None,
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions crates/vm/levm/bench/revm_comparison/src/levm_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ pub fn run_with_levm(contract_code: &str, runs: u64, calldata: &str) {

// when using stateful execute() we have to use nonce when instantiating the vm. Otherwise use 0.
for _nonce in 0..runs - 1 {
let mut vm = init_vm(&mut db, 0, calldata.clone()).unwrap();
let mut vm = init_vm(&mut db, 0, calldata.clone()).unwrap(); // ok-clone: value needed later, used as part of bench runner
let tx_report = black_box(vm.stateless_execute().unwrap());
assert!(tx_report.is_success());
}
let mut vm = init_vm(&mut db, 0, calldata.clone()).unwrap();
let mut vm = init_vm(&mut db, 0, calldata).unwrap();
let tx_report = black_box(vm.stateless_execute().unwrap());

assert!(tx_report.is_success(), "{:?}", tx_report.result);
Expand All @@ -58,7 +58,7 @@ fn init_db(bytecode: Bytes) -> GeneralizedDatabase {
let cache = BTreeMap::from([
(
Address::from_low_u64_be(CONTRACT_ADDRESS),
Account::new(U256::MAX, bytecode.clone(), 0, BTreeMap::new()),
Account::new(U256::MAX, bytecode, 0, BTreeMap::new()),
),
(
Address::from_low_u64_be(SENDER_ADDRESS),
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/levm/bench/revm_comparison/src/revm_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::hint::black_box;
pub fn run_with_revm(contract_code: &str, runs: u64, calldata: &str) {
let rich_acc_address = address!("1000000000000000000000000000000000000000");
let bytes = hex::decode(contract_code).unwrap();
let raw_bytecode = Bytecode::new_raw(bytes.clone().into());
let raw_bytecode = Bytecode::new_raw(bytes.into());

let mut evm = Evm::builder()
.modify_tx_env(|tx| {
Expand Down
10 changes: 5 additions & 5 deletions crates/vm/levm/runner/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ fn main() {
mnemonics_to_bytecode(strings)
};

debug!("Final bytecode: 0x{}", hex::encode(bytecode.clone()));
debug!("Final bytecode: 0x{}", hex::encode(bytecode.clone())); // ok-clone: need to return value, used in test runner

bytecode
} else {
Expand All @@ -125,7 +125,7 @@ fn main() {

// Now we want to initialize the VM, so we set up the environment and database.
// Env
let env = Environment {
let env = Arc::new(Environment {
origin: runner_input.transaction.sender,
gas_limit: runner_input.transaction.gas_limit,
gas_price: runner_input.transaction.gas_price,
Expand All @@ -136,7 +136,7 @@ fn main() {
),
coinbase: COINBASE,
..Default::default()
};
});

// DB
let initial_state = setup_initial_state(&mut runner_input, bytecode);
Expand All @@ -148,7 +148,7 @@ fn main() {
let mut vm = VM::new(
env,
&mut db,
&Transaction::LegacyTransaction(LegacyTransaction::from(runner_input.transaction.clone())),
&Transaction::LegacyTransaction(LegacyTransaction::from(runner_input.transaction.clone())), // ok-clone: value needed later, used in test runner
LevmCallTracer::disabled(),
VMType::L1,
)
Expand Down Expand Up @@ -277,7 +277,7 @@ fn setup_initial_state(
let input_pre_state: BTreeMap<Address, Account> = runner_input
.pre
.iter()
.map(|(addr, acc)| (*addr, Account::from(acc.clone())))
.map(|(addr, acc)| (*addr, Account::from(acc.clone()))) // ok-clone: value needed later, used in test runner
.collect();
initial_state.extend(input_pre_state);
// Contract bytecode or initcode
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/levm/src/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl LevmAccount {
}
}

#[derive(Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum AccountStatus {
#[default]
Unmodified,
Expand Down
6 changes: 3 additions & 3 deletions crates/vm/levm/src/call_frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,9 @@ impl CallFrameBackup {
self.original_accounts_info
.entry(address)
.or_insert_with(|| LevmAccount {
info: account.info.clone(),
info: account.info,
storage: BTreeMap::new(),
status: account.status.clone(),
status: account.status,
});

Ok(())
Expand Down Expand Up @@ -425,7 +425,7 @@ impl<'a> VM<'a> {

/// Restores the cache state to the state before changes made during a callframe.
pub fn restore_cache_state(&mut self) -> Result<(), VMError> {
let callframe_backup = self.current_call_frame.call_frame_backup.clone();
let callframe_backup = std::mem::take(&mut self.current_call_frame.call_frame_backup);
restore_cache_state(self.db, callframe_backup)
}

Expand Down
6 changes: 3 additions & 3 deletions crates/vm/levm/src/db/gen_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl GeneralizedDatabase {
Entry::Vacant(entry) => {
let info = self.store.get_account_info(address)?;
let account = LevmAccount::from(info);
self.initial_accounts_state.insert(address, account.clone());
self.initial_accounts_state.insert(address, account.clone()); // ok-clone: we're caching the original state of the account
Ok(entry.insert(account))
}
}
Expand Down Expand Up @@ -176,7 +176,7 @@ impl GeneralizedDatabase {
let new_account_update = AccountUpdate {
address: *address,
removed: false,
info: Some(new_state_account.info.clone()),
info: Some(new_state_account.info),
code: Some(
self.codes
.get(&new_state_account.info.code_hash)
Expand Down Expand Up @@ -229,7 +229,7 @@ impl GeneralizedDatabase {
}

let info = if acc_info_updated {
Some(new_state_account.info.clone())
Some(new_state_account.info)
} else {
None
};
Expand Down
4 changes: 2 additions & 2 deletions crates/vm/levm/src/hooks/backup_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct BackupHook {
impl Hook for BackupHook {
fn prepare_execution(&mut self, vm: &mut crate::vm::VM<'_>) -> Result<(), VMError> {
// Here we need to backup the callframe for undoing transaction changes if we want to.
self.pre_execution_backup = vm.current_call_frame.call_frame_backup.clone();
self.pre_execution_backup = std::mem::take(&mut vm.current_call_frame.call_frame_backup);
Ok(())
}

Expand All @@ -25,7 +25,7 @@ impl Hook for BackupHook {
) -> Result<(), VMError> {
// We want to restore to the initial state, this includes saving the changes made by the prepare execution
// and the changes made by the execution itself.
let mut execution_backup = vm.current_call_frame.call_frame_backup.clone();
let mut execution_backup = std::mem::take(&mut vm.current_call_frame.call_frame_backup);
let pre_execution_backup = std::mem::take(&mut self.pre_execution_backup);
execution_backup.extend(pre_execution_backup);
vm.db.tx_backup = Some(execution_backup);
Expand Down
6 changes: 3 additions & 3 deletions crates/vm/levm/src/hooks/default_hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl Hook for DefaultHook {
/// See 'docs' for more information about validations.
fn prepare_execution(&mut self, vm: &mut VM<'_>) -> Result<(), VMError> {
let sender_address = vm.env.origin;
let sender_info = vm.db.get_account(sender_address)?.info.clone();
let sender_info = vm.db.get_account(sender_address)?.info;

if vm.env.config.fork >= Fork::Prague {
validate_min_gas_limit(vm)?;
Expand Down Expand Up @@ -243,15 +243,15 @@ pub fn delete_self_destruct_accounts(vm: &mut VM<'_>) -> Result<(), VMError> {

pub fn validate_min_gas_limit(vm: &mut VM<'_>) -> Result<(), VMError> {
// check for gas limit is grater or equal than the minimum required
let calldata = vm.current_call_frame.calldata.clone();
let calldata = &vm.current_call_frame.calldata;
let intrinsic_gas: u64 = vm.get_intrinsic_gas()?;

if vm.current_call_frame.gas_limit < intrinsic_gas {
return Err(TxValidationError::IntrinsicGasTooLow.into());
}

// calldata_cost = tokens_in_calldata * 4
let calldata_cost: u64 = gas_cost::tx_calldata(&calldata)?;
let calldata_cost: u64 = gas_cost::tx_calldata(calldata)?;

// same as calculated in gas_used()
let tokens_in_calldata: u64 = calldata_cost / STANDARD_TOKEN_COST;
Expand Down
Loading
Loading