commit
fc25330804
@ -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(¶ms, &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(¶ms.address);
|
||||
|
||||
@ -231,11 +245,11 @@ impl<'a> Executive<'a> {
|
||||
self.state.transfer_balance(¶ms.sender, ¶ms.address, ¶ms.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(¶ms, &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(¶ms, 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))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user