Skip to content

Commit

Permalink
Merge branch 'main' of github.com:lambdaclass/lambda_ethereum_rust in…
Browse files Browse the repository at this point in the history
…to move_levm_ef_tests_to_cmd
  • Loading branch information
ilitteri committed Nov 14, 2024
2 parents 6d7b5d9 + 108163a commit ced0f88
Show file tree
Hide file tree
Showing 24 changed files with 1,340 additions and 639 deletions.
4 changes: 4 additions & 0 deletions cmd/ef_tests/levm/report.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// Note: I use this to do not affect the EF tests logic with this side effects
// The cost to add this would be to return a Result<(), InternalError> in EFTestsReport methods
#![allow(clippy::arithmetic_side_effects)]

use colored::Colorize;
use std::fmt;

Expand Down
5 changes: 5 additions & 0 deletions crates/vm/levm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,10 @@ as_conversions = "deny"
unwrap_used = "deny"
expect_used = "deny"

arithmetic_side_effects = "deny"
overflow_check_conditional = "warn"
manual_saturating_arithmetic = "warn"


[lib]
path = "./src/lib.rs"
16 changes: 12 additions & 4 deletions crates/vm/levm/src/account.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use crate::{
constants::EMPTY_CODE_HASH,
errors::{InternalError, VMError},
};
use bytes::Bytes;
use ethereum_rust_core::{H256, U256};
use keccak_hash::keccak;
use std::collections::HashMap;

use crate::{constants::EMPTY_CODE_HASH, errors::VMError};

#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct AccountInfo {
pub balance: U256,
Expand Down Expand Up @@ -88,7 +90,13 @@ impl Account {
self
}

pub fn increment_nonce(&mut self) {
self.info.nonce += 1;
// TODO: Replace nonce increments with this or cache's analog (currently does not have senders)
pub fn increment_nonce(&mut self) -> Result<(), VMError> {
self.info.nonce = self
.info
.nonce
.checked_add(1)
.ok_or(VMError::Internal(InternalError::NonceOverflowed))?;
Ok(())
}
}
25 changes: 17 additions & 8 deletions crates/vm/levm/src/call_frame.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use crate::{constants::STACK_LIMIT, errors::VMError, memory::Memory, opcodes::Opcode};
use crate::{
constants::STACK_LIMIT,
errors::{InternalError, VMError},
memory::Memory,
opcodes::Opcode,
};
use bytes::Bytes;
use ethereum_rust_core::{types::Log, Address, U256};
use std::collections::HashMap;
Expand Down Expand Up @@ -114,18 +119,22 @@ impl CallFrame {
}
}

pub fn next_opcode(&mut self) -> Option<Opcode> {
pub fn next_opcode(&mut self) -> Result<Option<Opcode>, VMError> {
let opcode = self.opcode_at(self.pc);
self.increment_pc();
opcode
self.increment_pc()?;
Ok(opcode)
}

pub fn increment_pc_by(&mut self, count: usize) {
self.pc += count;
pub fn increment_pc_by(&mut self, count: usize) -> Result<(), VMError> {
self.pc = self
.pc
.checked_add(count)
.ok_or(VMError::Internal(InternalError::PCOverflowed))?;
Ok(())
}

pub fn increment_pc(&mut self) {
self.increment_pc_by(1);
pub fn increment_pc(&mut self) -> Result<(), VMError> {
self.increment_pc_by(1)
}

pub fn pc(&self) -> usize {
Expand Down
106 changes: 2 additions & 104 deletions crates/vm/levm/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::errors::{InternalError, VMError};
use ethereum_rust_core::{H256, U256};

pub const SUCCESS_FOR_CALL: i32 = 1;
Expand All @@ -8,101 +7,6 @@ pub const SUCCESS_FOR_RETURN: i32 = 1;
pub const REVERT_FOR_CREATE: i32 = 0;
pub const WORD_SIZE: usize = 32;

/// Contains the gas costs of the EVM instructions (in wei)
pub mod gas_cost {
use ethereum_rust_core::U256;

pub const ADD: U256 = U256([3, 0, 0, 0]);
pub const MUL: U256 = U256([5, 0, 0, 0]);
pub const SUB: U256 = U256([3, 0, 0, 0]);
pub const DIV: U256 = U256([5, 0, 0, 0]);
pub const SDIV: U256 = U256([5, 0, 0, 0]);
pub const MOD: U256 = U256([5, 0, 0, 0]);
pub const SMOD: U256 = U256([5, 0, 0, 0]);
pub const ADDMOD: U256 = U256([8, 0, 0, 0]);
pub const MULMOD: U256 = U256([8, 0, 0, 0]);
pub const EXP_STATIC: U256 = U256([10, 0, 0, 0]);
pub const EXP_DYNAMIC_BASE: U256 = U256([50, 0, 0, 0]);
pub const SIGNEXTEND: U256 = U256([5, 0, 0, 0]);
pub const LT: U256 = U256([3, 0, 0, 0]);
pub const GT: U256 = U256([3, 0, 0, 0]);
pub const SLT: U256 = U256([3, 0, 0, 0]);
pub const SGT: U256 = U256([3, 0, 0, 0]);
pub const EQ: U256 = U256([3, 0, 0, 0]);
pub const ISZERO: U256 = U256([3, 0, 0, 0]);
pub const AND: U256 = U256([3, 0, 0, 0]);
pub const OR: U256 = U256([3, 0, 0, 0]);
pub const XOR: U256 = U256([3, 0, 0, 0]);
pub const NOT: U256 = U256([3, 0, 0, 0]);
pub const BYTE: U256 = U256([3, 0, 0, 0]);
pub const SHL: U256 = U256([3, 0, 0, 0]);
pub const SHR: U256 = U256([3, 0, 0, 0]);
pub const SAR: U256 = U256([3, 0, 0, 0]);
pub const KECCAK25_STATIC: U256 = U256([30, 0, 0, 0]);
pub const KECCAK25_DYNAMIC_BASE: U256 = U256([6, 0, 0, 0]);
pub const CALLDATALOAD: U256 = U256([3, 0, 0, 0]);
pub const CALLDATASIZE: U256 = U256([2, 0, 0, 0]);
pub const CALLDATACOPY_STATIC: U256 = U256([3, 0, 0, 0]);
pub const CALLDATACOPY_DYNAMIC_BASE: U256 = U256([3, 0, 0, 0]);
pub const RETURNDATASIZE: U256 = U256([2, 0, 0, 0]);
pub const RETURNDATACOPY_STATIC: U256 = U256([3, 0, 0, 0]);
pub const RETURNDATACOPY_DYNAMIC_BASE: U256 = U256([3, 0, 0, 0]);
pub const ADDRESS: U256 = U256([2, 0, 0, 0]);
pub const ORIGIN: U256 = U256([2, 0, 0, 0]);
pub const CALLER: U256 = U256([2, 0, 0, 0]);
pub const BLOCKHASH: U256 = U256([20, 0, 0, 0]);
pub const COINBASE: U256 = U256([2, 0, 0, 0]);
pub const TIMESTAMP: U256 = U256([2, 0, 0, 0]);
pub const NUMBER: U256 = U256([2, 0, 0, 0]);
pub const PREVRANDAO: U256 = U256([2, 0, 0, 0]);
pub const GASLIMIT: U256 = U256([2, 0, 0, 0]);
pub const CHAINID: U256 = U256([2, 0, 0, 0]);
pub const SELFBALANCE: U256 = U256([5, 0, 0, 0]);
pub const BASEFEE: U256 = U256([2, 0, 0, 0]);
pub const BLOBHASH: U256 = U256([3, 0, 0, 0]);
pub const BLOBBASEFEE: U256 = U256([2, 0, 0, 0]);
pub const POP: U256 = U256([2, 0, 0, 0]);
pub const MLOAD_STATIC: U256 = U256([3, 0, 0, 0]);
pub const MSTORE_STATIC: U256 = U256([3, 0, 0, 0]);
pub const MSTORE8_STATIC: U256 = U256([3, 0, 0, 0]);
pub const JUMP: U256 = U256([8, 0, 0, 0]);
pub const JUMPI: U256 = U256([10, 0, 0, 0]);
pub const PC: U256 = U256([2, 0, 0, 0]);
pub const MSIZE: U256 = U256([2, 0, 0, 0]);
pub const GAS: U256 = U256([2, 0, 0, 0]);
pub const JUMPDEST: U256 = U256([1, 0, 0, 0]);
pub const TLOAD: U256 = U256([100, 0, 0, 0]);
pub const TSTORE: U256 = U256([100, 0, 0, 0]);
pub const MCOPY_STATIC: U256 = U256([3, 0, 0, 0]);
pub const MCOPY_DYNAMIC_BASE: U256 = U256([3, 0, 0, 0]);
pub const PUSH0: U256 = U256([2, 0, 0, 0]);
pub const PUSHN: U256 = U256([3, 0, 0, 0]);
pub const DUPN: U256 = U256([3, 0, 0, 0]);
pub const SWAPN: U256 = U256([3, 0, 0, 0]);
pub const LOGN_STATIC: U256 = U256([375, 0, 0, 0]);
pub const LOGN_DYNAMIC_BASE: U256 = U256([375, 0, 0, 0]);
pub const LOGN_DYNAMIC_BYTE_BASE: U256 = U256([8, 0, 0, 0]);
pub const CALLVALUE: U256 = U256([2, 0, 0, 0]);
pub const CODESIZE: U256 = U256([2, 0, 0, 0]);
pub const CODECOPY_STATIC: U256 = U256([3, 0, 0, 0]);
pub const CODECOPY_DYNAMIC_BASE: U256 = U256([3, 0, 0, 0]);
pub const GASPRICE: U256 = U256([2, 0, 0, 0]);
pub const EXTCODECOPY_DYNAMIC_BASE: U256 = U256([3, 0, 0, 0]);
pub const SELFDESTRUCT_STATIC: U256 = U256([5000, 0, 0, 0]);
pub const SELFDESTRUCT_DYNAMIC: U256 = U256([25000, 0, 0, 0]);
pub const COLD_ADDRESS_ACCESS_COST: U256 = U256([2600, 0, 0, 0]);
}

// Costs in gas for call opcodes (in wei)
pub mod call_opcode {
use ethereum_rust_core::U256;

pub const WARM_ADDRESS_ACCESS_COST: U256 = U256([100, 0, 0, 0]);
pub const COLD_ADDRESS_ACCESS_COST: U256 = U256([2600, 0, 0, 0]);
pub const NON_ZERO_VALUE_COST: U256 = U256([9000, 0, 0, 0]);
pub const BASIC_FALLBACK_FUNCTION_STIPEND: U256 = U256([2300, 0, 0, 0]);
pub const VALUE_TO_EMPTY_ACCOUNT_COST: U256 = U256([25000, 0, 0, 0]);
}
pub const STACK_LIMIT: usize = 1024;

pub const GAS_REFUND_DENOMINATOR: u64 = 5;
Expand All @@ -122,14 +26,6 @@ pub const MAX_CREATE_CODE_SIZE: usize = 2 * MAX_CODE_SIZE;

pub const INVALID_CONTRACT_PREFIX: u8 = 0xef;

// Costs in gas for init word and init code (in wei)
pub const INIT_WORD_COST: u64 = 2;

pub fn init_code_cost(init_code_length: usize) -> Result<u64, VMError> {
let length_u64 = u64::try_from(init_code_length)
.map_err(|_| VMError::Internal(InternalError::ConversionError))?;
Ok(INIT_WORD_COST * (length_u64 + 31) / 32)
}
pub mod create_opcode {
use ethereum_rust_core::U256;

Expand All @@ -148,6 +44,8 @@ pub const BLOB_BASE_FEE_UPDATE_FRACTION: U256 = U256([3338477, 0, 0, 0]);

// Storage constants
pub const COLD_STORAGE_ACCESS_COST: U256 = U256([2100, 0, 0, 0]);
pub const WARM_ADDRESS_ACCESS_COST: U256 = U256([100, 0, 0, 0]);
pub const BALANCE_COLD_ADDRESS_ACCESS_COST: U256 = U256([2600, 0, 0, 0]);

// Block constants
pub const LAST_AVAILABLE_BLOCK_LIMIT: U256 = U256([256, 0, 0, 0]);
Expand Down
10 changes: 8 additions & 2 deletions crates/vm/levm/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,16 @@ impl Cache {
Ok(())
}

pub fn increment_account_nonce(&mut self, address: &Address) {
// TODO: Replace nonce increments with this (currently does not have senders)
pub fn increment_account_nonce(&mut self, address: &Address) -> Result<(), VMError> {
if let Some(account) = self.accounts.get_mut(address) {
account.info.nonce += 1;
account.info.nonce = account
.info
.nonce
.checked_add(1)
.ok_or(VMError::Internal(InternalError::NonceOverflowed))?;
}
Ok(())
}

pub fn is_account_cached(&self, address: &Address) -> bool {
Expand Down
Loading

0 comments on commit ced0f88

Please sign in to comment.