Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into agustin-mcopy-instr…
Browse files Browse the repository at this point in the history
…uction
  • Loading branch information
Agusrodri committed Jun 3, 2024
2 parents 3f15f92 + 699fd9a commit 64be3bf
Show file tree
Hide file tree
Showing 56 changed files with 669 additions and 1,064 deletions.
30 changes: 17 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
[workspace]
members = [
"interpreter",
"jsontests",
"precompile",
"tracer",
]
resolver = "2"

[workspace.package]
edition = "2021"
rust-version = "1.60.0"
license = "Apache-2.0"
authors = ["rust-evm Developers <[email protected]>"]
repository = "https://github.com/rust-ethereum/evm"
Expand All @@ -7,7 +18,8 @@ keywords = ["no_std", "ethereum", "evm"]
[package]
name = "evm"
version = "1.0.0-dev"
edition = "2021"
edition = { workspace = true }
rust-version = { workspace = true }
license = { workspace = true }
authors = { workspace = true }
repository = { workspace = true }
Expand All @@ -27,20 +39,12 @@ std = [
"sha3/std",
"evm-interpreter/std",
]
with-codec = [
scale = [
"primitive-types/codec",
"primitive-types/scale-info",
"evm-interpreter/with-codec",
"evm-interpreter/scale",
]
with-serde = [
serde = [
"primitive-types/impl-serde",
"evm-interpreter/with-serde",
]

[workspace]
members = [
"interpreter",
"jsontests",
"precompile",
"tracer",
"evm-interpreter/serde",
]
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ interpreter that can be easily customized.
## Status

The Rust EVM project has a long history dating back to the initial
implementation in 2017 (when it was called SputnikVM). It has went through
multiple rewrites over the years to accomodate for different requirements, when
we successfully tested one integrating Geth to sync the mainnet.
implementation in 2017 (when it was called SputnikVM). It has gone through
multiple rewrites over the years to accommodate for different requirements,
when we successfully tested one integrating Geth to sync the mainnet.

The current rewrite is used in production for the Frontier project (the
Ethereum-compatibility layer for Polkadot). However, we have not yet fully
Expand Down
14 changes: 8 additions & 6 deletions interpreter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
[package]
name = "evm-interpreter"
version = "1.0.0-dev"
edition = "2021"
edition = { workspace = true }
rust-version = { workspace = true }
license = { workspace = true }
authors = { workspace = true }
repository = { workspace = true }
keywords = { workspace = true }
description = "The interpreter part of Ethereum Virtual Machine"

[dependencies]
auto_impl = "1.2"
paste = "1.0"
primitive-types = { version = "0.12", default-features = false, features = ["rlp"] }
rlp = { version = "0.5", default-features = false }
scale-codec = { package = "parity-scale-codec", version = "3.2", default-features = false, features = ["derive", "full"], optional = true }
scale-info = { version = "2.3", default-features = false, features = ["derive"], optional = true }
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
sha3 = { version = "0.10", default-features = false }
auto_impl = "1.1"

[dev-dependencies]
hex = "0.4"
Expand All @@ -25,17 +27,17 @@ default = ["std"]
std = [
"primitive-types/std",
"rlp/std",
"serde/std",
"scale-codec/std",
"scale-info/std",
"serde/std",
"sha3/std",
]
with-codec = [
scale = [
"scale-codec",
"scale-info",
"primitive-types/impl-codec",
]
with-serde = [
"serde",
serde = [
"dep:serde",
"primitive-types/impl-serde",
]
95 changes: 33 additions & 62 deletions interpreter/src/error.rs → interpreter/src/error/exit.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,18 @@
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>;

/// Exit reason.
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "with-codec",
feature = "scale",
derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
)]
#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ExitError {
/// Machine returns a normal EVM error.
Exception(ExitException),
Expand All @@ -54,30 +30,25 @@ impl From<ExitError> for ExitResult {
}

#[cfg(feature = "std")]
impl std::error::Error for ExitError {
fn description(&self) -> &str {
impl std::error::Error for ExitError {}

impl fmt::Display for ExitError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Exception(_) => "EVM exit exception",
Self::Reverted => "EVM internal revert",
Self::Fatal(_) => "EVM fatal error",
Self::Exception(_) => f.write_str("EVM exit exception"),
Self::Reverted => f.write_str("EVM internal revert"),
Self::Fatal(_) => f.write_str("EVM fatal error"),
}
}
}

#[cfg(feature = "std")]
impl std::fmt::Display for ExitError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{self:?}")
}
}

/// Exit succeed reason.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "with-codec",
feature = "scale",
derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
)]
#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ExitSucceed {
/// Machine encountered an explicit stop.
Stopped,
Expand All @@ -96,67 +67,67 @@ impl From<ExitSucceed> for ExitResult {
/// Exit error reason.
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "with-codec",
feature = "scale",
derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
)]
#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ExitException {
/// Trying to pop from an empty stack.
#[cfg_attr(feature = "with-codec", codec(index = 0))]
#[cfg_attr(feature = "scale", codec(index = 0))]
StackUnderflow,
/// Trying to push into a stack over stack limit.
#[cfg_attr(feature = "with-codec", codec(index = 1))]
#[cfg_attr(feature = "scale", codec(index = 1))]
StackOverflow,
/// Jump destination is invalid.
#[cfg_attr(feature = "with-codec", codec(index = 2))]
#[cfg_attr(feature = "scale", codec(index = 2))]
InvalidJump,
/// An opcode accesses memory region, but the region is invalid.
#[cfg_attr(feature = "with-codec", codec(index = 3))]
#[cfg_attr(feature = "scale", codec(index = 3))]
InvalidRange,
/// Encountered the designated invalid opcode.
#[cfg_attr(feature = "with-codec", codec(index = 4))]
#[cfg_attr(feature = "scale", codec(index = 4))]
DesignatedInvalid,
/// Call stack is too deep (runtime).
#[cfg_attr(feature = "with-codec", codec(index = 5))]
#[cfg_attr(feature = "scale", codec(index = 5))]
CallTooDeep,
/// Create opcode encountered collision (runtime).
#[cfg_attr(feature = "with-codec", codec(index = 6))]
#[cfg_attr(feature = "scale", codec(index = 6))]
CreateCollision,
/// Create init code exceeds limit (runtime).
#[cfg_attr(feature = "with-codec", codec(index = 7))]
#[cfg_attr(feature = "scale", codec(index = 7))]
CreateContractLimit,

/// Invalid opcode during execution or starting byte is 0xef ([EIP-3541](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3541.md)).
#[cfg_attr(feature = "with-codec", codec(index = 15))]
#[cfg_attr(feature = "scale", codec(index = 15))]
InvalidOpcode(Opcode),

/// An opcode accesses external information, but the request is off offset
/// limit (runtime).
#[cfg_attr(feature = "with-codec", codec(index = 8))]
#[cfg_attr(feature = "scale", codec(index = 8))]
OutOfOffset,
/// Execution runs out of gas (runtime).
#[cfg_attr(feature = "with-codec", codec(index = 9))]
#[cfg_attr(feature = "scale", codec(index = 9))]
OutOfGas,
/// Not enough fund to start the execution (runtime).
#[cfg_attr(feature = "with-codec", codec(index = 10))]
#[cfg_attr(feature = "scale", codec(index = 10))]
OutOfFund,

/// PC underflowed (unused).
#[allow(clippy::upper_case_acronyms)]
#[cfg_attr(feature = "with-codec", codec(index = 11))]
#[cfg_attr(feature = "scale", codec(index = 11))]
PCUnderflow,

/// Attempt to create an empty account (runtime, unused).
#[cfg_attr(feature = "with-codec", codec(index = 12))]
#[cfg_attr(feature = "scale", codec(index = 12))]
CreateEmpty,

/// Nonce reached maximum value of 2^64-1
/// https://eips.ethereum.org/EIPS/eip-2681
#[cfg_attr(feature = "with-codec", codec(index = 14))]
#[cfg_attr(feature = "scale", codec(index = 14))]
MaxNonce,

/// Other normal errors.
#[cfg_attr(feature = "with-codec", codec(index = 13))]
#[cfg_attr(feature = "scale", codec(index = 13))]
Other(Cow<'static, str>),
}

Expand All @@ -175,10 +146,10 @@ impl From<ExitException> for ExitError {
/// Exit fatal reason.
#[derive(Clone, Debug, Eq, PartialEq)]
#[cfg_attr(
feature = "with-codec",
feature = "scale",
derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
)]
#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ExitFatal {
/// The operation is not supported.
NotSupported,
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),
}
}
}
Loading

0 comments on commit 64be3bf

Please sign in to comment.