diff --git a/src/evm/executive.rs b/src/evm/executive.rs index 9173c4116..86df11ebc 100644 --- a/src/evm/executive.rs +++ b/src/evm/executive.rs @@ -58,11 +58,20 @@ 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 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); + + { + let mut ext = Ext::new(self.state, self.info, self.engine, self.depth, new_address.clone()); + let mut data = RuntimeData::new(); + + // TODO: init runtime data + data.gas = *gas; + data.gas_price = *gas_price; + + let evm = VmFactory::create(); + evm.exec(data, &mut ext); + } + + self.state.transfer_balance(sender, &new_address, endowment); ExecutiveResult::Ok } } diff --git a/src/evm/ext.rs b/src/evm/ext.rs index 3b709ee44..854e97101 100644 --- a/src/evm/ext.rs +++ b/src/evm/ext.rs @@ -7,6 +7,7 @@ use util::bytes::*; use state::*; use env_info::*; use evm::LogEntry; +use engine::*; struct SubState { // any accounts that have suicided @@ -76,20 +77,22 @@ pub trait ExtFace { pub struct Ext<'a> { state: &'a mut State, info: &'a EnvInfo, + engine: &'a Engine, + depth: usize, address: Address, - substate: SubState, - depth: usize + substate: SubState } impl<'a> Ext<'a> { /// Creates new evm environment object with backing state. - pub fn new(state: &'a mut State, info: &'a EnvInfo, address: Address, depth: usize) -> Self { + pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, depth: usize, address: Address) -> Self { Ext { state: state, info: info, + engine: engine, + depth: depth, address: address, substate: SubState::new(), - depth: depth } } diff --git a/src/evm/jit.rs b/src/evm/jit.rs index f8bb42fa0..d8627107c 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -97,8 +97,10 @@ impl IntoJit for Address { impl IntoJit for evm::RuntimeData { fn into_jit(self) -> evmjit::RuntimeDataHandle { let mut data = evmjit::RuntimeDataHandle::new(); - data.gas = self.gas as i64; - data.gas_price = self.gas_price as i64; + assert!(self.gas <= U256::from(u64::max_value()), "evmjit gas must be lower than 2 ^ 64"); + assert!(self.gas_price <= U256::from(u64::max_value()), "evmjit gas_price must be lower than 2 ^ 64"); + data.gas = self.gas.low_u64() as i64; + data.gas_price = self.gas_price.low_u64() as i64; data.call_data = self.call_data.as_ptr(); data.call_data_size = self.call_data.len() as u64; mem::forget(self.call_data); @@ -282,6 +284,27 @@ mod tests { use super::*; use state::*; use env_info::*; + use engine::*; + use evm_schedule::*; + use spec::*; + + struct TestEngine { + spec: Spec + } + + impl TestEngine { + fn new() -> Self { + TestEngine { + spec: Spec::frontier() + } + } + } + + impl Engine for TestEngine { + fn name(&self) -> &str { "TestEngine" } + fn spec(&self) -> &Spec { &self.spec } + fn evm_schedule(&self, _env_info: &EnvInfo) -> EvmSchedule { EvmSchedule::new_frontier() } + } #[test] fn test_to_and_from_u256() { @@ -318,14 +341,15 @@ mod tests { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let mut data = RuntimeData::new(); data.address = address.clone(); - data.gas = 0x174876e800; + data.gas = U256::from(0x174876e800u64); data.code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap(); let mut state = State::new_temp(); let info = EnvInfo::new(); + let engine = TestEngine::new(); { - let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let mut ext = Ext::new(&mut state, &info, &engine, 0, address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); } @@ -339,14 +363,15 @@ mod tests { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let mut data = RuntimeData::new(); data.address = address.clone(); - data.gas = 0x174876e800; + data.gas = U256::from(0x174876e800u64); data.code = "6000600020600055".from_hex().unwrap(); let mut state = State::new_temp(); let info = EnvInfo::new(); + let engine = TestEngine::new(); { - let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let mut ext = Ext::new(&mut state, &info, &engine, 0, address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); } @@ -360,14 +385,15 @@ mod tests { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); let mut data = RuntimeData::new(); data.address = address.clone(); - data.gas = 0x174876e800; + data.gas = U256::from(0x174876e800u64); data.code = "6005600420600055".from_hex().unwrap(); let mut state = State::new_temp(); let info = EnvInfo::new(); + let engine = TestEngine::new(); { - let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let mut ext = Ext::new(&mut state, &info, &engine, 0, address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); } @@ -382,14 +408,15 @@ mod tests { let mut data = RuntimeData::new(); data.address = address.clone(); data.origin = address.clone(); - data.gas = 0x174876e800; + data.gas = U256::from(0x174876e800u64); data.code = "32600055".from_hex().unwrap(); let mut state = State::new_temp(); let info = EnvInfo::new(); + let engine = TestEngine::new(); { - let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let mut ext = Ext::new(&mut state, &info, &engine, 0, address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); } @@ -403,14 +430,16 @@ mod tests { let mut data = RuntimeData::new(); data.address = address.clone(); data.caller = address.clone(); - data.gas = 0x174876e800; + data.gas = U256::from(0x174876e800u64); + data.code = "32600055".from_hex().unwrap(); data.code = "33600055".from_hex().unwrap(); let mut state = State::new_temp(); let info = EnvInfo::new(); + let engine = TestEngine::new(); { - let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let mut ext = Ext::new(&mut state, &info, &engine, 0, address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); } @@ -439,16 +468,17 @@ mod tests { data.address = address.clone(); data.caller = caller.clone(); data.origin = caller.clone(); - data.gas = 0x174876e800; + data.gas = U256::from(0x174876e800u64); data.code = address_code.clone(); let mut state = State::new_temp(); state.set_code(&address, address_code); state.set_code(&caller, caller_code); let info = EnvInfo::new(); + let engine = TestEngine::new(); { - let mut ext = Ext::new(&mut state, &info, caller.clone(), 0); + let mut ext = Ext::new(&mut state, &info, &engine, 0, caller.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); } @@ -463,15 +493,16 @@ mod tests { let mut data = RuntimeData::new(); data.address = address.clone(); data.caller = address.clone(); - data.gas = 0x174876e800; + data.gas = U256::from(0x174876e800u64); data.code = "3331600055".from_hex().unwrap(); let mut state = State::new_temp(); state.add_balance(&address, &U256::from(0x10)); let info = EnvInfo::new(); + let engine = TestEngine::new(); { - let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let mut ext = Ext::new(&mut state, &info, &engine, 0, address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); } @@ -485,12 +516,13 @@ mod tests { let mut data = RuntimeData::new(); data.address = address.clone(); data.caller = address.clone(); - data.gas = 0x174876e800; + data.gas = U256::from(0x174876e800u64); data.code = "60006000a0".from_hex().unwrap(); let mut state = State::new_temp(); let info = EnvInfo::new(); - let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let engine = TestEngine::new(); + let mut ext = Ext::new(&mut state, &info, &engine, 0, address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); let logs = ext.logs(); @@ -515,12 +547,13 @@ mod tests { let mut data = RuntimeData::new(); data.address = address.clone(); data.caller = address.clone(); - data.gas = 0x174876e800; + data.gas = U256::from(0x174876e800u64); data.code = "60ff6000533360206000a1".from_hex().unwrap(); let mut state = State::new_temp(); let info = EnvInfo::new(); - let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let engine = TestEngine::new(); + let mut ext = Ext::new(&mut state, &info, &engine, 0, address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); let logs = ext.logs(); @@ -540,16 +573,17 @@ mod tests { let mut data = RuntimeData::new(); data.address = address.clone(); data.caller = address.clone(); - data.gas = 0x174876e800; + data.gas = U256::from(0x174876e800u64); 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 engine = TestEngine::new(); { - let mut ext = Ext::new(&mut state, &info, address.clone(), 0); + let mut ext = Ext::new(&mut state, &info, &engine, 0, address.clone()); let evm = JitEvm; assert_eq!(evm.exec(data, &mut ext), ReturnCode::Stop); } diff --git a/src/evm/runtime_data.rs b/src/evm/runtime_data.rs index 01adb34a3..2090ba4bd 100644 --- a/src/evm/runtime_data.rs +++ b/src/evm/runtime_data.rs @@ -4,8 +4,8 @@ use util::hash::*; use util::uint::*; pub struct RuntimeData { - pub gas: u64, - pub gas_price: u64, + pub gas: U256, + pub gas_price: U256, pub call_data: Vec, pub address: Address, pub caller: Address, @@ -22,16 +22,16 @@ pub struct RuntimeData { impl RuntimeData { pub fn new() -> RuntimeData { RuntimeData { - gas: 0, - gas_price: 0, + gas: U256::zero(), + gas_price: U256::zero(), call_data: vec![], address: Address::new(), caller: Address::new(), origin: Address::new(), - call_value: U256::from(0), + call_value: U256::zero(), coinbase: Address::new(), - difficulty: U256::from(0), - gas_limit: U256::from(0), + difficulty: U256::zero(), + gas_limit: U256::zero(), number: 0, timestamp: 0, code: vec![] diff --git a/src/transaction.rs b/src/transaction.rs index 517926b40..c06c8a997 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -1,4 +1,3 @@ -use std::marker::PhantomData; use util::hash::*; use util::bytes::*; use util::uint::*;