Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: revm-interpreter created #320

Merged
merged 1 commit into from
Jan 8, 2023
Merged
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
464 changes: 319 additions & 145 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions bins/revm-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ edition = "2021"
bytes = "1.1"
hex = "0.4"
revm = { path = "../../crates/revm", version = "2.3.1" }
revm-interpreter = { path = "../../crates/interpreter", version = "3.0.0" }
microbench = "0.5"

[[bin]]
Expand Down
41 changes: 35 additions & 6 deletions bins/revm-test/src/bin/snailtracer.rs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bins/revme/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ revm = { path = "../../crates/revm", version = "2.3.1", default-features = false
"ethersdb",
"std",
"secp256k1",
"with-serde",
"serde",
] }
rlp = { version = "0.5", default-features = false }
ruint = { version = "1.7.0", features = ["rlp", "serde"] }
Expand Down
5 changes: 4 additions & 1 deletion bins/revme/src/statetest/models/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub enum SpecName {
MergeMeterInitCode,
#[serde(alias = "Merge+3855")]
MergePush0,
#[serde(other)]
Unknown,
}

impl SpecName {
Expand All @@ -49,7 +51,8 @@ impl SpecName {
Self::MergePush0 => SpecId::MERGE_EOF,
Self::ByzantiumToConstantinopleAt5 | Self::Constantinople => {
panic!("Overriden with PETERSBURG")
} //_ => panic!("Conversion failed"),
}
Self::Unknown => panic!("Unknown spec"),
}
}
}
7 changes: 3 additions & 4 deletions bins/revme/src/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ use std::{

use indicatif::ProgressBar;
use revm::{
bits::{B160, B256},
db::AccountState,
inspectors::CustomPrintTracer,
Bytecode, CreateScheme, Env, ExecutionResult, SpecId, TransactTo, U256,
db::AccountState, inspectors::CustomPrintTracer, Bytecode, CreateScheme, Env, ExecutionResult,
SpecId, TransactTo, B160, B256, U256,
};
use std::sync::atomic::Ordering;
use walkdir::{DirEntry, WalkDir};
Expand Down Expand Up @@ -189,6 +187,7 @@ pub fn execute_test_suit(path: &Path, elapsed: &Arc<Mutex<Duration>>) -> Result<
| SpecName::MergeEOF
| SpecName::MergeMeterInitCode
| SpecName::MergePush0
| SpecName::Unknown
) {
continue;
}
Expand Down
3 changes: 3 additions & 0 deletions crates/interpreter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# v3.0.0

Interpreter was extracted from main REVM crate. Before v3.0.0 version, this code was part of REVM.
71 changes: 71 additions & 0 deletions crates/interpreter/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
[package]
authors = ["Dragan Rakita <[email protected]>"]
description = "REVM Interpreter"
edition = "2021"
keywords = ["no_std", "ethereum", "vm", "evm", "revm", "interpreter"]
license = "MIT"
name = "revm-interpreter"
repository = "https://github.com/bluealloy/revm"
version = "3.0.0"
readme = "../../README.md"

[dependencies]
bytes = { version = "1.1", default-features = false }
hashbrown = { version = "0.13" }
hex = { version = "0.4", default-features = false }
rlp = { version = "0.5", default-features = false } # used for create2 address calculation
ruint = { version = "1.7.0", features = ["primitive-types", "rlp"] }


# bits B256 B160 crate
fixed-hash = { version = "0.8", default-features = false, features = [
"rustc-hex",
] }

#utility
hex-literal = "0.3"
derive_more = "0.99"
enumn = "0.1"

# sha3 keccak hasher
sha3 = { version = "0.10", default-features = false, features = [] }

# optional
serde = { version = "1.0", features = ["derive", "rc"], optional = true }
arbitrary = { version = "1.2", features = ["derive"], optional = true }

[dev-dependencies]
arbitrary = { version = "1.2", features = ["derive"] }
proptest = { version = "1.0" }
proptest-derive = "0.2.0"
ruint = { version = "1.7.0", features = [
"primitive-types",
"rlp",
"proptest",
"arbitrary",
] }

[features]
default = ["std"]
dev = [
"memory_limit",
"optional_balance_check",
"optional_block_gas_limit",
"optional_eip3607",
"optional_gas_refund",
]
memory_limit = []
no_gas_measuring = []
optional_balance_check = []
optional_block_gas_limit = []
optional_eip3607 = []
optional_gas_refund = []
std = ["bytes/std", "rlp/std", "hex/std"]
serde = [
"dep:serde",
"hex/serde",
"hashbrown/serde",
"ruint/serde",
"bytes/serde",
]
arbitrary = ["dep:arbitrary", "ruint/arbitrary", "ruint/proptest"]
File renamed without changes.
30 changes: 25 additions & 5 deletions crates/revm/src/bits.rs → crates/interpreter/src/bits.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
use derive_more::{AsRef, Deref};
use fixed_hash::{construct_fixed_hash, impl_fixed_hash_conversions};

#[cfg(test)]
use proptest_derive::Arbitrary as PropTestArbitrary;

#[cfg(any(test, feature = "arbitrary"))]
use arbitrary::Arbitrary;

construct_fixed_hash! {
/// revm 256 bits type.
#[cfg_attr(test, derive(PropTestArbitrary))]
#[cfg_attr(any(test, feature = "arbitrary"), derive(Arbitrary))]
#[derive(AsRef,Deref)]
pub struct B256(32);
}

construct_fixed_hash! {
/// revm 160 bits type.
#[cfg_attr(test, derive(PropTestArbitrary))]
#[cfg_attr(any(test, feature = "arbitrary"), derive(Arbitrary))]
#[derive(AsRef,Deref)]
pub struct B160(20);
}
Expand All @@ -25,7 +35,7 @@ impl From<u64> for B160 {

impl_fixed_hash_conversions!(B256, B160);

#[cfg(feature = "with-serde")]
#[cfg(feature = "serde")]
impl serde::Serialize for B256 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand All @@ -35,7 +45,7 @@ impl serde::Serialize for B256 {
serialize::serialize_raw(&mut slice, &self.0, serializer)
}
}
#[cfg(feature = "with-serde")]
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for B256 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand All @@ -46,7 +56,7 @@ impl<'de> serde::Deserialize<'de> for B256 {
Ok(B256(bytes))
}
}
#[cfg(feature = "with-serde")]
#[cfg(feature = "serde")]
impl serde::Serialize for B160 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
Expand All @@ -57,7 +67,7 @@ impl serde::Serialize for B160 {
}
}

#[cfg(feature = "with-serde")]
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for B160 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand All @@ -70,7 +80,7 @@ impl<'de> serde::Deserialize<'de> for B160 {
}

// code optained from: https://docs.rs/impl-serde/0.4.0/impl_serde/
#[cfg(feature = "with-serde")]
#[cfg(feature = "serde")]
mod serialize {

use alloc::{string::String, vec::Vec};
Expand Down Expand Up @@ -294,3 +304,13 @@ mod serialize {
deserializer.deserialize_str(Visitor { len })
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn arbitrary() {
proptest::proptest!(|(_v1: B160, _v2: B256)| {});
}
}
55 changes: 55 additions & 0 deletions crates/interpreter/src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use crate::{B160, B256, U256};
use sha3::{Digest, Keccak256};

#[inline(always)]
pub fn keccak256(input: &[u8]) -> B256 {
B256::from_slice(Keccak256::digest(input).as_slice())
}

/// Returns the address for the legacy `CREATE` scheme: [`CreateScheme::Create`]
pub fn create_address(caller: B160, nonce: u64) -> B160 {
let mut stream = rlp::RlpStream::new_list(2);
stream.append(&caller.0.as_ref());
stream.append(&nonce);
let out = keccak256(&stream.out());
B160(out[12..].try_into().unwrap())
}

/// Returns the address for the `CREATE2` scheme: [`CreateScheme::Create2`]
pub fn create2_address(caller: B160, code_hash: B256, salt: U256) -> B160 {
let mut hasher = Keccak256::new();
hasher.update([0xff]);
hasher.update(&caller[..]);
hasher.update(salt.to_be_bytes::<{ U256::BYTES }>());
hasher.update(&code_hash[..]);

B160(hasher.finalize().as_slice()[12..].try_into().unwrap())
}

/// Serde functions to serde as [bytes::Bytes] hex string
#[cfg(feature = "serde")]
pub(crate) mod serde_hex_bytes {
use serde::{Deserialize, Deserializer, Serializer};

pub fn serialize<S, T>(x: T, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: AsRef<[u8]>,
{
s.serialize_str(&format!("0x{}", hex::encode(x.as_ref())))
}

pub fn deserialize<'de, D>(d: D) -> Result<bytes::Bytes, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(d)?;
if let Some(value) = value.strip_prefix("0x") {
hex::decode(value)
} else {
hex::decode(&value)
}
.map(Into::into)
.map_err(|e| serde::de::Error::custom(e.to_string()))
}
}
File renamed without changes.
File renamed without changes.
44 changes: 44 additions & 0 deletions crates/interpreter/src/host.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
mod dummy_host;

use crate::{
Bytecode, Bytes, CallInputs, CreateInputs, Env, Gas, Interpreter, Return, SelfDestructResult,
B160, B256, U256,
};
pub use dummy_host::DummyHost;

/// EVM context host.
pub trait Host {
fn step(&mut self, interpreter: &mut Interpreter, is_static: bool) -> Return;
fn step_end(&mut self, interpreter: &mut Interpreter, is_static: bool, ret: Return) -> Return;

fn env(&mut self) -> &mut Env;

/// load account. Returns (is_cold,is_new_account)
fn load_account(&mut self, address: B160) -> Option<(bool, bool)>;
/// Get environmental block hash.
fn block_hash(&mut self, number: U256) -> Option<B256>;
/// Get balance of address and if account is cold loaded.
fn balance(&mut self, address: B160) -> Option<(U256, bool)>;
/// Get code of address and if account is cold loaded.
fn code(&mut self, address: B160) -> Option<(Bytecode, bool)>;
/// Get code hash of address and if account is cold loaded.
fn code_hash(&mut self, address: B160) -> Option<(B256, bool)>;
/// Get storage value of address at index and if account is cold loaded.
fn sload(&mut self, address: B160, index: U256) -> Option<(U256, bool)>;
/// Set storage value of account address at index.
/// Returns (original, present, new, sis_cold)
fn sstore(
&mut self,
address: B160,
index: U256,
value: U256,
) -> Option<(U256, U256, U256, bool)>;
/// Create a log owned by address with given topics and data.
fn log(&mut self, address: B160, topics: Vec<B256>, data: Bytes);
/// Mark an address to be deleted, with funds transferred to target.
fn selfdestruct(&mut self, address: B160, target: B160) -> Option<SelfDestructResult>;
/// Invoke a create operation.
fn create(&mut self, inputs: &mut CreateInputs) -> (Return, Option<B160>, Gas, Bytes);
/// Invoke a call operation.
fn call(&mut self, input: &mut CallInputs) -> (Return, Gas, Bytes);
}
Loading