Skip to content

Commit

Permalink
[revm] Add CreateInputs
Browse files Browse the repository at this point in the history
  • Loading branch information
rakita committed Feb 20, 2022
1 parent 0c389f2 commit b092da0
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 134 deletions.
16 changes: 4 additions & 12 deletions bins/revme/src/debugger/ctrl/ctrl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::path::PathBuf;
use bytes::Bytes;

use primitive_types::{H160, U256};
use revm::{Database, EVMData, Gas, Inspector, Return, OPCODE_JUMPMAP, CallInputs};
use revm::{CallInputs, CreateInputs, Database, EVMData, Gas, Inspector, Return, OPCODE_JUMPMAP};

use termwiz::lineedit::*;

Expand Down Expand Up @@ -234,26 +234,18 @@ impl<DB: Database> Inspector<DB> for Controller {
fn create(
&mut self,
_data: &mut revm::EVMData<'_, DB>,
_caller: primitive_types::H160,
_scheme: &revm::CreateScheme,
_value: primitive_types::U256,
_init_code: &bytes::Bytes,
_gas: u64,
_inputs: &CreateInputs,
) -> (Return, Option<H160>, Gas, Bytes) {
(Return::Continue, None, Gas::new(0), Bytes::new())
}

fn create_end(
&mut self,
_data: &mut EVMData<'_, DB>,
_caller: H160,
_scheme: &revm::CreateScheme,
_value: U256,
_init_code: &Bytes,
_inputs: &CreateInputs,
_ret: Return,
_address: Option<H160>,
_gas_limit: u64,
_remaining_gas: u64,
_remaining_gas: Gas,
_out: &Bytes,
) {
if let StateMachine::StepOut = self.state_interp {
Expand Down
30 changes: 11 additions & 19 deletions bins/revme/src/statetest/trace.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use bytes::Bytes;
use primitive_types::{H160, U256};
use primitive_types::H160;
pub use revm::Inspector;
use revm::{opcode, spec_opcode_gas, Database, EVMData, Gas, Return, CallInputs};
use revm::{opcode, spec_opcode_gas, Database, EVMData, Gas, Return, CallInputs, CreateInputs};

#[derive(Clone)]
pub struct CustomPrintTracer {
Expand Down Expand Up @@ -90,7 +90,7 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {
) -> (Return, Gas, Bytes) {
println!(
"SM CALL: {:?},context:{:?}, is_static:{:?}, transfer:{:?}, input:{:?}",
inputs.code_address,
inputs.contract,
inputs.context,
is_static,
inputs.transfer,
Expand All @@ -113,34 +113,26 @@ impl<DB: Database> Inspector<DB> for CustomPrintTracer {
fn create(
&mut self,
_data: &mut EVMData<'_, DB>,
caller: H160,
scheme: &revm::CreateScheme,
value: U256,
init_code: &bytes::Bytes,
gas: u64,
inputs: &CreateInputs,
) -> (Return, Option<H160>, Gas, Bytes) {
println!(
"CREATE CALL: caller:{:?}, scheme:{:?}, value:{:?}, init_code:{:?}, gas:{:?}",
caller,
scheme,
value,
hex::encode(init_code),
gas
inputs.caller,
inputs.scheme,
inputs.value,
hex::encode(&inputs.init_code),
inputs.gas_limit
);
(Return::Continue, None, Gas::new(0), Bytes::new())
}

fn create_end(
&mut self,
_data: &mut EVMData<'_, DB>,
_caller: H160,
_scheme: &revm::CreateScheme,
_value: U256,
_init_code: &Bytes,
_inputs: &CreateInputs,
_ret: Return,
_address: Option<H160>,
_gas_limit: u64,
_remaining_gas: u64,
_remaining_gas: Gas,
_out: &Bytes,
) {
}
Expand Down
115 changes: 41 additions & 74 deletions crates/revm/src/evm_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
models::SelfDestructResult,
return_ok,
subroutine::{Account, State, SubRoutine},
CallContext, CallInputs, CreateScheme, Env, Gas, Inspector, Log, Return, Spec,
CallContext, CallInputs, CreateInputs, CreateScheme, Env, Gas, Inspector, Log, Return, Spec,
SpecId::*,
TransactOut, TransactTo, Transfer, KECCAK_EMPTY,
};
Expand Down Expand Up @@ -118,7 +118,7 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> Transact
apparent_value: value,
};
let call_input = CallInputs {
code_address: address,
contract: address,
transfer: Transfer {
source: caller,
target: address,
Expand All @@ -132,8 +132,14 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> Transact
(exit, gas, TransactOut::Call(bytes))
}
TransactTo::Create(scheme) => {
let (exit, address, ret_gas, bytes) =
self.create_inner::<GSPEC>(caller, scheme, value, data, gas_limit);
let create_input = CreateInputs {
caller,
scheme,
value,
init_code: data,
gas_limit,
};
let (exit, address, ret_gas, bytes) = self.create_inner::<GSPEC>(&create_input);
(exit, ret_gas, TransactOut::Create(bytes, address))
}
};
Expand Down Expand Up @@ -285,31 +291,27 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,

fn create_inner<SPEC: Spec>(
&mut self,
caller: H160,
scheme: CreateScheme,
value: U256,
init_code: Bytes,
gas_limit: u64,
inputs: &CreateInputs,
) -> (Return, Option<H160>, Gas, Bytes) {
let gas = Gas::new(gas_limit);
self.load_account(caller);
let gas = Gas::new(inputs.gas_limit);
self.load_account(inputs.caller);

// check depth of calls
if self.data.subroutine.depth() > interpreter::CALL_STACK_LIMIT {
return (Return::CallTooDeep, None, gas, Bytes::new());
}
// check balance of caller and value. Do this before increasing nonce
if self.balance(caller).0 < value {
if self.balance(inputs.caller).0 < inputs.value {
return (Return::OutOfFund, None, gas, Bytes::new());
}

// inc nonce of caller
let old_nonce = self.data.subroutine.inc_nonce(caller);
let old_nonce = self.data.subroutine.inc_nonce(inputs.caller);
// create address
let code_hash = H256::from_slice(Keccak256::digest(&init_code).as_slice());
let created_address = match scheme {
CreateScheme::Create => create_address(caller, old_nonce),
CreateScheme::Create2 { salt } => create2_address(caller, code_hash, salt),
let code_hash = H256::from_slice(Keccak256::digest(&inputs.init_code).as_slice());
let created_address = match inputs.scheme {
CreateScheme::Create => create_address(inputs.caller, old_nonce),
CreateScheme::Create2 { salt } => create2_address(inputs.caller, code_hash, salt),
};
let ret = Some(created_address);

Expand All @@ -330,11 +332,12 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
}

// transfer value to contract address
if let Err(e) = self
.data
.subroutine
.transfer(caller, created_address, value, self.data.db)
{
if let Err(e) = self.data.subroutine.transfer(
inputs.caller,
created_address,
inputs.value,
self.data.db,
) {
self.data.subroutine.checkpoint_revert(checkpoint);
return (e, ret, gas, Bytes::new());
}
Expand All @@ -343,8 +346,13 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
self.data.subroutine.inc_nonce(created_address);
}
// create new interp and execute init function
let contract =
Contract::new::<SPEC>(Bytes::new(), init_code, created_address, caller, value);
let contract = Contract::new::<SPEC>(
Bytes::new(),
inputs.init_code.clone(),
created_address,
inputs.caller,
inputs.value,
);
let mut interp =
Interpreter::new::<SPEC>(contract, gas.limit(), self.data.subroutine.depth());
if Self::INSPECT {
Expand Down Expand Up @@ -403,18 +411,10 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
}

#[allow(clippy::too_many_arguments)]
fn call_inner<SPEC: Spec>(
&mut self,
inputs: &CallInputs,
/*code_address: H160,
transfer: Transfer,
input: Bytes,
gas_limit: u64,
context: CallContext,*/
) -> (Return, Gas, Bytes) {
fn call_inner<SPEC: Spec>(&mut self, inputs: &CallInputs) -> (Return, Gas, Bytes) {
let mut gas = Gas::new(inputs.gas_limit);
// Load account and get code. Account is now hot.
let (code, _) = self.code(inputs.code_address);
let (code, _) = self.code(inputs.contract);

// check depth
if self.data.subroutine.depth() > interpreter::CALL_STACK_LIMIT {
Expand Down Expand Up @@ -446,7 +446,7 @@ impl<'a, GSPEC: Spec, DB: Database, const INSPECT: bool> EVMImpl<'a, GSPEC, DB,
}

// call precompiles
if let Some(precompile) = self.precompiles.get(&inputs.code_address) {
if let Some(precompile) = self.precompiles.get(&inputs.contract) {
let out = match precompile {
Precompile::Standard(fun) => fun(inputs.input.as_ref(), inputs.gas_limit),
Precompile::Custom(fun) => fun(inputs.input.as_ref(), inputs.gas_limit),
Expand Down Expand Up @@ -582,42 +582,17 @@ impl<'a, GSPEC: Spec, DB: Database + 'a, const INSPECT: bool> Host
.selfdestruct(address, target, self.data.db)
}

fn create<SPEC: Spec>(
&mut self,
caller: H160,
scheme: CreateScheme,
value: U256,
init_code: Bytes,
gas_limit: u64,
) -> (Return, Option<H160>, Gas, Bytes) {
fn create<SPEC: Spec>(&mut self, inputs: &CreateInputs) -> (Return, Option<H160>, Gas, Bytes) {
if INSPECT {
let (ret, address, gas, out) = self.inspector.create(
&mut self.data,
caller,
&scheme,
value,
&init_code,
gas_limit,
);
let (ret, address, gas, out) = self.inspector.create(&mut self.data, inputs);
if ret != Return::Continue {
return (ret, address, gas, out);
}
}
let (ret, address, gas, out) =
self.create_inner::<SPEC>(caller, scheme, value, init_code.clone(), gas_limit);
let (ret, address, gas, out) = self.create_inner::<SPEC>(inputs);
if INSPECT {
self.inspector.create_end(
&mut self.data,
caller,
&scheme,
value,
&init_code,
ret,
address,
gas_limit,
gas.remaining(),
&out,
);
self.inspector
.create_end(&mut self.data, inputs, ret, address, gas, &out);
}
(ret, address, gas, out)
}
Expand Down Expand Up @@ -692,15 +667,7 @@ pub trait Host {
/// Mark an address to be deleted, with funds transferred to target.
fn selfdestruct(&mut self, address: H160, target: H160) -> SelfDestructResult;
/// Invoke a create operation.
fn create<SPEC: Spec>(
&mut self,
caller: H160,
scheme: CreateScheme,
value: U256,
init_code: Bytes,
gas: u64,
) -> (Return, Option<H160>, Gas, Bytes);

fn create<SPEC: Spec>(&mut self, inputs: &CreateInputs) -> (Return, Option<H160>, Gas, Bytes);
/// Invoke a call operation.
fn call<SPEC: Spec>(&mut self, input: &CallInputs) -> (Return, Gas, Bytes);
}
32 changes: 8 additions & 24 deletions crates/revm/src/inspector.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use bytes::Bytes;
use primitive_types::{H160, U256};
use primitive_types::H160;

use crate::{
evm_impl::EVMData, CreateScheme, Database, Gas, Interpreter, Return, CallInputs,
evm_impl::EVMData, Database, Gas, Interpreter, Return, CallInputs, CreateInputs,
};
use auto_impl::auto_impl;

Expand Down Expand Up @@ -68,25 +68,17 @@ pub trait Inspector<DB: Database> {
fn create(
&mut self,
data: &mut EVMData<'_, DB>,
caller: H160,
scheme: &CreateScheme,
value: U256,
init_code: &Bytes,
gas_limit: u64,
inputs: &CreateInputs,
) -> (Return, Option<H160>, Gas, Bytes);

#[allow(clippy::too_many_arguments)]
fn create_end(
&mut self,
data: &mut EVMData<'_, DB>,
caller: H160,
scheme: &CreateScheme,
value: U256,
init_code: &Bytes,
inputs: &CreateInputs,
ret: Return,
address: Option<H160>,
gas_limit: u64,
remaining_gas: u64,
remaining_gas: Gas,
out: &Bytes,
);

Expand Down Expand Up @@ -168,26 +160,18 @@ impl<DB: Database> Inspector<DB> for NoOpInspector {
fn create(
&mut self,
_data: &mut EVMData<'_, DB>,
_caller: H160,
_scheme: &CreateScheme,
_value: U256,
_init_code: &Bytes,
_gas_limit: u64,
_inputs: &CreateInputs,
) -> (Return, Option<H160>, Gas, Bytes) {
(Return::Continue, None, Gas::new(0), Bytes::new())
}

fn create_end(
&mut self,
_data: &mut EVMData<'_, DB>,
_caller: H160,
_scheme: &CreateScheme,
_value: U256,
_init_code: &Bytes,
_inputs: &CreateInputs,
_ret: Return,
_address: Option<H160>,
_gas_limit: u64,
_remaining_gas: u64,
_remaining_gas: Gas,
_out: &Bytes,
) {
}
Expand Down
Loading

0 comments on commit b092da0

Please sign in to comment.