diff --git a/src/evm/jit.rs b/src/evm/jit.rs index c8a3c4b66..9aee82e34 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -220,18 +220,18 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { // check if balance is sufficient and we are not too deep if self.ext.balance(&self.address) >= value && self.ext.depth() < self.ext.schedule().max_depth { - if let evm::ContractCreateResult::Created(new_address, gas_left) = self.ext.create(&gas, &value, code) { - unsafe { - *io_gas = gas_left.low_u64(); + match self.ext.create(&gas, &value, code) { + evm::ContractCreateResult::Created(new_address, gas_left) => unsafe { *address = new_address.into_jit(); - return; + *io_gas = gas_left.low_u64(); + }, + evm::ContractCreateResult::Failed => unsafe { + *address = Address::new().into_jit(); + *io_gas = 0; } } - } - - unsafe { - *io_gas = 0; - *address = Address::new().into_jit(); + } else { + unsafe { *address = Address::new().into_jit(); } } } diff --git a/src/evm/tests.rs b/src/evm/tests.rs index 8a0ddfc3f..1a688299f 100644 --- a/src/evm/tests.rs +++ b/src/evm/tests.rs @@ -1,6 +1,6 @@ use common::*; use evm; -use evm::{Ext, Schedule, Factory}; +use evm::{Ext, Schedule, Factory, ContractCreateResult, MessageCallResult}; struct FakeLogEntry { topics: Vec, @@ -30,7 +30,7 @@ impl Ext for FakeExt { self.store.get(key).unwrap_or(&H256::new()).clone() } - fn set_storage_at(&mut self, key: H256, value: H256) { + fn set_storage(&mut self, key: H256, value: H256) { self.store.insert(key, value); } @@ -46,18 +46,17 @@ impl Ext for FakeExt { self.blockhashes.get(number).unwrap_or(&H256::new()).clone() } - fn create(&mut self, _gas: &U256, _value: &U256, _code: &[u8]) -> (U256, Option
) { + fn create(&mut self, _gas: &U256, _value: &U256, _code: &[u8]) -> ContractCreateResult { unimplemented!(); } fn call(&mut self, _gas: &U256, - _call_gas: &U256, - _receive_address: &Address, + _address: &Address, _value: &U256, _data: &[u8], _code_address: &Address, - _output: &mut [u8]) -> result::Result<(U256, bool), evm::Error> { + _output: &mut [u8]) -> MessageCallResult { unimplemented!(); } @@ -91,6 +90,10 @@ impl Ext for FakeExt { fn depth(&self) -> usize { unimplemented!(); } + + fn add_sstore_refund(&mut self) { + unimplemented!(); + } } #[test] diff --git a/src/tests/executive.rs b/src/tests/executive.rs index bd8817bb9..32ed27d46 100644 --- a/src/tests/executive.rs +++ b/src/tests/executive.rs @@ -4,7 +4,7 @@ use executive::*; use spec::*; use engine::*; use evm; -use evm::{Schedule, Ext, Factory}; +use evm::{Schedule, Ext, Factory, ContractCreateResult, MessageCallResult}; use ethereum; use externalities::*; use substate::*; @@ -61,8 +61,8 @@ impl<'a> Ext for TestExt<'a> { self.ext.storage_at(key) } - fn set_storage_at(&mut self, key: H256, value: H256) { - self.ext.set_storage_at(key, value) + fn set_storage(&mut self, key: H256, value: H256) { + self.ext.set_storage(key, value) } fn exists(&self, address: &Address) -> bool { @@ -77,60 +77,31 @@ impl<'a> Ext for TestExt<'a> { self.ext.blockhash(number) } - fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> (U256, Option
) { - // in call and create we need to check if we exited with insufficient balance or max limit reached. - // in case of reaching max depth, we should store callcreates. Otherwise, ignore. - let res = self.ext.create(gas, value, code); - let ext = &self.ext; - match res { - // just record call create - (gas_left, Some(address)) => { - self.callcreates.push(CallCreate { - data: code.to_vec(), - destination: Some(address.clone()), - _gas_limit: *gas, - value: *value - }); - (gas_left, Some(address)) - }, - // creation failed only due to reaching max_depth - (gas_left, None) if ext.state.balance(&ext.params.address) >= *value => { - self.callcreates.push(CallCreate { - data: code.to_vec(), - // callcreate test does not need an address - destination: None, - _gas_limit: *gas, - value: *value - }); - let address = contract_address(&ext.params.address, &ext.state.nonce(&ext.params.address)); - (gas_left, Some(address)) - }, - other => other - } + fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult { + let address = contract_address(&self.ext.params.address, &self.ext.state.nonce(&self.ext.params.address)); + self.callcreates.push(CallCreate { + data: code.to_vec(), + destination: None, + _gas_limit: *gas, + value: *value + }); + ContractCreateResult::Created(address, *gas) } fn call(&mut self, gas: &U256, - call_gas: &U256, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address, - output: &mut [u8]) -> Result<(U256, bool), evm::Error> { - let res = self.ext.call(gas, call_gas, receive_address, value, data, code_address, output); - let ext = &self.ext; - if let &Ok((gas_left, _)) = &res { - if ext.state.balance(&ext.params.address) >= *value { - self.callcreates.push(CallCreate { - data: data.to_vec(), - destination: Some(receive_address.clone()), - _gas_limit: *call_gas, - value: *value - }); - return Ok((gas_left, true)) - } - } - res + output: &mut [u8]) -> MessageCallResult { + self.callcreates.push(CallCreate { + data: data.to_vec(), + destination: Some(receive_address.clone()), + _gas_limit: *gas, + value: *value + }); + MessageCallResult::Success(*gas) } fn extcode(&self, address: &Address) -> Vec { @@ -158,7 +129,11 @@ impl<'a> Ext for TestExt<'a> { } fn depth(&self) -> usize { - self.ext.depth() + 0 + } + + fn add_sstore_refund(&mut self) { + self.ext.add_sstore_refund() } } @@ -200,7 +175,7 @@ fn do_json_test(json_data: &[u8]) -> Vec { info.timestamp = xjson!(&env["currentTimestamp"]); }); - let engine = TestEngine::new(0); + let engine = TestEngine::new(1); // params let mut params = ActionParams::new();