diff --git a/src/evm/evm.rs b/src/evm/evm.rs index 2beb80e45..faf156502 100644 --- a/src/evm/evm.rs +++ b/src/evm/evm.rs @@ -5,7 +5,7 @@ use evm::{EvmParams, Ext}; /// Evm errors. pub enum EvmError { - /// Returned when transaction execution run out of gas. + /// `OutOfGas` is returned when transaction execution runs out of gas. /// The state should be reverted to the state from before the /// transaction execution. But it does not mean that transaction /// was invalid. Balance still should be transfered and nonce diff --git a/src/evm/executive.rs b/src/evm/executive.rs index 9936b95cf..bde96c34d 100644 --- a/src/evm/executive.rs +++ b/src/evm/executive.rs @@ -503,20 +503,6 @@ mod tests { use null_engine::*; use std::ops::*; - struct TestEngine; - - impl TestEngine { - fn new() -> Self { - TestEngine - } - } - - impl Engine for TestEngine { - fn name(&self) -> &str { "TestEngine" } - fn spec(&self) -> &Spec { unimplemented!() } - fn evm_schedule(&self, _env_info: &EnvInfo) -> EvmSchedule { EvmSchedule::new_frontier() } - } - #[test] fn test_contract_address() { let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap(); @@ -538,12 +524,12 @@ mod tests { let mut state = State::new_temp(); state.add_balance(&sender, &U256::from(0x100u64)); let info = EnvInfo::new(); - let engine = TestEngine::new(); + let engine = NullEngine::new_boxed(ethereum::new_frontier()); let mut substate = Substate::new(); { - let mut ex = Executive::new(&mut state, &info, &engine); - assert_eq!(Executive::create(&mut ex, ¶ms, &mut substate), ExecutionResult::Ok); + let mut ex = Executive::new(&mut state, &info, engine.deref()); + let _res = ex.create(¶ms, &mut substate); } assert_eq!(state.storage_at(&address, &H256::new()), H256::from(&U256::from(0xf9u64))); @@ -565,12 +551,12 @@ mod tests { let mut state = State::new_temp(); state.add_balance(&sender, &U256::from(0x100u64)); let info = EnvInfo::new(); - let engine = TestEngine::new(); + let engine = NullEngine::new_boxed(ethereum::new_frontier()); let mut substate = Substate::new(); { - let mut ex = Executive::new(&mut state, &info, &engine); - assert_eq!(Executive::create(&mut ex, ¶ms, &mut substate), ExecutionResult::Ok); + let mut ex = Executive::new(&mut state, &info, engine.deref()); + let _res = ex.create(¶ms, &mut substate); } assert_eq!(state.storage_at(&address, &H256::new()), H256::from(next_address.clone())); @@ -612,13 +598,12 @@ mod tests { let mut state = State::new_temp(); state.init_code(&address, code.clone()); let info = EnvInfo::new(); - //let engine = TestEngine::new(); let engine = NullEngine::new_boxed(ethereum::new_frontier()); let mut substate = Substate::new(); { let mut ex = Executive::new(&mut state, &info, engine.deref()); - assert_eq!(Executive::call(&mut ex, ¶ms, &mut substate), ExecutionResult::Ok); + let _res = ex.call(¶ms, &mut substate, &mut []); } assert!(false); diff --git a/src/evm/jit.rs b/src/evm/jit.rs index f1e1b1bc3..e1c7a23df 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -210,8 +210,8 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { address: *mut evmjit::H256) { unsafe { match self.ext.create(*io_gas, &U256::from_jit(&*endowment), slice::from_raw_parts(init_beg, init_size as usize)) { - Some((addr, gas)) => { - *io_gas = gas; + Some((gas_left, addr)) => { + *io_gas = gas_left; *address = addr.into_jit(); }, None => () @@ -235,18 +235,16 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { &Address::from_jit(&*receive_address), &U256::from_jit(&*value), slice::from_raw_parts(in_beg, in_size as usize), - &Address::from_jit(&*code_address)); + &Address::from_jit(&*code_address), + slice::from_raw_parts_mut(out_beg, out_size as usize)); - if opt.is_none() { - return false; + match opt { + None => false, + Some(gas_left) => { + *io_gas = gas_left; + true + } } - - // TODO: fix this! - let (mut output, gas) = opt.unwrap(); - out_beg = output.as_mut_ptr(); - mem::forget(output); - *io_gas = gas; - true } } @@ -318,18 +316,15 @@ impl evm::Evm for JitEvm { let mut context = unsafe { evmjit::ContextHandle::new(data.into_jit(), &mut ext_handle) }; match context.exec() { - evmjit::ReturnCode::Stop => Ok(evm::EvmOutput::new(U256::from(context.gas_left()), None)), - evmjit::ReturnCode::Return => { - if context.output_data().len() as u64 * ext.schedule().create_data_gas as u64 > context.gas_left() { - return Err(evm::EvmError::OutOfGas); - } - - Ok(evm::EvmOutput::new(U256::from(context.gas_left()), Some(context.output_data().to_vec()))) + evmjit::ReturnCode::Stop => Ok(U256::from(context.gas_left())), + evmjit::ReturnCode::Return => match ext.ret(context.gas_left(), context.output_data()) { + Some(gas_left) => Ok(U256::from(gas_left)), + None => Err(evm::EvmError::OutOfGas) }, evmjit::ReturnCode::Suicide => { // what if there is a suicide and we run out of gas just after? ext.suicide(); - Ok(evm::EvmOutput::new(U256::from(context.gas_left()), None)) + Ok(U256::from(context.gas_left())) }, evmjit::ReturnCode::OutOfGas => Err(evm::EvmError::OutOfGas), _err => Err(evm::EvmError::Internal) @@ -408,7 +403,7 @@ mod tests { let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); @@ -432,7 +427,7 @@ mod tests { let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop {}); @@ -456,7 +451,7 @@ mod tests { let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop {}); @@ -481,7 +476,7 @@ mod tests { let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop {}); @@ -506,7 +501,7 @@ mod tests { let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop {}); @@ -547,7 +542,7 @@ mod tests { let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop {}); @@ -573,7 +568,7 @@ mod tests { let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop {}); @@ -595,7 +590,7 @@ mod tests { let engine = TestEngine::new(); let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop {}); @@ -630,7 +625,7 @@ mod tests { let engine = TestEngine::new(); let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop {}); @@ -662,7 +657,7 @@ mod tests { let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop {}); @@ -688,7 +683,7 @@ mod tests { let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate, OutputPolicy::InitContract); let evm = JitEvm; let _res = evm.exec(¶ms, &mut ext); //assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop {}); diff --git a/src/evm/mod.rs b/src/evm/mod.rs index 3e3b7ffcb..84345f070 100644 --- a/src/evm/mod.rs +++ b/src/evm/mod.rs @@ -13,5 +13,6 @@ pub use self::evm::{Evm, EvmError, EvmResult}; pub use self::ext::{Ext}; pub use self::logentry::LogEntry; pub use self::vmfactory::VmFactory; -pub use self::executive::{Executive, ExecutionResult, Externalities, Substate}; +// TODO: reduce this to absolutely necessary things +pub use self::executive::{Executive, ExecutionResult, Externalities, Substate, OutputPolicy}; pub use self::params::EvmParams;