Merge remote-tracking branch 'origin/master' into gav

This commit is contained in:
Gav Wood 2016-01-15 01:02:37 +01:00
commit 50424506e4

View File

@ -39,6 +39,14 @@ impl Substate {
}
}
pub fn accrue(&mut self, s: Substate) {
self.suicides.extend(s.suicides.into_iter());
self.logs.extend(s.logs.into_iter());
self.refunds_count = self.refunds_count + s.refunds_count;
self.out_of_gas |= s.out_of_gas;
self.contracts_created.extend(s.contracts_created.into_iter());
}
pub fn out_of_gas(&self) -> bool { self.out_of_gas }
}
@ -204,12 +212,15 @@ impl<'a> Executive<'a> {
} else if params.code.len() > 0 {
// if destination is a contract, do normal message call
// part of substate that may be reverted
let mut unconfirmed_substate = Substate::new();
let res = {
let mut ext = Externalities::from_executive(self, params, substate, OutputPolicy::Return(output));
let mut ext = Externalities::from_executive(self, params, &mut unconfirmed_substate, OutputPolicy::Return(output));
let evm = Factory::create();
evm.exec(&params, &mut ext)
};
self.revert_if_needed(&res, substate, backup);
self.enact_result(&res, substate, unconfirmed_substate, backup);
res
} else {
// otherwise, nothing
@ -224,6 +235,9 @@ impl<'a> Executive<'a> {
// backup used in case of running out of gas
let backup = self.state.clone();
// part of substate that may be reverted
let mut unconfirmed_substate = Substate::new();
// at first create new contract
self.state.new_contract(&params.address);
@ -231,11 +245,11 @@ impl<'a> Executive<'a> {
self.state.transfer_balance(&params.sender, &params.address, &params.value);
let res = {
let mut ext = Externalities::from_executive(self, params, substate, OutputPolicy::InitContract);
let mut ext = Externalities::from_executive(self, params, &mut unconfirmed_substate, OutputPolicy::InitContract);
let evm = Factory::create();
evm.exec(&params, &mut ext)
};
self.revert_if_needed(&res, substate, backup);
self.enact_result(&res, substate, unconfirmed_substate, backup);
res
}
@ -297,15 +311,14 @@ impl<'a> Executive<'a> {
}
}
fn revert_if_needed(&mut self, result: &evm::Result, substate: &mut Substate, backup: State) {
fn enact_result(&mut self, result: &evm::Result, substate: &mut Substate, un_substate: Substate, backup: State) {
// TODO: handle other evm::Errors same as OutOfGas once they are implemented
match result {
&Err(evm::Error::OutOfGas) => {
substate.out_of_gas = true;
self.state.revert(backup);
},
&Err(evm::Error::Internal) => (),
&Ok(_) => ()
&Ok(_) | &Err(evm::Error::Internal) => substate.accrue(un_substate)
}
}
}
@ -466,7 +479,7 @@ impl<'a> Ext for Externalities<'a> {
let mut ex = Executive::from_parent(self.state, self.info, self.engine, self.depth);
match ex.call(&params, self.substate, BytesRef::Fixed(output)) {
Ok(gas_left) => Ok((gas + gas_left, true)), //Some(CallResult::new(gas + gas_left, true)),
Ok(gas_left) => Ok((gas + gas_left, true)),
_ => Ok((gas, false))
}
}