diff --git a/src/evm/executive.rs b/src/evm/executive.rs index 95de150c5..f509ae4d1 100644 --- a/src/evm/executive.rs +++ b/src/evm/executive.rs @@ -40,6 +40,10 @@ impl Substate { } } + pub fn logs(&self) -> &[LogEntry] { + &self.logs + } + /// Appends another substate to this substate. fn accrue(&mut self, s: Substate) { self.suicides.extend(s.suicides.into_iter()); @@ -203,7 +207,7 @@ impl<'a> Executive<'a> { } /// Finalizes the transaction (does refunds and suicides). - fn finalize(&self, substate: Substate, gas: U256, gas_used: U256) { + fn finalize(&mut self, substate: Substate, gas: U256, gas_used: U256) { let schedule = self.engine.evm_schedule(self.info); // refunds from SSTORE nonzero -> zero @@ -214,7 +218,9 @@ impl<'a> Executive<'a> { let refund = cmp::min(sstore_refunds + suicide_refunds, (gas - gas_used) / U256::from(2)); // perform suicides - //self.state. + for address in substate.suicides.iter() { + self.state.kill_account(address); + } } } @@ -248,8 +254,8 @@ impl<'a> Ext for Externalities<'a> { } fn sstore(&mut self, key: H256, value: H256) { + // if SSTORE nonzero -> zero, increment refund count if value == H256::new() && self.state.storage_at(&self.params.address, &key) != H256::new() { - //self.substate.refunds_count = self.substate.refunds_count + U256::from(self.engine.evm_schedule(self.info).sstore_refund_gas); self.substate.refunds_count = self.substate.refunds_count + U256::one(); } self.state.set_storage(&self.params.address, key, value) @@ -269,9 +275,9 @@ impl<'a> Ext for Externalities<'a> { } } - fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> (Address, u64) { + fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> Option<(Address, u64)> { match self.state.balance(&self.params.address) >= *endowment && self.depth < 1024 { - false => (Address::new(), gas), + false => None, true => { let address = contract_address(&self.params.address, &self.state.nonce(&self.params.address)); let params = EvmParams { @@ -292,7 +298,7 @@ impl<'a> Ext for Externalities<'a> { println!("res: {:?}", res); } self.substate.accrue(substate); - (address, gas) + Some((address, gas)) } } } diff --git a/src/evm/ext.rs b/src/evm/ext.rs index cca353965..46dc47ec7 100644 --- a/src/evm/ext.rs +++ b/src/evm/ext.rs @@ -18,11 +18,14 @@ pub trait Ext { fn blockhash(&self, number: &U256) -> H256; /// Creates new contract. - /// Returns new contract address and gas used. - fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> (Address, u64); + /// If contract creation is successfull, + /// returns new contract address and gas used, + /// otherwise `None`. + fn create(&mut self, gas: u64, endowment: &U256, code: &[u8]) -> Option<(Address, u64)>; - /// Calls existing contract. - /// Returns call output and gas used. + /// Message call. + /// If call is successfull, returns call output and gas used, + /// otherwise `None`. fn call(&mut self, gas: u64, call_gas: u64, receive_address: &Address, value: &U256, data: &[u8], code_address: &Address) -> Option<(Vec, u64)>; /// Returns code at given address diff --git a/src/evm/jit.rs b/src/evm/jit.rs index 29defd33d..d15c8d3ee 100644 --- a/src/evm/jit.rs +++ b/src/evm/jit.rs @@ -208,9 +208,13 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { init_size: u64, address: *mut evmjit::H256) { unsafe { - let (addr, gas) = self.ext.create(*io_gas, &U256::from_jit(&*endowment), slice::from_raw_parts(init_beg, init_size as usize)); - *io_gas = gas; - *address = addr.into_jit(); + 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; + *address = addr.into_jit(); + }, + None => () + }; } } @@ -389,9 +393,10 @@ mod tests { let mut state = State::new_temp(); let info = EnvInfo::new(); let engine = TestEngine::new(); + let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); let evm = JitEvm; assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); } @@ -411,9 +416,10 @@ mod tests { let mut state = State::new_temp(); let info = EnvInfo::new(); let engine = TestEngine::new(); + let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); let evm = JitEvm; assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); } @@ -433,9 +439,10 @@ mod tests { let mut state = State::new_temp(); let info = EnvInfo::new(); let engine = TestEngine::new(); + let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); let evm = JitEvm; assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); } @@ -456,9 +463,10 @@ mod tests { let mut state = State::new_temp(); let info = EnvInfo::new(); let engine = TestEngine::new(); + let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); let evm = JitEvm; assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); } @@ -479,9 +487,10 @@ mod tests { let mut state = State::new_temp(); let info = EnvInfo::new(); let engine = TestEngine::new(); + let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); let evm = JitEvm; assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); } @@ -518,9 +527,10 @@ mod tests { state.init_code(&sender, sender_code); let info = EnvInfo::new(); let engine = TestEngine::new(); + let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); let evm = JitEvm; assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); } @@ -542,9 +552,10 @@ mod tests { state.add_balance(&address, &U256::from(0x10)); let info = EnvInfo::new(); let engine = TestEngine::new(); + let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); let evm = JitEvm; assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); } @@ -563,10 +574,13 @@ mod tests { let mut state = State::new_temp(); let info = EnvInfo::new(); let engine = TestEngine::new(); - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); - let evm = JitEvm; - assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); - let logs = ext.logs(); + let mut substate = Substate::new(); + { + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let evm = JitEvm; + assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); + } + let logs = substate.logs(); assert_eq!(logs.len(), 1); let log = &logs[0]; assert_eq!(log.address(), &address); @@ -594,10 +608,13 @@ mod tests { let mut state = State::new_temp(); let info = EnvInfo::new(); let engine = TestEngine::new(); - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); - let evm = JitEvm; - assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); - let logs = ext.logs(); + let mut substate = Substate::new(); + { + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); + let evm = JitEvm; + assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); + } + let logs = substate.logs(); assert_eq!(logs.len(), 1); let log = &logs[0]; assert_eq!(log.address(), &address); @@ -621,9 +638,10 @@ mod tests { info.number = U256::one(); info.last_hashes.push(H256::from(address.clone())); let engine = TestEngine::new(); + let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); let evm = JitEvm; assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); } @@ -645,9 +663,10 @@ mod tests { info.number = U256::one(); info.last_hashes.push(H256::from(address.clone())); let engine = TestEngine::new(); + let mut substate = Substate::new(); { - let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms); + let mut ext = Externalities::new(&mut state, &info, &engine, 0, ¶ms, &mut substate); let evm = JitEvm; assert_eq!(evm.exec(¶ms, &mut ext), EvmResult::Stop); }