Skip to content

Commit

Permalink
cleanup, nits, fix build
Browse files Browse the repository at this point in the history
  • Loading branch information
rakita committed Dec 4, 2022
1 parent c019de9 commit fb8073d
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 71 deletions.
10 changes: 3 additions & 7 deletions bins/revm-test/src/bin/snailtracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,9 @@ pub fn simple_example() {
// Microbenchmark
let bench_options = microbench::Options::default().time(Duration::from_secs(3));

microbench::bench(
&bench_options,
"Snailtracer benchmark",
|| {
let (_, _) = evm.transact();
},
);
microbench::bench(&bench_options, "Snailtracer benchmark", || {
let (_, _) = evm.transact();
});
}

fn main() {
Expand Down
1 change: 1 addition & 0 deletions crates/revm/src/db/web3db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ impl Database for Web3DB {
}

fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
// saturate usize
if number > U256::from(u64::MAX) {
return Ok(KECCAK_EMPTY);
}
Expand Down
40 changes: 24 additions & 16 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,32 +476,33 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
);

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

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

if INSPECT {
self.inspector
.initialize_interp(&mut interp, &mut self.data, false);
.initialize_interp(&mut interpreter, &mut self.data, false);
}
let exit_reason = interp.run::<Self, GSPEC>(self, INSPECT);
let exit_reason = interpreter.run::<Self, GSPEC>(self, INSPECT);

// Host error if present on execution\
let (ret, address, gas, out) = match exit_reason {
return_ok!() => {
let b = Bytes::new();
// if ok, check contract creation limit and calculate gas deduction on output len.
let mut bytes = interp.return_value();
let mut bytes = interpreter.return_value();

// EIP-3541: Reject new contract code starting with the 0xEF byte
if GSPEC::enabled(LONDON) && !bytes.is_empty() && bytes.first() == Some(&0xEF) {
self.data.journaled_state.checkpoint_revert(checkpoint);
return (Return::CreateContractWithEF, ret, interp.gas, b);
return (Return::CreateContractWithEF, ret, interpreter.gas, b);
}

// EIP-170: Contract code size limit
Expand All @@ -510,18 +511,18 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
&& bytes.len() > self.data.env.cfg.limit_contract_code_size.unwrap_or(0x6000)
{
self.data.journaled_state.checkpoint_revert(checkpoint);
return (Return::CreateContractLimit, ret, interp.gas, b);
return (Return::CreateContractLimit, ret, interpreter.gas, b);
}
if crate::USE_GAS {
let gas_for_code = bytes.len() as u64 * crate::gas::CODEDEPOSIT;
if !interp.gas.record_cost(gas_for_code) {
if !interpreter.gas.record_cost(gas_for_code) {
// record code deposit gas cost and check if we are out of gas.
// EIP-2 point 3: If contract creation does not have enough gas to pay for the
// final gas fee for adding the contract code to the state, the contract
// creation fails (i.e. goes out-of-gas) rather than leaving an empty contract.
if GSPEC::enabled(HOMESTEAD) {
self.data.journaled_state.checkpoint_revert(checkpoint);
return (Return::OutOfGas, ret, interp.gas, b);
return (Return::OutOfGas, ret, interpreter.gas, b);
} else {
bytes = Bytes::new();
}
Expand All @@ -539,11 +540,16 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
self.data
.journaled_state
.set_code(created_address, bytecode);
(Return::Continue, ret, interp.gas, b)
(Return::Continue, ret, interpreter.gas, b)
}
_ => {
self.data.journaled_state.checkpoint_revert(checkpoint);
(exit_reason, ret, interp.gas, interp.return_value())
(
exit_reason,
ret,
interpreter.gas,
interpreter.return_value(),
)
}
};

Expand Down Expand Up @@ -668,28 +674,30 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
);

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

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

if INSPECT {
// create is always no static call.
self.inspector
.initialize_interp(&mut interp, &mut self.data, false);
.initialize_interp(&mut interpreter, &mut self.data, false);
}
let exit_reason = interp.run::<Self, GSPEC>(self, INSPECT);
let exit_reason = interpreter.run::<Self, GSPEC>(self, INSPECT);
if matches!(exit_reason, return_ok!()) {
self.data.journaled_state.checkpoint_commit();
} else {
self.data.journaled_state.checkpoint_revert(checkpoint);
}

(exit_reason, interp.gas, interp.return_value())
(exit_reason, interpreter.gas, interpreter.return_value())
};

if INSPECT {
Expand Down
6 changes: 3 additions & 3 deletions crates/revm/src/instructions/bitwise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub fn byte(interpreter: &mut Interpreter, _host: &mut dyn Host) {

for i in 0..256 {
if i < 8 && op1 < U256::from(32) {
let o = u128::try_from(op1).unwrap() as usize;
let o = as_usize_saturated!(op1);
let t = 255 - (7 - i + 8 * o);
let bit_mask = U256::from(1) << t;
let value = (*op2 & bit_mask) >> t;
Expand All @@ -95,14 +95,14 @@ pub fn shl<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
// EIP-145: Bitwise shifting instructions in EVM
check!(interpreter, SPEC::enabled(CONSTANTINOPLE));
pop_top!(interpreter, op1, op2);
*op2 = *op2 << usize::try_from(op1).unwrap_or(256)
*op2 <<= as_usize_saturated!(op1);
}

pub fn shr<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
// EIP-145: Bitwise shifting instructions in EVM
check!(interpreter, SPEC::enabled(CONSTANTINOPLE));
pop_top!(interpreter, op1, op2);
*op2 = *op2 >> usize::try_from(op1).unwrap_or(256)
*op2 >>= as_usize_saturated!(op1);
}

pub fn sar<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
Expand Down
15 changes: 8 additions & 7 deletions crates/revm/src/instructions/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use crate::{gas, interpreter::Interpreter, Host, Return, Spec, SpecId::*, U256};
pub fn jump(interpreter: &mut Interpreter, _host: &mut dyn Host) {
// gas!(interp, gas::MID);
pop!(interpreter, dest);
let dest = as_usize_or_fail!(interpreter,dest, Return::InvalidJump);
let dest = as_usize_or_fail!(interpreter, dest, Return::InvalidJump);
if interpreter.contract.is_valid_jump(dest) {
// Safety: In analysis we are checking create our jump table and we do check above to be
// sure that jump is safe to execute.
interpreter.instruction_pointer = unsafe { interpreter.contract.bytecode.as_ptr().add(dest) };
interpreter.instruction_pointer =
unsafe { interpreter.contract.bytecode.as_ptr().add(dest) };
} else {
interpreter.instruction_result = Return::InvalidJump;
}
Expand All @@ -17,7 +18,7 @@ pub fn jumpi(interpreter: &mut Interpreter, _host: &mut dyn Host) {
// gas!(interp, gas::HIGH);
pop!(interpreter, dest, value);
if value != U256::ZERO {
let dest = as_usize_or_fail!(interpreter,dest, Return::InvalidJump);
let dest = as_usize_or_fail!(interpreter, dest, Return::InvalidJump);
if interpreter.contract.is_valid_jump(dest) {
// Safety: In analysis we are checking if jump is valid destination and
// this `if` makes this unsafe block safe.
Expand Down Expand Up @@ -47,11 +48,11 @@ pub fn pc(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn ret(interpreter: &mut Interpreter, _host: &mut dyn Host) {
// zero gas cost gas!(interp,gas::ZERO);
pop!(interpreter, start, len);
let len = as_usize_or_fail!(interpreter,len, Return::OutOfGas);
let len = as_usize_or_fail!(interpreter, len, Return::OutOfGas);
if len == 0 {
interpreter.return_range = usize::MAX..usize::MAX;
} else {
let offset = as_usize_or_fail!(interpreter,start, Return::OutOfGas);
let offset = as_usize_or_fail!(interpreter, start, Return::OutOfGas);
memory_resize!(interpreter, offset, len);
interpreter.return_range = offset..(offset + len);
}
Expand All @@ -63,11 +64,11 @@ pub fn revert<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn Host) {
// EIP-140: REVERT instruction
check!(interpreter, SPEC::enabled(BYZANTIUM));
pop!(interpreter, start, len);
let len = as_usize_or_fail!(interpreter,len, Return::OutOfGas);
let len = as_usize_or_fail!(interpreter, len, Return::OutOfGas);
if len == 0 {
interpreter.return_range = usize::MAX..usize::MAX;
} else {
let offset = as_usize_or_fail!(interpreter,start, Return::OutOfGas);
let offset = as_usize_or_fail!(interpreter, start, Return::OutOfGas);
memory_resize!(interpreter, offset, len);
interpreter.return_range = offset..(offset + len);
}
Expand Down
6 changes: 4 additions & 2 deletions crates/revm/src/instructions/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub fn blockhash(interpreter: &mut Interpreter, host: &mut dyn Host) {
return;
}
*number = U256::from_be_bytes(*ret.unwrap());
return
return;
}
}
*number = U256::ZERO;
Expand Down Expand Up @@ -188,7 +188,9 @@ pub fn log<const N: u8, SPEC: Spec>(interpreter: &mut Interpreter, host: &mut dy
let mut topics = Vec::with_capacity(n);
for _ in 0..(n) {
// Safety: stack bounds already checked few lines above
topics.push(B256(unsafe { interpreter.stack.pop_unsafe().to_be_bytes() }));
topics.push(B256(unsafe {
interpreter.stack.pop_unsafe().to_be_bytes()
}));
}

host.log(interpreter.contract.address, topics, data);
Expand Down
34 changes: 9 additions & 25 deletions crates/revm/src/instructions/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,38 +195,22 @@ macro_rules! push {
)
}

// macro_rules! as_usize_saturated {
// ( $v:expr ) => {
// $v.saturating_to::<usize>()
// };
// }

// macro_rules! as_usize_or_fail {
// ( $interp:expr, $v:expr ) => {{
// as_usize_or_fail!($interp, $v, Return::OutOfGas)
// }};

// ( $interp:expr, $v:expr, $reason:expr ) => {
// match $v[0] == 0 {
// Ok(value) => value,
// Err(_) => {
// $interp.instruction_result = $reason;
// return;
// }
// }
// };
// }

macro_rules! as_usize_saturated {
macro_rules! as_u64_saturated {
( $v:expr ) => {{
if $v.as_limbs()[1] != 0 || $v.as_limbs()[2] != 0 || $v.as_limbs()[3] != 0 {
usize::MAX
u64::MAX
} else {
$v.as_limbs()[0] as usize
$v.as_limbs()[0]
}
}};
}

macro_rules! as_usize_saturated {
( $v:expr ) => {{
as_u64_saturated!($v) as usize
}};
}

macro_rules! as_usize_or_fail {
( $interp:expr, $v:expr ) => {{
as_usize_or_fail!($interp, $v, Return::OutOfGas)
Expand Down
8 changes: 4 additions & 4 deletions crates/revm/src/instructions/system.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
B256, U256, common::keccak256, gas, interpreter::Interpreter, Host, Return, Spec, SpecId::*, KECCAK_EMPTY,
common::keccak256, gas, interpreter::Interpreter, Host, Return, Spec, SpecId::*, B256,
KECCAK_EMPTY, U256,
};
use std::cmp::min;

Expand All @@ -26,7 +27,6 @@ pub fn address(interpreter: &mut Interpreter, _host: &mut dyn Host) {
pub fn caller(interpreter: &mut Interpreter, _host: &mut dyn Host) {
// gas!(interp, gas::BASE);
push_b256!(interpreter, B256::from(interpreter.contract.caller));

}

pub fn codesize(interpreter: &mut Interpreter, _host: &mut dyn Host) {
Expand Down Expand Up @@ -112,7 +112,7 @@ pub fn returndatacopy<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn
// EIP-211: New opcodes: RETURNDATASIZE and RETURNDATACOPY
check!(interpreter, SPEC::enabled(BYZANTIUM));
pop!(interpreter, memory_offset, offset, len);
let len = as_usize_or_fail!(interpreter,len, Return::OutOfGas);
let len = as_usize_or_fail!(interpreter, len, Return::OutOfGas);
gas_or_fail!(interpreter, gas::verylowcopy_cost(len as u64));
let data_offset = as_usize_saturated!(offset);
let (data_end, overflow) = data_offset.overflowing_add(len);
Expand All @@ -121,7 +121,7 @@ pub fn returndatacopy<SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut dyn
return;
}
if len != 0 {
let memory_offset = as_usize_or_fail!(interpreter,memory_offset, Return::OutOfGas);
let memory_offset = as_usize_or_fail!(interpreter, memory_offset, Return::OutOfGas);
memory_resize!(interpreter, memory_offset, len);
interpreter.memory.set(
memory_offset,
Expand Down
8 changes: 5 additions & 3 deletions crates/revm/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub use stack::Stack;

use crate::{
instructions::{eval, Return},
Gas, Host, USE_GAS,Spec
Gas, Host, Spec, USE_GAS,
};
use bytes::Bytes;
use core::ops::Range;
Expand Down Expand Up @@ -47,8 +47,7 @@ impl Interpreter {
unsafe { *self.instruction_pointer }
}
#[cfg(not(feature = "memory_limit"))]
pub fn new<SPEC: Spec>(contract: Contract, gas_limit: u64,is_static:bool) -> Self {

pub fn new<SPEC: Spec>(contract: Contract, gas_limit: u64, is_static: bool) -> Self {
Self {
instruction_pointer: contract.bytecode.as_ptr(),
return_range: Range::default(),
Expand All @@ -66,6 +65,7 @@ impl Interpreter {
pub fn new_with_memory_limit<SPEC: Spec>(
contract: Contract,
gas_limit: u64,
is_static: bool,
memory_limit: u64,
) -> Self {
Self {
Expand All @@ -75,6 +75,8 @@ impl Interpreter {
stack: Stack::new(),
return_data_buffer: Bytes::new(),
contract,
instruction_result: Return::Continue,
is_static,
gas: Gas::new(gas_limit),
memory_limit,
}
Expand Down
9 changes: 5 additions & 4 deletions crates/revm_precompiles/src/modexp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ fn byzantium_gas_calc(base_len: u64, exp_len: u64, mod_len: u64, exp_highp: &Big
// mul * iter_count bounded by 2^195 < 2^256 (no overflow)
let gas = (mul * iter_count) / U256::from(20);

if gas.bit_len() > 64 {
if gas.as_limbs()[1] != 0 || gas.as_limbs()[2] != 0 || gas.as_limbs()[3] != 0 {
u64::MAX
} else {
u128::try_from(gas).unwrap() as u64
gas.as_limbs()[0]
}
}

Expand All @@ -185,10 +185,11 @@ fn berlin_gas_calc(base_length: u64, exp_length: u64, mod_length: u64, exp_highp
let multiplication_complexity = calculate_multiplication_complexity(base_length, mod_length);
let iteration_count = calculate_iteration_count(exp_length, exp_highp);
let gas = (multiplication_complexity * U256::from(iteration_count)) / U256::from(3);
if gas > U256::from(u64::MAX) {

if gas.as_limbs()[1] != 0 || gas.as_limbs()[2] != 0 || gas.as_limbs()[3] != 0 {
u64::MAX
} else {
max(200, u128::try_from(gas).unwrap() as u64)
max(200, gas.as_limbs()[0])
}
}

Expand Down

0 comments on commit fb8073d

Please sign in to comment.