Skip to content

Commit

Permalink
Merge pull request #34 from bnb-chain/roshan/parlia
Browse files Browse the repository at this point in the history
chore: merge with upstream
  • Loading branch information
unclezoro authored Jun 19, 2024
2 parents bc30717 + 88cc933 commit e7e3479
Show file tree
Hide file tree
Showing 93 changed files with 2,007 additions and 1,124 deletions.
177 changes: 95 additions & 82 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ members = [
"crates/revm",
"crates/primitives",
"crates/interpreter",
"crates/precompile",
"crates/precompile",
]
resolver = "2"
default-members = ["crates/revm"]
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ cargo run -p revm --features std,serde-json,ethersdb --example generate_block_tr
* [VERBS](https://github.com/simtopia/verbs) an open-source Ethereum agent-based modelling and simulation library with a Python API.
* [Hardhat](https://github.com/NomicFoundation/hardhat) is a development environment to compile, deploy, test, and debug your Ethereum software.
* [Trin](https://github.com/ethereum/trin) is Portal Network client. An execution and consensus layer Ethereum light client written in Rust. Portal Network client's provide complete, provable, and distributed execution archival access.
* [Simular](https://github.com/simular-fi/simular/) is a Python smart-contract API with a fast, embedded, Ethereum Virtual Machine.
* ...

(If you want to add project to the list, ping me or open the PR)
Expand Down
2 changes: 1 addition & 1 deletion bins/revm-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ revm = { path = "../../crates/revm", version = "9.0.0", default-features=false }
microbench = "0.5"
alloy-sol-macro = "0.7.0"
alloy-sol-types = "0.7.0"
regex = "1.10.4"
regex = "1.10.5"
eyre = "0.6.12"


Expand Down
2 changes: 2 additions & 0 deletions bins/revme/src/cmd/statetest/models/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ pub enum SpecName {
Merge,
Shanghai,
Cancun,
Prague,
#[serde(other)]
Unknown,
}
Expand All @@ -44,6 +45,7 @@ impl SpecName {
Self::Merge => SpecId::MERGE,
Self::Shanghai => SpecId::SHANGHAI,
Self::Cancun => SpecId::CANCUN,
Self::Prague => SpecId::PRAGUE,
Self::ByzantiumToConstantinopleAt5 | Self::Constantinople => {
panic!("Overridden with PETERSBURG")
}
Expand Down
15 changes: 11 additions & 4 deletions bins/revme/src/cmd/statetest/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use revm::{
inspector_handle_register,
inspectors::TracerEip3155,
primitives::{
calc_excess_blob_gas, keccak256, Bytecode, Bytes, EVMResultGeneric, Env, ExecutionResult,
SpecId, TransactTo, B256, U256,
calc_excess_blob_gas, keccak256, Bytecode, Bytes, EVMResultGeneric, Env, Eof,
ExecutionResult, SpecId, TransactTo, B256, EOF_MAGIC_BYTES, U256,
},
Evm, State,
};
Expand Down Expand Up @@ -258,10 +258,17 @@ pub fn execute_test_suite(
// Create database and insert cache
let mut cache_state = revm::CacheState::new(false);
for (address, info) in unit.pre {
let code_hash = keccak256(&info.code);
let bytecode = match info.code.get(..2) {
Some(magic) if magic == &EOF_MAGIC_BYTES => {
Bytecode::Eof(Eof::decode(info.code.clone()).unwrap().into())
}
_ => Bytecode::new_raw(info.code),
};
let acc_info = revm::primitives::AccountInfo {
balance: info.balance,
code_hash: keccak256(&info.code),
code: Some(Bytecode::new_raw(info.code)),
code_hash,
code: Some(bytecode),
nonce: info.nonce,
};
cache_state.insert_account_with_storage(address, acc_info, info.storage);
Expand Down
7 changes: 0 additions & 7 deletions crates/interpreter/src/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,6 @@ impl Gas {
self.limit - self.remaining
}

#[doc(hidden)]
#[inline]
#[deprecated(note = "use `spent` instead")]
pub const fn spend(&self) -> u64 {
self.spent()
}

/// Returns the amount of gas remaining.
#[inline]
pub const fn remaining(&self) -> u64 {
Expand Down
2 changes: 1 addition & 1 deletion crates/interpreter/src/gas/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pub const VERYLOW: u64 = 3;
pub const DATA_LOADN_GAS: u64 = 3;

pub const CONDITION_JUMP_GAS: u64 = 4;
pub const RETF_GAS: u64 = 4;
pub const RETF_GAS: u64 = 3;
pub const DATA_LOAD_GAS: u64 = 4;

pub const LOW: u64 = 5;
Expand Down
4 changes: 2 additions & 2 deletions crates/interpreter/src/host.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::primitives::{Address, Bytecode, Env, Log, B256, U256};
use crate::primitives::{Address, Bytes, Env, Log, B256, U256};

mod dummy;
pub use dummy::DummyHost;
Expand All @@ -23,7 +23,7 @@ pub trait Host {
fn balance(&mut self, address: Address) -> Option<(U256, bool)>;

/// Get code of `address` and if the account is cold.
fn code(&mut self, address: Address) -> Option<(Bytecode, bool)>;
fn code(&mut self, address: Address) -> Option<(Bytes, bool)>;

/// Get code hash of `address` and if the account is cold.
fn code_hash(&mut self, address: Address) -> Option<(B256, bool)>;
Expand Down
7 changes: 3 additions & 4 deletions crates/interpreter/src/host/dummy.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::primitives::{hash_map::Entry, Bytecode, HashMap, U256};
use crate::{
primitives::{Address, Env, Log, B256, KECCAK_EMPTY},
primitives::{hash_map::Entry, Address, Bytes, Env, HashMap, Log, B256, KECCAK_EMPTY, U256},
Host, SStoreResult, SelfDestructResult,
};
use std::vec::Vec;
Expand Down Expand Up @@ -61,8 +60,8 @@ impl Host for DummyHost {
}

#[inline]
fn code(&mut self, _address: Address) -> Option<(Bytecode, bool)> {
Some((Bytecode::default(), false))
fn code(&mut self, _address: Address) -> Option<(Bytes, bool)> {
Some((Bytes::default(), false))
}

#[inline]
Expand Down
5 changes: 2 additions & 3 deletions crates/interpreter/src/instruction_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ impl From<SuccessReason> for InstructionResult {
SuccessReason::Return => InstructionResult::Return,
SuccessReason::Stop => InstructionResult::Stop,
SuccessReason::SelfDestruct => InstructionResult::SelfDestruct,
SuccessReason::EofReturnContract => InstructionResult::ReturnContract,
}
}
}
Expand Down Expand Up @@ -269,9 +270,7 @@ impl From<InstructionResult> for SuccessOrHalt {
InstructionResult::FatalExternalError => Self::FatalExternalError,
InstructionResult::EOFOpcodeDisabledInLegacy => Self::Halt(HaltReason::OpcodeNotFound),
InstructionResult::EOFFunctionStackOverflow => Self::FatalExternalError,
InstructionResult::ReturnContract => {
panic!("Unexpected EOF internal Return Contract")
}
InstructionResult::ReturnContract => Self::Success(SuccessReason::EofReturnContract),
}
}
}
Expand Down
23 changes: 5 additions & 18 deletions crates/interpreter/src/instructions/bitwise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,25 +112,12 @@ pub fn sar<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, _host: &
pop_top!(interpreter, op1, op2);

let shift = as_usize_saturated!(op1);
*op2 = if shift >= 256 {
// If the shift is 256 or more, the result depends on the sign of the last bit.
if op2.bit(255) {
U256::MAX // Negative number, all bits set to one.
} else {
U256::ZERO // Non-negative number, all bits set to zero.
}
*op2 = if shift < 256 {
op2.arithmetic_shr(shift)
} else if op2.bit(255) {
U256::MAX
} else {
// Normal shift
if op2.bit(255) {
// Check the most significant bit.
// Arithmetic right shift for negative numbers.
let shifted_value = *op2 >> shift;
let mask = U256::MAX << (256 - shift); // Mask for the sign bits.
shifted_value | mask // Apply the mask to simulate the filling of sign bits.
} else {
// Logical right shift for non-negative numbers.
*op2 >> shift
}
U256::ZERO
};
}

Expand Down
77 changes: 36 additions & 41 deletions crates/interpreter/src/instructions/contract.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,18 @@
mod call_helpers;

pub use call_helpers::{
calc_call_gas, get_memory_input_and_out_ranges, resize_memory_and_return_range,
};
pub use call_helpers::{calc_call_gas, get_memory_input_and_out_ranges, resize_memory};
use revm_primitives::{keccak256, BerlinSpec};

use crate::{
gas::{self, cost_per_word, EOF_CREATE_GAS, KECCAK256WORD},
instructions::utility::read_u16,
interpreter::Interpreter,
primitives::{Address, Bytes, Eof, Spec, SpecId::*, U256},
CallInputs, CallScheme, CallValue, CreateInputs, CreateScheme, EOFCreateInput, Host,
CallInputs, CallScheme, CallValue, CreateInputs, CreateScheme, EOFCreateInputs, Host,
InstructionResult, InterpreterAction, InterpreterResult, LoadAccountResult, MAX_INITCODE_SIZE,
};
use core::{cmp::max, ops::Range};
use core::cmp::max;
use std::boxed::Box;

/// Resize memory and return memory range if successful.
/// Return `None` if there is not enough gas. And if `len`
/// is zero return `Some(usize::MAX..usize::MAX)`.
pub fn resize_memory(
interpreter: &mut Interpreter,
offset: U256,
len: U256,
) -> Option<Range<usize>> {
let len = as_usize_or_fail_ret!(interpreter, len, None);
if len != 0 {
let offset = as_usize_or_fail_ret!(interpreter, offset, None);
resize_memory!(interpreter, offset, len, None);
// range is checked in resize_memory! macro and it is bounded by usize.
Some(offset..offset + len)
} else {
//unrealistic value so we are sure it is not used
Some(usize::MAX..usize::MAX)
}
}

/// EOF Create instruction
pub fn eofcreate<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
require_eof!(interpreter);
Expand All @@ -53,10 +30,20 @@ pub fn eofcreate<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H)
.expect("EOF is checked");

// resize memory and get return range.
let Some(return_range) = resize_memory(interpreter, data_offset, data_size) else {
let Some(input_range) = resize_memory(interpreter, data_offset, data_size) else {
return;
};

let input = if !input_range.is_empty() {
interpreter
.shared_memory
.slice_range(input_range)
.to_vec()
.into()
} else {
Bytes::new()
};

let eof = Eof::decode(sub_container.clone()).expect("Subcontainer is verified");

if !eof.body.is_data_filled {
Expand All @@ -72,18 +59,23 @@ pub fn eofcreate<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H)

let created_address = interpreter
.contract
.caller
.target_address
.create2(salt.to_be_bytes(), keccak256(sub_container));

let gas_reduce = max(interpreter.gas.remaining() / 64, 5000);
let gas_limit = interpreter.gas().remaining().saturating_sub(gas_reduce);
gas!(interpreter, gas_limit);

// Send container for execution container is preverified.
interpreter.instruction_result = InstructionResult::CallOrCreate;
interpreter.next_action = InterpreterAction::EOFCreate {
inputs: Box::new(EOFCreateInput::new(
inputs: Box::new(EOFCreateInputs::new(
interpreter.contract.target_address,
created_address,
value,
eof,
interpreter.gas().remaining(),
return_range,
gas_limit,
input,
)),
};

Expand All @@ -92,7 +84,7 @@ pub fn eofcreate<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H)

pub fn return_contract<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
require_init_eof!(interpreter);
let deploy_container_index = unsafe { read_u16(interpreter.instruction_pointer) };
let deploy_container_index = unsafe { *interpreter.instruction_pointer };
pop!(interpreter, aux_data_offset, aux_data_size);
let aux_data_size = as_usize_or_fail!(interpreter, aux_data_size);
// important: offset must be ignored if len is zeros
Expand Down Expand Up @@ -147,8 +139,11 @@ pub fn return_contract<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &
pub fn extcall_input(interpreter: &mut Interpreter) -> Option<Bytes> {
pop_ret!(interpreter, input_offset, input_size, None);

let return_memory_offset =
resize_memory_and_return_range(interpreter, input_offset, input_size)?;
let return_memory_offset = resize_memory(interpreter, input_offset, input_size)?;

if return_memory_offset.is_empty() {
return Some(Bytes::new());
}

Some(Bytes::copy_from_slice(
interpreter
Expand All @@ -168,10 +163,6 @@ pub fn extcall_gas_calc<H: Host + ?Sized>(
return None;
};

if load_result.is_cold {
gas!(interpreter, gas::COLD_ACCOUNT_ACCESS_COST, None);
}

// TODO(EOF) is_empty should only be checked on delegatecall
let call_cost = gas::call_cost(
BerlinSpec::SPEC_ID,
Expand All @@ -193,8 +184,6 @@ pub fn extcall_gas_calc<H: Host + ?Sized>(
return None;
}

// TODO check remaining gas more then N

gas!(interpreter, gas_limit, None);
Some(gas_limit)
}
Expand All @@ -203,6 +192,8 @@ pub fn extcall<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, host
require_eof!(interpreter);
pop_address!(interpreter, target_address);

// TODO check if target is left paddded with zeroes.

// input call
let Some(input) = extcall_input(interpreter) else {
return;
Expand Down Expand Up @@ -238,6 +229,8 @@ pub fn extdelegatecall<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpret
require_eof!(interpreter);
pop_address!(interpreter, target_address);

// TODO check if target is left paddded with zeroes.

// input call
let Some(input) = extcall_input(interpreter) else {
return;
Expand Down Expand Up @@ -271,6 +264,8 @@ pub fn extstaticcall<H: Host + ?Sized>(interpreter: &mut Interpreter, host: &mut
require_eof!(interpreter);
pop_address!(interpreter, target_address);

// TODO check if target is left paddded with zeroes.

// input call
let Some(input) = extcall_input(interpreter) else {
return;
Expand All @@ -290,7 +285,7 @@ pub fn extstaticcall<H: Host + ?Sized>(interpreter: &mut Interpreter, host: &mut
bytecode_address: target_address,
value: CallValue::Transfer(U256::ZERO),
scheme: CallScheme::Call,
is_static: interpreter.is_static,
is_static: true,
is_eof: true,
return_memory_offset: 0..0,
}),
Expand Down
6 changes: 3 additions & 3 deletions crates/interpreter/src/instructions/contract/call_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ pub fn get_memory_input_and_out_ranges(
) -> Option<(Bytes, Range<usize>)> {
pop_ret!(interpreter, in_offset, in_len, out_offset, out_len, None);

let in_range = resize_memory_and_return_range(interpreter, in_offset, in_len)?;
let in_range = resize_memory(interpreter, in_offset, in_len)?;

let mut input = Bytes::new();
if !in_range.is_empty() {
input = Bytes::copy_from_slice(interpreter.shared_memory.slice_range(in_range));
}

let ret_range = resize_memory_and_return_range(interpreter, out_offset, out_len)?;
let ret_range = resize_memory(interpreter, out_offset, out_len)?;
Some((input, ret_range))
}

/// Resize memory and return range of memory.
/// If `len` is 0 dont touch memory and return `usize::MAX` as offset and 0 as length.
#[inline]
pub fn resize_memory_and_return_range(
pub fn resize_memory(
interpreter: &mut Interpreter,
offset: U256,
len: U256,
Expand Down
4 changes: 3 additions & 1 deletion crates/interpreter/src/instructions/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ pub fn unknown<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {

#[cfg(test)]
mod test {
use std::sync::Arc;

use revm_primitives::{bytes, eof::TypesSection, Bytecode, Eof, PragueSpec};

use super::*;
Expand Down Expand Up @@ -322,7 +324,7 @@ mod test {
eof.body.code_section.push(bytes2.clone());
eof.body.types_section.push(types);

let mut interp = Interpreter::new_bytecode(Bytecode::Eof(eof));
let mut interp = Interpreter::new_bytecode(Bytecode::Eof(Arc::new(eof)));
interp.gas = Gas::new(10000);
interp
}
Expand Down
Loading

0 comments on commit e7e3479

Please sign in to comment.