Test for failed create transactions, failed actions are logged as such.
This commit is contained in:
parent
f75fb6a59f
commit
d2d5806e9b
@ -306,11 +306,9 @@ impl<'a> Executive<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some((TraceAction::Create(ref mut c), _)) = trace_info {
|
if let Some((TraceAction::Create(ref mut c), _)) = trace_info {
|
||||||
if let Some(output) = trace_output {
|
c.result = res.as_ref().ok().map(|gas_left| (c.gas - *gas_left, created, trace_output.expect("trace_info is Some: qed")));
|
||||||
c.result = res.as_ref().ok().map(|gas_left| (c.gas - *gas_left, created, output));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!(target: "executive", "trace_info={:?}", trace_info);
|
trace!(target: "executive", "trace_info={:?}", trace_info);
|
||||||
|
|
||||||
self.enact_result(&res, substate, unconfirmed_substate, trace_info);
|
self.enact_result(&res, substate, unconfirmed_substate, trace_info);
|
||||||
@ -349,6 +347,8 @@ impl<'a> Executive<'a> {
|
|||||||
self.state.kill_account(address);
|
self.state.kill_account(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let trace = substate.subtraces.and_then(|mut v| v.pop());
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Err(evm::Error::Internal) => Err(ExecutionError::Internal),
|
Err(evm::Error::Internal) => Err(ExecutionError::Internal),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
@ -359,7 +359,7 @@ impl<'a> Executive<'a> {
|
|||||||
cumulative_gas_used: self.info.gas_used + t.gas,
|
cumulative_gas_used: self.info.gas_used + t.gas,
|
||||||
logs: vec![],
|
logs: vec![],
|
||||||
contracts_created: vec![],
|
contracts_created: vec![],
|
||||||
trace: None,
|
trace: trace,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
@ -370,7 +370,7 @@ impl<'a> Executive<'a> {
|
|||||||
cumulative_gas_used: self.info.gas_used + gas_used,
|
cumulative_gas_used: self.info.gas_used + gas_used,
|
||||||
logs: substate.logs,
|
logs: substate.logs,
|
||||||
contracts_created: substate.contracts_created,
|
contracts_created: substate.contracts_created,
|
||||||
trace: substate.subtraces.and_then(|mut v| v.pop()),
|
trace: trace,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -384,6 +384,7 @@ impl<'a> Executive<'a> {
|
|||||||
| Err(evm::Error::StackUnderflow {..})
|
| Err(evm::Error::StackUnderflow {..})
|
||||||
| Err(evm::Error::OutOfStack {..}) => {
|
| Err(evm::Error::OutOfStack {..}) => {
|
||||||
self.state.revert_snapshot();
|
self.state.revert_snapshot();
|
||||||
|
substate.accrue_trace(un_substate.subtraces, maybe_info)
|
||||||
},
|
},
|
||||||
Ok(_) | Err(evm::Error::Internal) => {
|
Ok(_) | Err(evm::Error::Internal) => {
|
||||||
self.state.clear_snapshot();
|
self.state.clear_snapshot();
|
||||||
|
@ -392,6 +392,44 @@ fn should_apply_create_transaction() {
|
|||||||
assert_eq!(result.trace, expected_trace);
|
assert_eq!(result.trace, expected_trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_trace_failed_create_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Create,
|
||||||
|
value: x!(100),
|
||||||
|
data: FromHex::from_hex("5b600056").unwrap(),
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Create(TraceCreate {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(78792),
|
||||||
|
init: FromHex::from_hex("5b600056").unwrap(),
|
||||||
|
result: None
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn code_from_database() {
|
fn code_from_database() {
|
||||||
let a = Address::zero();
|
let a = Address::zero();
|
||||||
|
@ -49,19 +49,27 @@ impl Substate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Merge secondary substate `s` into self, accruing each element correspondingly.
|
/// Merge tracing information from substate `s` if enabled.
|
||||||
|
pub fn accrue_trace(&mut self, subs: Option<Vec<Trace>>, maybe_info: Option<(TraceAction, usize)>) {
|
||||||
|
// it failed, so we don't bother accrueing any protocol-level stuff, only the
|
||||||
|
// trace info.
|
||||||
|
if let Some(info) = maybe_info {
|
||||||
|
self.subtraces.as_mut().expect("maybe_action is Some: so we must be tracing: qed").push(Trace {
|
||||||
|
action: info.0,
|
||||||
|
depth: info.1,
|
||||||
|
subs: subs.expect("maybe_action is Some: so we must be tracing: qed"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Merge secondary substate `s` into self, accruing each element correspondingly; will merge
|
||||||
|
/// tracing information too, if enabled.
|
||||||
pub fn accrue(&mut self, s: Substate, maybe_info: Option<(TraceAction, usize)>) {
|
pub fn accrue(&mut self, s: Substate, maybe_info: Option<(TraceAction, usize)>) {
|
||||||
self.suicides.extend(s.suicides.into_iter());
|
self.suicides.extend(s.suicides.into_iter());
|
||||||
self.logs.extend(s.logs.into_iter());
|
self.logs.extend(s.logs.into_iter());
|
||||||
self.sstore_clears_count = self.sstore_clears_count + s.sstore_clears_count;
|
self.sstore_clears_count = self.sstore_clears_count + s.sstore_clears_count;
|
||||||
self.contracts_created.extend(s.contracts_created.into_iter());
|
self.contracts_created.extend(s.contracts_created.into_iter());
|
||||||
if let Some(info) = maybe_info {
|
self.accrue_trace(s.subtraces, maybe_info);
|
||||||
self.subtraces.as_mut().expect("maybe_action is Some: so we must be tracing: qed").push(Trace {
|
|
||||||
action: info.0,
|
|
||||||
depth: info.1,
|
|
||||||
subs: s.subtraces.expect("maybe_action is Some: so we must be tracing: qed"),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user