fixing executive finalize in progress

This commit is contained in:
debris 2016-01-14 14:36:07 +01:00
parent 899c17ff74
commit 05246c4f7d
4 changed files with 24 additions and 7 deletions

View File

@ -45,7 +45,7 @@ impl EnvInfo {
difficulty: u256_from_json(&json["currentDifficulty"]), difficulty: u256_from_json(&json["currentDifficulty"]),
gas_limit: u256_from_json(&json["currentGasLimit"]), gas_limit: u256_from_json(&json["currentGasLimit"]),
timestamp: u64_from_json(&json["currentTimestamp"]), timestamp: u64_from_json(&json["currentTimestamp"]),
last_hashes: (1..257).map(|i| format!("{}", current_number - i).as_bytes().sha3()).collect(), last_hashes: (0..current_number).map(|i| format!("{}", current_number - i).as_bytes().sha3()).collect(),
gas_used: x!(0), gas_used: x!(0),
} }
} }

View File

@ -219,11 +219,23 @@ impl<'a> Executive<'a> {
} }
/// Finalizes the transaction (does refunds and suicides). /// Finalizes the transaction (does refunds and suicides).
fn finalize(&mut self, t: &Transaction, substate: Substate, backup: State, result: evm::Result) -> ExecutionResult { fn finalize(&mut self, t: &Transaction, substate: Substate, mut backup: State, result: evm::Result) -> ExecutionResult {
match result { match result {
Err(evm::Error::Internal) => Err(ExecutionError::Internal), Err(evm::Error::Internal) => Err(ExecutionError::Internal),
Err(evm::Error::OutOfGas) => { Err(evm::Error::OutOfGas) => {
*self.state = backup; // apply first transfer to backup, and then revert everything
let sender = t.sender().unwrap();
match t.action() {
&Action::Create => {
let nonce = backup.nonce(&sender);
let address = contract_address(&sender, &nonce);
backup.new_contract(&address);
backup.transfer_balance(&sender, &address, &t.value);
}
&Action::Call(ref address) => backup.transfer_balance(&sender, address, &t.value)
}
self.state.revert(backup);
Ok(Executed { Ok(Executed {
gas: t.gas, gas: t.gas,
gas_used: t.gas, gas_used: t.gas,
@ -832,9 +844,9 @@ mod tests {
}; };
assert_eq!(executed.gas, U256::from(100_000)); assert_eq!(executed.gas, U256::from(100_000));
assert_eq!(executed.gas_used, U256::from(20_025)); assert_eq!(executed.gas_used, U256::from(41_301));
assert_eq!(executed.refunded, U256::from(79_975)); assert_eq!(executed.refunded, U256::from(58_699));
assert_eq!(executed.cumulative_gas_used, U256::from(20_025)); assert_eq!(executed.cumulative_gas_used, U256::from(41_301));
assert_eq!(executed.logs.len(), 0); assert_eq!(executed.logs.len(), 0);
assert_eq!(executed.out_of_gas, false); assert_eq!(executed.out_of_gas, false);
assert_eq!(executed.contracts_created.len(), 0); assert_eq!(executed.contracts_created.len(), 0);

View File

@ -138,10 +138,15 @@ impl State {
/// This will change the state accordingly. /// This will change the state accordingly.
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult { pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &Transaction) -> ApplyResult {
let e = try!(Executive::new(self, env_info, engine).transact(t)); let e = try!(Executive::new(self, env_info, engine).transact(t));
println!("Executed: {:?}", e);
self.commit(); self.commit();
Ok(Receipt::new(self.root().clone(), e.gas_used, e.logs)) Ok(Receipt::new(self.root().clone(), e.gas_used, e.logs))
} }
pub fn revert(&mut self, backup: State) {
self.cache = backup.cache;
}
/// Convert into a JSON representation. /// Convert into a JSON representation.
pub fn as_json(&self) -> String { pub fn as_json(&self) -> String {
unimplemented!(); unimplemented!();

View File

@ -57,4 +57,4 @@ fn do_json_test(json_data: &[u8]) -> Vec<String> {
} }
declare_test!{StateTests_stExample, "StateTests/stExample"} declare_test!{StateTests_stExample, "StateTests/stExample"}
declare_test!{StateTests_stLogTests, "StateTests/stLogTests"} declare_test!{StateTests_stLogTests, "StateTests/stLogTests"}