diff --git a/src/evm/evm.rs b/src/evm/evm.rs index d53adcf39..7b1997733 100644 --- a/src/evm/evm.rs +++ b/src/evm/evm.rs @@ -1,6 +1,6 @@ //! Evm interface. -use evm::Ext; +use evm::{EvmParams, Ext}; #[derive(Debug, Eq, PartialEq)] pub enum ReturnCode { @@ -12,5 +12,5 @@ pub enum ReturnCode { } pub trait Evm { - fn exec(&self, ext: &mut Ext) -> ReturnCode; + fn exec(&self, params: &EvmParams, ext: &mut Ext) -> ReturnCode; } diff --git a/src/evm/executive.rs b/src/evm/executive.rs index 1780f7027..dae41bf5f 100644 --- a/src/evm/executive.rs +++ b/src/evm/executive.rs @@ -1,3 +1,4 @@ +use std::mem; use util::hash::*; use util::uint::*; use util::rlp::*; @@ -7,7 +8,7 @@ use state::*; use env_info::*; use engine::*; use transaction::*; -use evm::{VmFactory, Ext, LogEntry, EvmParams, ParamsKind, ReturnCode}; +use evm::{VmFactory, Ext, LogEntry, EvmParams, ReturnCode}; /// Returns new address created from address and given nonce. pub fn contract_address(address: &Address, nonce: &U256) -> Address { @@ -29,95 +30,78 @@ pub struct Executive<'a> { info: &'a EnvInfo, engine: &'a Engine, depth: usize, - params: EvmParams, - - logs: Vec, - refunds: U256, } impl<'a> Executive<'a> { - pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, t: &Transaction) -> Self { - // TODO: validate nonce ? - - let sender = t.sender(); - - let params = match t.kind() { - TransactionKind::ContractCreation => EvmParams { - address: contract_address(&sender, &t.nonce), - sender: sender.clone(), - origin: sender.clone(), - gas: t.gas, - gas_price: t.gas_price, - value: t.value, - code: t.data.clone(), - data: vec![], - kind: ParamsKind::Create - }, - TransactionKind::MessageCall => EvmParams { - address: t.to.clone().unwrap(), - sender: sender.clone(), - origin: sender.clone(), - gas: t.gas, - gas_price: t.gas_price, - value: t.value, - code: state.code(&t.to.clone().unwrap()).unwrap_or(vec![]), - data: t.data.clone(), - kind: ParamsKind::Call - } - }; - - Executive::new_from_params(state, info, engine, params) + pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine) -> Self { + Executive::new_with_depth(state, info, engine, 0) } - pub fn new_from_params(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, params: EvmParams) -> Self { + fn from_parent(e: &'a mut Externalities) -> Self { + Executive::new_with_depth(e.state, e.info, e.engine, e.depth + 1) + } + + fn new_with_depth(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, depth: usize) -> Self { Executive { state: state, info: info, engine: engine, - depth: 0, - params: params, - logs: vec![], - refunds: U256::zero(), + depth: depth, } } - fn from_parent(e: &'a mut Executive, params: EvmParams) -> Self { - Executive { - state: e.state, - info: e.info, - engine: e.engine, - depth: e.depth + 1, - params: params, - logs: vec![], - refunds: U256::zero(), - } - } - - pub fn exec(&mut self) -> ExecutiveResult { + pub fn transact(e: &mut Executive<'a>, t: &Transaction) -> ExecutiveResult { // TODO: validate that we have enough funds + // TODO: validate nonce ? + + let sender = t.sender(); - match &self.params.kind() { - &ParamsKind::Call => { - self.state.inc_nonce(&self.params.address); - self.call() + match t.kind() { + TransactionKind::ContractCreation => { + let params = EvmParams { + address: contract_address(&sender, &t.nonce), + sender: sender.clone(), + origin: sender.clone(), + gas: t.gas, + gas_price: t.gas_price, + value: t.value, + code: t.data.clone(), + data: vec![], + }; + e.state.inc_nonce(¶ms.address); + unimplemented!() + //Executive::call(e, ¶ms) }, - &ParamsKind::Create => self.create() + TransactionKind::MessageCall => { + let params = EvmParams { + address: t.to.clone().unwrap(), + sender: sender.clone(), + origin: sender.clone(), + gas: t.gas, + gas_price: t.gas_price, + value: t.value, + code: e.state.code(&t.to.clone().unwrap()).unwrap_or(vec![]), + data: t.data.clone(), + }; + e.state.inc_nonce(¶ms.address); + Executive::create(e, ¶ms) + } } } - fn call(&mut self) -> ExecutiveResult { + fn call(e: &mut Executive<'a>, p: &EvmParams) -> ExecutiveResult { + //let _ext = Externalities::from_executive(e, &p); ExecutiveResult::Ok } - - fn create(&mut self) -> ExecutiveResult { - self.state.inc_nonce(&self.params.sender); + fn create(e: &mut Executive<'a>, params: &EvmParams) -> ExecutiveResult { //self.state.require_or_from(&self.params.address, false, ||Account::new_contract(U256::from(0))); - self.state.transfer_balance(&self.params.sender, &self.params.address, &self.params.value); + e.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.value); + let mut ext = Externalities::new(e.state, e.info, e.engine, e.depth, params); + let code = { let evm = VmFactory::create(); - // TODO: valdidate that exec returns proper code - evm.exec(self) + evm.exec(¶ms, &mut ext) }; match code { @@ -139,17 +123,43 @@ impl<'a> Executive<'a> { } } } +} +pub struct Externalities<'a> { + state: &'a mut State, + info: &'a EnvInfo, + engine: &'a Engine, + depth: usize, + params: &'a EvmParams, + logs: Vec, + refunds: U256 +} + +impl<'a> Externalities<'a> { + pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, depth: usize, params: &'a EvmParams) -> Self { + Externalities { + state: state, + info: info, + engine: engine, + depth: depth, + params: params, + logs: vec![], + refunds: U256::zero() + } + } + + // TODO: figure out how to use this function + // so the lifetime checker is satisfied + //pub fn from_executive(e: &mut Executive<'a>, params: &EvmParams) -> Self { + //Externalities::new(e.state, e.info, e.engine, e.depth, params) + //} + pub fn logs(&self) -> &[LogEntry] { &self.logs } } -impl<'a> Ext for Executive<'a> { - fn params(&self) -> &EvmParams { - &self.params - } - +impl<'a> Ext for Externalities<'a> { fn sload(&self, key: &H256) -> H256 { self.state.storage_at(&self.params.address, key) } @@ -189,12 +199,10 @@ impl<'a> Ext for Executive<'a> { value: endowment.clone(), code: code.to_vec(), data: vec![], - kind: ParamsKind::Create }; - println!("address: {:?}", address); - println!("code: {:?}", code); - let mut ex = Executive::from_parent(self, params); - let res = ex.create(); + let mut ex = Executive::from_parent(self); + ex.state.inc_nonce(&address); + let res = Executive::create(&mut ex, ¶ms); println!("res: {:?}", res); (address, gas) } @@ -213,12 +221,11 @@ impl<'a> Ext for Executive<'a> { value: value.clone(), code: self.state.code(code_address).unwrap_or(vec![]), data: data.to_vec(), - kind: ParamsKind::Call }; { - let mut ex = Executive::from_parent(self, params); - ex.call(); + let mut ex = Executive::from_parent(self); + Executive::call(&mut ex, ¶ms); unimplemented!(); } @@ -280,7 +287,7 @@ mod tests { fn test_executive() { let sender = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let address = contract_address(&sender, &U256::zero()); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.sender = sender.clone(); params.gas = U256::from(0x174876e800u64); @@ -292,8 +299,8 @@ mod tests { let engine = TestEngine::new(); { - let mut ex = Executive::new_from_params(&mut state, &info, &engine, params); - assert_eq!(ex.exec(), ExecutiveResult::Ok); + let mut ex = Executive::new(&mut state, &info, &engine); + assert_eq!(Executive::create(&mut ex, ¶ms), ExecutiveResult::Ok); } assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0xf9u64))); @@ -308,7 +315,7 @@ mod tests { let next_address = contract_address(&address, &U256::zero()); println!("address: {:?}", address); println!("next address: {:?}", next_address); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.sender = sender.clone(); params.origin = sender.clone(); @@ -320,8 +327,8 @@ mod tests { let engine = TestEngine::new(); { - let mut ex = Executive::new_from_params(&mut state, &info, &engine, params); - assert_eq!(ex.exec(), ExecutiveResult::Ok); + let mut ex = Executive::new(&mut state, &info, &engine); + assert_eq!(Executive::create(&mut ex, ¶ms), ExecutiveResult::Ok); } assert_eq!(state.storage_at(&address, &H256::new()), H256::from(next_address.clone())); diff --git a/src/evm/ext.rs b/src/evm/ext.rs index e97e177c0..926ce6728 100644 --- a/src/evm/ext.rs +++ b/src/evm/ext.rs @@ -3,12 +3,8 @@ use util::hash::*; use util::uint::*; use util::bytes::*; -use evm::EvmParams; pub trait Ext { - /// Returns evm params. - fn params(&self) -> &EvmParams; - /// Returns a value for given key. fn sload(&self, key: &H256) -> H256; diff --git a/src/evm/jit.rs b/src/evm/jit.rs index f35897b22..5e90ac396 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -301,12 +301,11 @@ impl From for evm::ReturnCode { pub struct JitEvm; impl evm::Evm for JitEvm { - fn exec(&self, ext: &mut evm::Ext) -> evm::ReturnCode { + fn exec(&self, params: &evm::EvmParams, ext: &mut evm::Ext) -> evm::ReturnCode { // Dirty hack. This is unsafe, but we interact with ffi, so it's justified. let ext_adapter: ExtAdapter<'static> = unsafe { ::std::mem::transmute(ExtAdapter::new(ext)) }; let mut ext_handle = evmjit::ExtHandle::new(ext_adapter); let mut data = RuntimeData::new(); - let params = ext.params(); data.gas = params.gas; data.gas_price = params.gas_price; data.call_data = params.data.clone(); @@ -315,6 +314,7 @@ impl evm::Evm for JitEvm { data.origin = params.origin.clone(); data.call_value = params.value; data.code = params.code.clone(); + println!("params.address: {:?}, params.code: {:?}", params.address, params.code); // TODO: data.coinbase = Address::new(); @@ -394,7 +394,7 @@ mod tests { #[test] fn test_ext_add() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.gas = U256::from(0x174876e800u64); params.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap(); @@ -404,9 +404,9 @@ mod tests { let engine = TestEngine::new(); { - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); } assert_eq!(state.storage_at(&address, &H256::new()), @@ -416,7 +416,7 @@ mod tests { #[test] fn test_ext_sha3_0() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.gas = U256::from(0x174876e800u64); params.code = "6000600020600055".from_hex().unwrap(); @@ -426,9 +426,9 @@ mod tests { let engine = TestEngine::new(); { - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); } assert_eq!(state.storage_at(&address, &H256::new()), @@ -438,7 +438,7 @@ mod tests { #[test] fn test_ext_sha3_1() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.gas = U256::from(0x174876e800u64); params.code = "6005600420600055".from_hex().unwrap(); @@ -448,9 +448,9 @@ mod tests { let engine = TestEngine::new(); { - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); } assert_eq!(state.storage_at(&address, &H256::new()), @@ -460,7 +460,7 @@ mod tests { #[test] fn test_origin() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.origin = address.clone(); params.gas = U256::from(0x174876e800u64); @@ -471,9 +471,9 @@ mod tests { let engine = TestEngine::new(); { - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); } assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone()); @@ -482,7 +482,7 @@ mod tests { #[test] fn test_sender() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.sender = address.clone(); params.gas = U256::from(0x174876e800u64); @@ -494,9 +494,9 @@ mod tests { let engine = TestEngine::new(); { - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); } assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone()); @@ -519,7 +519,7 @@ mod tests { let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let address_code = "333b60006000333c600051600055".from_hex().unwrap(); let sender_code = "6005600055".from_hex().unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.sender = sender.clone(); params.origin = sender.clone(); @@ -533,9 +533,9 @@ mod tests { let engine = TestEngine::new(); { - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); } assert_eq!(state.storage_at(&address, &H256::new()), @@ -545,7 +545,7 @@ mod tests { #[test] fn test_balance() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.sender = address.clone(); params.gas = U256::from(0x174876e800u64); @@ -557,9 +557,9 @@ mod tests { let engine = TestEngine::new(); { - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); } assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0x10))); @@ -568,7 +568,7 @@ mod tests { #[test] fn test_empty_log() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.gas = U256::from(0x174876e800u64); params.code = "60006000a0".from_hex().unwrap(); @@ -576,9 +576,9 @@ mod tests { let mut state = State::new_temp(); let info = EnvInfo::new(); let engine = TestEngine::new(); - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); let logs = ext.logs(); assert_eq!(logs.len(), 1); let log = &logs[0]; @@ -598,7 +598,7 @@ mod tests { // a1 - log with 1 topic let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.sender = address.clone(); params.gas = U256::from(0x174876e800u64); @@ -607,9 +607,9 @@ mod tests { let mut state = State::new_temp(); let info = EnvInfo::new(); let engine = TestEngine::new(); - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); let logs = ext.logs(); assert_eq!(logs.len(), 1); let log = &logs[0]; @@ -624,7 +624,7 @@ mod tests { #[test] fn test_blockhash() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.gas = U256::from(0x174876e800u64); params.code = "600040600055".from_hex().unwrap(); @@ -636,9 +636,9 @@ mod tests { let engine = TestEngine::new(); { - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); } assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone())); @@ -647,7 +647,7 @@ mod tests { #[test] fn test_calldataload() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); - let mut params = EvmParams::new_create(); + let mut params = EvmParams::new(); params.address = address.clone(); params.gas = U256::from(0x174876e800u64); params.code = "600135600055".from_hex().unwrap(); @@ -660,9 +660,9 @@ mod tests { let engine = TestEngine::new(); { - let mut ext = Executive::new_from_params(&mut state, &info, &engine, params); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); let evm = JitEvm; - assert_eq!(evm.exec(&mut ext), ReturnCode::Stop); + assert_eq!(evm.exec(¶ms, &mut ext), ReturnCode::Stop); } assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23").unwrap()); diff --git a/src/evm/mod.rs b/src/evm/mod.rs index c5391ae5b..c4a310788 100644 --- a/src/evm/mod.rs +++ b/src/evm/mod.rs @@ -13,5 +13,5 @@ pub use self::evm::{Evm, ReturnCode}; pub use self::ext::{Ext}; pub use self::logentry::LogEntry; pub use self::vmfactory::VmFactory; -pub use self::executive::{Executive, ExecutiveResult}; -pub use self::params::{EvmParams, ParamsKind}; +pub use self::executive::{Executive, ExecutiveResult, Externalities}; +pub use self::params::EvmParams; diff --git a/src/evm/params.rs b/src/evm/params.rs index d2c8cf88e..9fee7d42d 100644 --- a/src/evm/params.rs +++ b/src/evm/params.rs @@ -2,12 +2,6 @@ use util::hash::*; use util::uint::*; use util::bytes::*; -#[derive(Eq, PartialEq, Clone)] -pub enum ParamsKind { - Create, - Call -} - #[derive(Clone)] pub struct EvmParams { pub address: Address, @@ -17,12 +11,11 @@ pub struct EvmParams { pub gas_price: U256, pub value: U256, pub code: Bytes, - pub data: Bytes, - pub kind: ParamsKind + pub data: Bytes } impl EvmParams { - pub fn new(kind: ParamsKind) -> EvmParams { + pub fn new() -> EvmParams { EvmParams { address: Address::new(), sender: Address::new(), @@ -32,20 +25,6 @@ impl EvmParams { value: U256::zero(), code: vec![], data: vec![], - kind: kind } } - - pub fn new_call() -> EvmParams { - EvmParams::new(ParamsKind::Call) - } - - pub fn new_create() -> EvmParams { - EvmParams::new(ParamsKind::Create) - } - - pub fn kind(&self) -> ParamsKind { - //TODO - ParamsKind::Create - } }