Skip to content
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
2 changes: 1 addition & 1 deletion bins/revme/src/debugger/ctrl/ctrl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl<DB: Database> Inspector<DB> for Controller {
println!(
"call_depth:{} PC:{} Opcode: {:#x} {:?} gas(spend,remaining):({},{})\n\
Stack:{}",
interp.call_depth,
data.subroutine.depth(),
interp.program_counter(),
opcode,
OPCODE_JUMPMAP[opcode as usize].unwrap_or("Invalid"),
Expand Down
2 changes: 1 addition & 1 deletion bins/revme/src/statetest/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {

println!(
"depth:{}, PC:{}, gas:{:#x}({}), OPCODE: {:?}({:?}) refund:{:#x}({}) Stack:{:?}, Data:",
interp.call_depth,
data.subroutine.depth(),
interp.program_counter(),
interp.gas.remaining()+self.full_gas_block-self.reduced_gas_block,
interp.gas.remaining()+self.full_gas_block-self.reduced_gas_block,
Expand Down
1 change: 1 addition & 0 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ secp256k1 = ["revm_precompiles/secp256k1"]
k256 = ["revm_precompiles/k256_ecrecover"]
web3db = ["futures", "tokio", "parking_lot", "web3"]
with-serde = ["serde", "primitive-types/serde", "hex", "hex/serde"]
memory_limit = []
26 changes: 22 additions & 4 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,17 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
inputs.caller,
inputs.value,
);
let mut interp =
Interpreter::new::<SPEC>(contract, gas.limit(), self.data.subroutine.depth());

#[cfg(feature = "memory_limit")]
let mut interp = Interpreter::new_with_memory_limit::<SPEC>(
contract,
gas.limit(),
self.data.env.cfg.memory_limit,
);

#[cfg(not(feature = "memory_limit"))]
let mut interp = Interpreter::new::<SPEC>(contract, gas.limit());

if Self::INSPECT {
self.inspector
.initialize_interp(&mut interp, &mut self.data, false); // TODO fix is_static
Expand Down Expand Up @@ -518,8 +527,17 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
// Create interpreter and execute subcall
let contract =
Contract::new_with_context::<SPEC>(inputs.input.clone(), code, &inputs.context);
let mut interp =
Interpreter::new::<SPEC>(contract, inputs.gas_limit, self.data.subroutine.depth());

#[cfg(feature = "memory_limit")]
let mut interp = Interpreter::new_with_memory_limit::<SPEC>(
contract,
gas.limit(),
self.data.env.cfg.memory_limit,
);

#[cfg(not(feature = "memory_limit"))]
let mut interp = Interpreter::new::<SPEC>(contract, gas.limit());

if Self::INSPECT {
self.inspector
.initialize_interp(&mut interp, &mut self.data, false); // TODO fix is_static
Expand Down
5 changes: 5 additions & 0 deletions crates/revm/src/instructions/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ macro_rules! memory_resize {
if let Some(new_size) =
crate::interpreter::memory::next_multiple_of_32(offset.saturating_add(len))
{
#[cfg(feature = "memory_limit")]
if new_size > ($interp.memory_limit as usize) {
return Return::OutOfGas;
}

if new_size > $interp.memory.len() {
if crate::USE_GAS {
let num_bytes = new_size / 32;
Expand Down
29 changes: 24 additions & 5 deletions crates/revm/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ pub struct Interpreter {
pub return_data_buffer: Bytes,
/// Return value.
pub return_range: Range<usize>,
/// used only for inspector.
pub call_depth: u64,
/// Memory limit. See [`crate::CfgEnv`].
#[cfg(feature = "memory_limit")]
pub memory_limit: u64,
}

impl Interpreter {
pub fn new<SPEC: Spec>(contract: Contract, gas_limit: u64, call_depth: u64) -> Self {
#[cfg(not(feature = "memory_limit"))]
pub fn new<SPEC: Spec>(contract: Contract, gas_limit: u64) -> Self {
Self {
program_counter: contract.code.as_ptr(),
return_range: Range::default(),
Expand All @@ -45,10 +47,27 @@ impl Interpreter {
return_data_buffer: Bytes::new(),
contract,
gas: Gas::new(gas_limit),
call_depth,
//times: [(std::time::Duration::ZERO, 0); 256],
}
}

#[cfg(feature = "memory_limit")]
pub fn new_with_memory_limit<SPEC: Spec>(
contract: Contract,
gas_limit: u64,
memory_limit: u64,
) -> Self {
Self {
program_counter: contract.code.as_ptr(),
return_range: Range::default(),
memory: Memory::new(),
stack: Stack::new(),
return_data_buffer: Bytes::new(),
contract,
gas: Gas::new(gas_limit),
memory_limit,
}
}

pub fn contract(&self) -> &Contract {
&self.contract
}
Expand Down
19 changes: 14 additions & 5 deletions crates/revm/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,18 +218,27 @@ pub struct TxEnv {
pub struct CfgEnv {
pub chain_id: U256,
pub spec_id: SpecId,
/// if all precompiles have some balance we can ignore initial fetching them from db.
/// this is clearly making noice if we use debugger and it is not really needed on mainnet.
/// default is false in most cases it is safe to be set to true, it depends on chain.
/// If all precompiles have some balance we can skip initially fetching them from the database.
/// This is is not really needed on mainnet, and defaults to false, but in most cases it is
/// safe to be set to `true`, depending on the chain.
pub perf_all_precompiles_have_balance: bool,
/// A hard memory limit in bytes beyond which [Memory] cannot be resized.
///
/// In cases where the gas limit may be extraordinarily high, it is recommended to set this to
/// a sane value to prevent memory allocation panics. Defaults to `2^32 - 1` bytes per
/// EIP-1985.
#[cfg(feature = "memory_limit")]
pub memory_limit: u64,
}

impl Default for CfgEnv {
fn default() -> CfgEnv {
CfgEnv {
chain_id: 1.into(), //mainnet is 1
chain_id: 1.into(),
spec_id: SpecId::LATEST,
perf_all_precompiles_have_balance: false,
#[cfg(feature = "memory_limit")]
memory_limit: 2u64.pow(32) - 1,
}
}
}
Expand All @@ -239,7 +248,7 @@ impl Default for BlockEnv {
BlockEnv {
gas_limit: U256::MAX,
number: 0.into(),
coinbase: H160::zero(), //zero address
coinbase: H160::zero(),
timestamp: U256::one(),
difficulty: U256::zero(),
basefee: U256::zero(),
Expand Down