Skip to content
Closed
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
8 changes: 7 additions & 1 deletion crates/interpreter/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::primitives::Bytecode;
use crate::{
primitives::{Address, Bytes, Env, B256, U256},
CallInputs, CreateInputs, Gas, InstructionResult, Interpreter, SelfDestructResult,
SharedMemory,
};
use alloc::vec::Vec;
pub use dummy::DummyHost;
Expand Down Expand Up @@ -51,7 +52,12 @@ pub trait Host {
fn create(
&mut self,
inputs: &mut CreateInputs,
shared_memory: &mut SharedMemory,
) -> (InstructionResult, Option<Address>, Gas, Bytes);
/// Invoke a call operation.
fn call(&mut self, input: &mut CallInputs) -> (InstructionResult, Gas, Bytes);
fn call(
&mut self,
input: &mut CallInputs,
shared_memory: &mut SharedMemory,
) -> (InstructionResult, Gas, Bytes);
}
8 changes: 7 additions & 1 deletion crates/interpreter/src/host/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::primitives::{hash_map::Entry, Bytecode, Bytes, HashMap, U256};
use crate::{
primitives::{Address, Env, Log, B256, KECCAK_EMPTY},
CallInputs, CreateInputs, Gas, Host, InstructionResult, Interpreter, SelfDestructResult,
SharedMemory,
};
use alloc::vec::Vec;

Expand Down Expand Up @@ -137,12 +138,17 @@ impl Host for DummyHost {
fn create(
&mut self,
_inputs: &mut CreateInputs,
_shared_memory: &mut SharedMemory,
) -> (InstructionResult, Option<Address>, Gas, Bytes) {
panic!("Create is not supported for this host")
}

#[inline]
fn call(&mut self, _input: &mut CallInputs) -> (InstructionResult, Gas, Bytes) {
fn call(
&mut self,
_input: &mut CallInputs,
_shared_memory: &mut SharedMemory,
) -> (InstructionResult, Gas, Bytes) {
panic!("Call is not supported for this host")
}
}
2 changes: 1 addition & 1 deletion crates/interpreter/src/instructions/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fn return_inner(interpreter: &mut Interpreter, result: InstructionResult) {
// important: offset must be ignored if len is zero
if len != 0 {
let offset = as_usize_or_fail!(interpreter, offset);
memory_resize!(interpreter, offset, len);
shared_memory_resize!(interpreter, offset, len);
interpreter.return_offset = offset;
}
interpreter.return_len = len;
Expand Down
28 changes: 14 additions & 14 deletions crates/interpreter/src/instructions/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ pub fn extcodecopy<H: Host, SPEC: Spec>(interpreter: &mut Interpreter, host: &mu
}
let memory_offset = as_usize_or_fail!(interpreter, memory_offset);
let code_offset = min(as_usize_saturated!(code_offset), code.len());
memory_resize!(interpreter, memory_offset, len);
shared_memory_resize!(interpreter, memory_offset, len);

// Safety: set_data is unsafe function and memory_resize ensures us that it is safe to call it
interpreter
.memory
.shared_memory
.set_data(memory_offset, code_offset, len, code.bytes());
}

Expand Down Expand Up @@ -197,8 +197,8 @@ pub fn log<H: Host, const N: usize>(interpreter: &mut Interpreter, host: &mut H)
Bytes::new()
} else {
let offset = as_usize_or_fail!(interpreter, offset);
memory_resize!(interpreter, offset, len);
Bytes::copy_from_slice(interpreter.memory.slice(offset, len))
shared_memory_resize!(interpreter, offset, len);
Bytes::copy_from_slice(interpreter.shared_memory.slice(offset, len))
};

if interpreter.stack.len() < N {
Expand Down Expand Up @@ -273,8 +273,8 @@ pub fn prepare_create_inputs<H: Host, const IS_CREATE2: bool, SPEC: Spec>(
}

let code_offset = as_usize_or_fail!(interpreter, code_offset);
memory_resize!(interpreter, code_offset, len);
Bytes::copy_from_slice(interpreter.memory.slice(code_offset, len))
shared_memory_resize!(interpreter, code_offset, len);
Bytes::copy_from_slice(interpreter.shared_memory.slice(code_offset, len))
};

let scheme = if IS_CREATE2 {
Expand Down Expand Up @@ -315,7 +315,8 @@ pub fn create<H: Host, const IS_CREATE2: bool, SPEC: Spec>(
return;
};

let (return_reason, address, gas, return_data) = host.create(&mut create_input);
let (return_reason, address, gas, return_data) =
host.create(&mut create_input, interpreter.shared_memory);

interpreter.return_data_buffer = match return_reason {
// Save data to return data buffer if the create reverted
Expand Down Expand Up @@ -399,16 +400,16 @@ fn prepare_call_inputs<H: Host, SPEC: Spec>(
let in_len = as_usize_or_fail!(interpreter, in_len);
let input = if in_len != 0 {
let in_offset = as_usize_or_fail!(interpreter, in_offset);
memory_resize!(interpreter, in_offset, in_len);
Bytes::copy_from_slice(interpreter.memory.slice(in_offset, in_len))
shared_memory_resize!(interpreter, in_offset, in_len);
Bytes::copy_from_slice(interpreter.shared_memory.slice(in_offset, in_len))
} else {
Bytes::new()
};

*result_len = as_usize_or_fail!(interpreter, out_len);
*result_offset = if *result_len != 0 {
let out_offset = as_usize_or_fail!(interpreter, out_offset);
memory_resize!(interpreter, out_offset, *result_len);
shared_memory_resize!(interpreter, out_offset, *result_len);
out_offset
} else {
usize::MAX //unrealistic value so we are sure it is not used
Expand Down Expand Up @@ -535,10 +536,9 @@ pub fn call_inner<H: Host, SPEC: Spec>(
};

// Call host to interact with target contract
let (reason, gas, return_data) = host.call(&mut call_input);
let (reason, gas, return_data) = host.call(&mut call_input, interpreter.shared_memory);

interpreter.return_data_buffer = return_data;

let target_len = min(out_len, interpreter.return_data_buffer.len());

match reason {
Expand All @@ -549,7 +549,7 @@ pub fn call_inner<H: Host, SPEC: Spec>(
interpreter.gas.record_refund(gas.refunded());
}
interpreter
.memory
.shared_memory
.set(out_offset, &interpreter.return_data_buffer[..target_len]);
push!(interpreter, U256::from(1));
}
Expand All @@ -558,7 +558,7 @@ pub fn call_inner<H: Host, SPEC: Spec>(
interpreter.gas.erase_cost(gas.remaining());
}
interpreter
.memory
.shared_memory
.set(out_offset, &interpreter.return_data_buffer[..target_len]);
push!(interpreter, U256::ZERO);
}
Expand Down
14 changes: 4 additions & 10 deletions crates/interpreter/src/instructions/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,26 +50,20 @@ macro_rules! gas_or_fail {
};
}

macro_rules! memory_resize {
macro_rules! shared_memory_resize {
($interp:expr, $offset:expr, $len:expr) => {
if let Some(new_size) =
crate::interpreter::memory::next_multiple_of_32($offset.saturating_add($len))
crate::interpreter::shared_memory::next_multiple_of_32($offset.saturating_add($len))
{
#[cfg(feature = "memory_limit")]
if new_size > ($interp.memory_limit as usize) {
$interp.instruction_result = InstructionResult::MemoryLimitOOG;
return;
}

if new_size > $interp.memory.len() {
if new_size > $interp.shared_memory.len() {
if crate::USE_GAS {
let num_bytes = new_size / 32;
if !$interp.gas.record_memory(crate::gas::memory_gas(num_bytes)) {
$interp.instruction_result = InstructionResult::MemoryLimitOOG;
return;
}
}
$interp.memory.resize(new_size);
$interp.shared_memory.resize(new_size);
}
} else {
$interp.instruction_result = InstructionResult::MemoryOOG;
Expand Down
24 changes: 15 additions & 9 deletions crates/interpreter/src/instructions/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,38 @@ pub fn mload<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {
gas!(interpreter, gas::VERYLOW);
pop!(interpreter, index);
let index = as_usize_or_fail!(interpreter, index);
memory_resize!(interpreter, index, 32);
shared_memory_resize!(interpreter, index, 32);
push!(
interpreter,
U256::from_be_bytes::<32>(interpreter.memory.slice(index, 32).try_into().unwrap())
U256::from_be_bytes::<32>(
interpreter
.shared_memory
.slice(index, 32)
.try_into()
.unwrap()
)
);
}

pub fn mstore<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {
gas!(interpreter, gas::VERYLOW);
pop!(interpreter, index, value);
let index = as_usize_or_fail!(interpreter, index);
memory_resize!(interpreter, index, 32);
interpreter.memory.set_u256(index, value);
shared_memory_resize!(interpreter, index, 32);
interpreter.shared_memory.set_u256(index, value);
}

pub fn mstore8<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {
gas!(interpreter, gas::VERYLOW);
pop!(interpreter, index, value);
let index = as_usize_or_fail!(interpreter, index);
memory_resize!(interpreter, index, 1);
interpreter.memory.set_byte(index, value.byte(0))
shared_memory_resize!(interpreter, index, 1);
interpreter.shared_memory.set_byte(index, value.byte(0))
}

pub fn msize<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {
gas!(interpreter, gas::BASE);
push!(interpreter, U256::from(interpreter.memory.len()));
push!(interpreter, U256::from(interpreter.shared_memory.len()));
}

// EIP-5656: MCOPY - Memory copying instruction
Expand All @@ -53,7 +59,7 @@ pub fn mcopy<H: Host, SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut H)
let dst = as_usize_or_fail!(interpreter, dst);
let src = as_usize_or_fail!(interpreter, src);
// resize memory
memory_resize!(interpreter, max(dst, src), len);
shared_memory_resize!(interpreter, max(dst, src), len);
// copy memory in place
interpreter.memory.copy(dst, src, len);
interpreter.shared_memory.copy(dst, src, len);
}
23 changes: 13 additions & 10 deletions crates/interpreter/src/instructions/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ pub fn keccak256<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {
KECCAK_EMPTY
} else {
let from = as_usize_or_fail!(interpreter, from);
memory_resize!(interpreter, from, len);
crate::primitives::keccak256(interpreter.memory.slice(from, len))
shared_memory_resize!(interpreter, from, len);
crate::primitives::keccak256(interpreter.shared_memory.slice(from, len))
};

push_b256!(interpreter, hash);
Expand Down Expand Up @@ -43,10 +43,10 @@ pub fn codecopy<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {
}
let memory_offset = as_usize_or_fail!(interpreter, memory_offset);
let code_offset = as_usize_saturated!(code_offset);
memory_resize!(interpreter, memory_offset, len);
shared_memory_resize!(interpreter, memory_offset, len);

// Safety: set_data is unsafe function and memory_resize ensures us that it is safe to call it
interpreter.memory.set_data(
interpreter.shared_memory.set_data(
memory_offset,
code_offset,
len,
Expand Down Expand Up @@ -89,12 +89,15 @@ pub fn calldatacopy<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {
}
let memory_offset = as_usize_or_fail!(interpreter, memory_offset);
let data_offset = as_usize_saturated!(data_offset);
memory_resize!(interpreter, memory_offset, len);
shared_memory_resize!(interpreter, memory_offset, len);

// Safety: set_data is unsafe function and memory_resize ensures us that it is safe to call it
interpreter
.memory
.set_data(memory_offset, data_offset, len, &interpreter.contract.input);
interpreter.shared_memory.set_data(
memory_offset,
data_offset,
len,
&interpreter.contract.input,
);
}

/// EIP-211: New opcodes: RETURNDATASIZE and RETURNDATACOPY
Expand All @@ -121,8 +124,8 @@ pub fn returndatacopy<H: Host, SPEC: Spec>(interpreter: &mut Interpreter, _host:
}
if len != 0 {
let memory_offset = as_usize_or_fail!(interpreter, memory_offset);
memory_resize!(interpreter, memory_offset, len);
interpreter.memory.set(
shared_memory_resize!(interpreter, memory_offset, len);
interpreter.shared_memory.set(
memory_offset,
&interpreter.return_data_buffer[data_offset..data_end],
);
Expand Down
Loading