Skip to content

Commit

Permalink
Merge branch 'master' into ahmad-cancun-eip-6780
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmadkaouk committed Jun 20, 2024
2 parents 2b6b4b6 + fda8a40 commit 924e068
Show file tree
Hide file tree
Showing 54 changed files with 878 additions and 394 deletions.
4 changes: 4 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[target.'cfg(all())']
rustflags = [
"-Aclippy::blocks_in_conditions",
]
4 changes: 3 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,6 @@ jobs:
jsontests/res/ethtests/GeneralStateTests/VMTests/vmBitwiseLogicOperation/ \
jsontests/res/ethtests/GeneralStateTests/VMTests/vmIOandFlowOperations/ \
jsontests/res/ethtests/GeneralStateTests/VMTests/vmLogTest/ \
jsontests/res/ethtests/GeneralStateTests/VMTests/vmTests/
jsontests/res/ethtests/GeneralStateTests/VMTests/vmTests/ \
jsontests/res/ethtests/GeneralStateTests/stEIP150singleCodeGasPrices/eip2929.json
27 changes: 1 addition & 26 deletions interpreter/src/error.rs → interpreter/src/error/exit.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,7 @@
use crate::Opcode;
use alloc::borrow::Cow;
use core::fmt;

/// Capture represents the result of execution.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Capture<E, T> {
/// The machine has exited. It cannot be executed again.
Exit(E),
/// The machine has trapped. It is waiting for external information, and can
/// be executed again.
Trap(T),
}

impl<E, T> Capture<E, T> {
pub fn exit(self) -> Option<E> {
match self {
Self::Exit(e) => Some(e),
Self::Trap(_) => None,
}
}

pub fn trap(self) -> Option<T> {
match self {
Self::Exit(_) => None,
Self::Trap(t) => Some(t),
}
}
}
use crate::opcode::Opcode;

/// Exit result.
pub type ExitResult = Result<ExitSucceed, ExitError>;
Expand Down
30 changes: 30 additions & 0 deletions interpreter/src/error/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
mod exit;
mod trap;

pub use self::{exit::*, trap::*};

/// Capture represents the result of execution.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Capture<E, T> {
/// The machine has exited. It cannot be executed again.
Exit(E),
/// The machine has trapped. It is waiting for external information, and can
/// be executed again.
Trap(T),
}

impl<E, T> Capture<E, T> {
pub fn exit(self) -> Option<E> {
match self {
Self::Exit(e) => Some(e),
Self::Trap(_) => None,
}
}

pub fn trap(self) -> Option<T> {
match self {
Self::Exit(_) => None,
Self::Trap(t) => Some(t),
}
}
}
153 changes: 80 additions & 73 deletions interpreter/src/trap.rs → interpreter/src/error/trap.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
//! Call and create trap handler.

use crate::utils::{h256_to_u256, u256_to_usize};
use crate::{
interpreter::Interpreter, Context, ExitError, ExitException, ExitResult, Machine, Memory,
RuntimeBackend, RuntimeState, Transfer,
};
use alloc::vec::Vec;
use core::cmp::{max, min};
use core::convert::Infallible;
use core::{
cmp::{max, min},
convert::Infallible,
};

use primitive_types::{H160, H256, U256};
use sha3::{Digest, Keccak256};

use crate::{
error::{ExitError, ExitException, ExitResult},
interpreter::Interpreter,
machine::{Machine, Memory},
runtime::{Context, RuntimeBackend, RuntimeState, Transfer},
utils::{h256_to_u256, u256_to_usize},
};

pub trait TrapConstruct<T> {
fn construct(v: T) -> Self;
}
Expand All @@ -21,72 +27,6 @@ pub trait TrapConsume<T> {
fn consume(self) -> Result<T, Self::Rest>;
}

/// Create scheme.
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum CreateScheme {
/// Legacy create scheme of `CREATE`.
Legacy {
/// Caller of the create.
caller: H160,
},
/// Create scheme of `CREATE2`.
Create2 {
/// Caller of the create.
caller: H160,
/// Code hash.
code_hash: H256,
/// Salt.
salt: H256,
},
}

impl CreateScheme {
pub fn address<H: RuntimeBackend>(&self, handler: &H) -> H160 {
match self {
Self::Create2 {
caller,
code_hash,
salt,
} => {
let mut hasher = Keccak256::new();
hasher.update([0xff]);
hasher.update(&caller[..]);
hasher.update(&salt[..]);
hasher.update(&code_hash[..]);
H256::from_slice(hasher.finalize().as_slice()).into()
}
Self::Legacy { caller } => {
let nonce = handler.nonce(*caller);
let mut stream = rlp::RlpStream::new_list(2);
stream.append(caller);
stream.append(&nonce);
H256::from_slice(Keccak256::digest(&stream.out()).as_slice()).into()
}
}
}

#[must_use]
pub const fn caller(&self) -> H160 {
match self {
Self::Create2 { caller, .. } => *caller,
Self::Legacy { caller } => *caller,
}
}
}

/// Call scheme.
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum CallScheme {
/// `CALL`
Call,
/// `CALLCODE`
CallCode,
/// `DELEGATECALL`
DelegateCall,
/// `STATICCALL`
StaticCall,
}

pub enum CallCreateTrap {
Create,
Create2,
Expand Down Expand Up @@ -161,6 +101,20 @@ impl CallCreateTrapData {
}
}

/// Call scheme.
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum CallScheme {
/// `CALL`
Call,
/// `CALLCODE`
CallCode,
/// `DELEGATECALL`
DelegateCall,
/// `STATICCALL`
StaticCall,
}

#[derive(Clone, Debug)]
pub struct CallTrapData {
pub target: H160,
pub transfer: Option<Transfer>,
Expand Down Expand Up @@ -376,6 +330,59 @@ impl CallTrapData {
}
}

/// Create scheme.
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub enum CreateScheme {
/// Legacy create scheme of `CREATE`.
Legacy {
/// Caller of the create call.
caller: H160,
},
/// Create scheme of `CREATE2`.
Create2 {
/// Caller of the create call.
caller: H160,
/// Code hash.
code_hash: H256,
/// Salt.
salt: H256,
},
}

impl CreateScheme {
pub fn address<H: RuntimeBackend>(&self, handler: &H) -> H160 {
match self {
Self::Create2 {
caller,
code_hash,
salt,
} => {
let mut hasher = Keccak256::new();
hasher.update([0xff]);
hasher.update(&caller[..]);
hasher.update(&salt[..]);
hasher.update(&code_hash[..]);
H256::from_slice(hasher.finalize().as_slice()).into()
}
Self::Legacy { caller } => {
let nonce = handler.nonce(*caller);
let mut stream = rlp::RlpStream::new_list(2);
stream.append(caller);
stream.append(&nonce);
H256::from_slice(Keccak256::digest(&stream.out()).as_slice()).into()
}
}
}

#[must_use]
pub const fn caller(&self) -> H160 {
match self {
Self::Create2 { caller, .. } => *caller,
Self::Legacy { caller } => *caller,
}
}
}

#[derive(Clone, Debug)]
pub struct CreateTrapData {
pub scheme: CreateScheme,
Expand Down
18 changes: 14 additions & 4 deletions interpreter/src/etable.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
use core::{
marker::PhantomData,
ops::{Deref, DerefMut},
};

use crate::{
eval::*, trap::CallCreateTrap, ExitResult, GasState, Machine, Opcode, RuntimeBackend,
RuntimeEnvironment, RuntimeState, TrapConstruct,
error::{CallCreateTrap, ExitResult, TrapConstruct},
eval::*,
machine::Machine,
opcode::Opcode,
runtime::{GasState, RuntimeBackend, RuntimeEnvironment, RuntimeState},
};
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};

pub trait EtableSet {
type State;
Expand Down Expand Up @@ -180,6 +186,7 @@ impl<S, H, Tr> Etable<S, H, Tr> {
table[Opcode::MSIZE.as_usize()] = eval_msize as _;

table[Opcode::JUMPDEST.as_usize()] = eval_jumpdest as _;
table[Opcode::MCOPY.as_usize()] = eval_mcopy as _;

table[Opcode::PUSH0.as_usize()] = eval_push0 as _;
table[Opcode::PUSH1.as_usize()] = eval_push1 as _;
Expand Down Expand Up @@ -298,6 +305,9 @@ where

table.0[Opcode::GAS.as_usize()] = eval_gas as _;

table.0[Opcode::TLOAD.as_usize()] = eval_tload as _;
table.0[Opcode::TSTORE.as_usize()] = eval_tstore as _;

table.0[Opcode::LOG0.as_usize()] = eval_log0 as _;
table.0[Opcode::LOG1.as_usize()] = eval_log1 as _;
table.0[Opcode::LOG2.as_usize()] = eval_log2 as _;
Expand Down
5 changes: 3 additions & 2 deletions interpreter/src/eval/arithmetic.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::utils::I256;
use core::convert::TryInto;
use core::ops::Rem;

use primitive_types::{U256, U512};

use crate::utils::I256;

#[inline]
pub fn div(op1: U256, op2: U256) -> U256 {
if op2 == U256::zero() {
Expand Down
3 changes: 2 additions & 1 deletion interpreter/src/eval/bitwise.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::utils::{Sign, I256};
use primitive_types::U256;

use crate::utils::{Sign, I256};

#[inline]
pub fn slt(op1: U256, op2: U256) -> U256 {
let op1: I256 = op1.into();
Expand Down
30 changes: 26 additions & 4 deletions interpreter/src/eval/misc.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use super::Control;
use crate::utils::u256_to_h256;
use crate::{ExitError, ExitException, ExitFatal, ExitSucceed, Machine};
use core::cmp::min;
use core::cmp::{max, min};

use primitive_types::{H256, U256};

use crate::{
error::{ExitError, ExitException, ExitFatal, ExitSucceed},
etable::Control,
machine::Machine,
utils::u256_to_h256,
};

#[inline]
pub fn codesize<S, Tr>(state: &mut Machine<S>) -> Control<Tr> {
let stack = &mut state.stack;
Expand Down Expand Up @@ -94,6 +99,23 @@ pub fn mload<S, Tr>(state: &mut Machine<S>) -> Control<Tr> {
Control::Continue
}

/// Support for EIP-5656: MCOPY instruction.
#[inline]
pub fn mcopy<S, Tr>(state: &mut Machine<S>) -> Control<Tr> {
pop_u256!(state, dst, src, len);
try_or_fail!(state.memory.resize_offset(max(dst, src), len));

if len.is_zero() {
return Control::Continue;
}

let dst = as_usize_or_fail!(dst);
let src = as_usize_or_fail!(src);
let len = as_usize_or_fail!(len);
state.memory.copy(dst, src, len);
Control::Continue
}

#[inline]
pub fn mstore<S, Tr>(state: &mut Machine<S>) -> Control<Tr> {
pop_u256!(state, index);
Expand Down
Loading

0 comments on commit 924e068

Please sign in to comment.