diff --git a/src/evm/executive.rs b/src/evm/executive.rs index 616eacd56..9173c4116 100644 --- a/src/evm/executive.rs +++ b/src/evm/executive.rs @@ -6,9 +6,9 @@ use state::*; use env_info::*; use engine::*; use transaction::*; -use evm::VmFactory; +use evm::{VmFactory, ExtFace, Ext, RuntimeData}; -fn contract_address(address: &Address, nonce: &U256) -> Address { +pub fn contract_address(address: &Address, nonce: &U256) -> Address { let mut stream = RlpStream::new_list(2); stream.append(address); stream.append(nonce); @@ -23,16 +23,16 @@ pub struct Executive<'a> { state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, - level: usize + depth: usize } impl<'a> Executive<'a> { - pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, level: usize) -> Self { + pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, depth: usize) -> Self { Executive { state: state, info: info, engine: engine, - level: level + depth: depth } } @@ -57,9 +57,12 @@ impl<'a> Executive<'a> { } fn create(&mut self, sender: &Address, endowment: &U256, gas_price: &U256, gas: &U256, init: &[u8], origin: &Address) -> ExecutiveResult { - let _new_address = contract_address(&sender, &(self.state.nonce(sender) - U256::one())); - let _evm = VmFactory::create(); - + let new_address = contract_address(&sender, &(self.state.nonce(sender) - U256::one())); + let mut ext = Ext::new(self.state, self.info, new_address, self.depth); + let data = RuntimeData::new(); + // TODO: init runtime data + let evm = VmFactory::create(); + evm.exec(data, &mut ext); ExecutiveResult::Ok } } diff --git a/src/evm/ext.rs b/src/evm/ext.rs index a5e7f3c2f..3b709ee44 100644 --- a/src/evm/ext.rs +++ b/src/evm/ext.rs @@ -42,11 +42,11 @@ pub trait ExtFace { /// Creates new contract. /// Returns new contract address and gas used. - fn create(&self, _gas: u64, _endowment: &U256, _code: &[u8]) -> (Address, u64); + fn create(&self, gas: u64, endowment: &U256, code: &[u8]) -> (Address, u64); /// Calls existing contract. /// Returns call output and gas used. - fn call(&self, _gas: u64, _call_gas: u64, _receive_address: &Address, _value: &U256, _data: &[u8], _code_address: &Address) -> Option<(Vec, u64)>; + fn call(&self, gas: u64, call_gas: u64, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address) -> Option<(Vec, u64)>; /// Returns code at given address fn extcode(&self, address: &Address) -> Vec; @@ -68,41 +68,38 @@ pub trait ExtFace { /// /// fn main() { /// let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); -/// let mut data = RuntimeData::new(); -/// let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address); +/// let mut state = State::new_temp(); +/// let info = EnvInfo::new(); +/// let ext = Ext::new(&mut state, &info, address); /// } /// ``` -pub struct Ext { - info: EnvInfo, - state: State, +pub struct Ext<'a> { + state: &'a mut State, + info: &'a EnvInfo, address: Address, - substate: SubState + substate: SubState, + depth: usize } -impl Ext { +impl<'a> Ext<'a> { /// Creates new evm environment object with backing state. - pub fn new(info: EnvInfo, state: State, address: Address) -> Ext { + pub fn new(state: &'a mut State, info: &'a EnvInfo, address: Address, depth: usize) -> Self { Ext { - info: info, state: state, + info: info, address: address, - substate: SubState::new() + substate: SubState::new(), + depth: depth } } - /// Returns state - // not sure if this is the best solution, but seems to be the easiest one, mk - pub fn state(&self) -> &State { - &self.state - } - - /// Returns substate + /// Returns substate logs. pub fn logs(&self) -> &[LogEntry] { &self.substate.logs } } -impl ExtFace for Ext { +impl<'a> ExtFace for Ext<'a> { fn sload(&self, key: &H256) -> H256 { self.state.storage_at(&self.address, key) } diff --git a/src/evm/jit.rs b/src/evm/jit.rs index 8b9e344c0..f8bb42fa0 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -321,10 +321,15 @@ mod tests { data.gas = 0x174876e800; data.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap(); - let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); - let evm = JitEvm; - assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); - let state = ext.state(); + let mut state = State::new_temp(); + let info = EnvInfo::new(); + + { + let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let evm = JitEvm; + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + } + assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe").unwrap()); } @@ -337,10 +342,15 @@ mod tests { data.gas = 0x174876e800; data.code = "6000600020600055".from_hex().unwrap(); - let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); - let evm = JitEvm; - assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); - let state = ext.state(); + let mut state = State::new_temp(); + let info = EnvInfo::new(); + + { + let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let evm = JitEvm; + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + } + assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").unwrap()); } @@ -353,10 +363,15 @@ mod tests { data.gas = 0x174876e800; data.code = "6005600420600055".from_hex().unwrap(); - let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); - let evm = JitEvm; - assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); - let state = ext.state(); + let mut state = State::new_temp(); + let info = EnvInfo::new(); + + { + let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let evm = JitEvm; + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + } + assert_eq!(state.storage_at(&address, &H256::new()), H256::from_str("c41589e7559804ea4a2080dad19d876a024ccb05117835447d72ce08c1d020ec").unwrap()); } @@ -370,10 +385,15 @@ mod tests { data.gas = 0x174876e800; data.code = "32600055".from_hex().unwrap(); - let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); - let evm = JitEvm; - assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); - let state = ext.state(); + let mut state = State::new_temp(); + let info = EnvInfo::new(); + + { + let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let evm = JitEvm; + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + } + assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone()); } @@ -386,10 +406,15 @@ mod tests { data.gas = 0x174876e800; data.code = "33600055".from_hex().unwrap(); - let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); - let evm = JitEvm; - assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); - let state = ext.state(); + let mut state = State::new_temp(); + let info = EnvInfo::new(); + + { + let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let evm = JitEvm; + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + } + assert_eq!(Address::from(state.storage_at(&address, &H256::new())), address.clone()); } @@ -420,10 +445,14 @@ mod tests { let mut state = State::new_temp(); state.set_code(&address, address_code); state.set_code(&caller, caller_code); - let mut ext = Ext::new(EnvInfo::new(), state, caller.clone()); - let evm = JitEvm; - assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); - let state = ext.state(); + let info = EnvInfo::new(); + + { + let mut ext = Ext::new(&mut state, &info, caller.clone(), 0); + let evm = JitEvm; + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + } + assert_eq!(state.storage_at(&caller, &H256::new()), H256::from_str("6005600055000000000000000000000000000000000000000000000000000000").unwrap()); } @@ -439,10 +468,14 @@ mod tests { let mut state = State::new_temp(); state.add_balance(&address, &U256::from(0x10)); - let mut ext = Ext::new(EnvInfo::new(), state, address.clone()); - let evm = JitEvm; - assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); - let state = ext.state(); + let info = EnvInfo::new(); + + { + let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let evm = JitEvm; + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + } + assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0x10))); } @@ -455,7 +488,9 @@ mod tests { data.gas = 0x174876e800; data.code = "60006000a0".from_hex().unwrap(); - let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); + let mut state = State::new_temp(); + let info = EnvInfo::new(); + let mut ext = Ext::new(&mut state, &info, address.clone(), 0); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); let logs = ext.logs(); @@ -483,7 +518,9 @@ mod tests { data.gas = 0x174876e800; data.code = "60ff6000533360206000a1".from_hex().unwrap(); - let mut ext = Ext::new(EnvInfo::new(), State::new_temp(), address.clone()); + let mut state = State::new_temp(); + let info = EnvInfo::new(); + let mut ext = Ext::new(&mut state, &info, address.clone(), 0); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); let logs = ext.logs(); @@ -506,13 +543,17 @@ mod tests { data.gas = 0x174876e800; data.code = "600040600055".from_hex().unwrap(); + let mut state = State::new_temp(); let mut info = EnvInfo::new(); info.number = U256::one(); info.last_hashes.push(H256::from(address.clone())); - let mut ext = Ext::new(info, State::new_temp(), address.clone()); - let evm = JitEvm; - assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); - let state = ext.state(); + + { + let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let evm = JitEvm; + assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); + } + assert_eq!(state.storage_at(&address, &H256::new()), H256::from(address.clone())); } }