Track depth.

This commit is contained in:
Gav Wood 2016-03-19 14:35:09 +01:00
parent 152f132b7b
commit bd7cd68c32
3 changed files with 16 additions and 11 deletions

View File

@ -250,20 +250,20 @@ impl<'a> Executive<'a> {
// part of substate that may be reverted
let mut unconfirmed_substate = Substate::new(substate.subtraces.is_some());
let mut action = substate.subtraces.as_ref().map(|_| TraceAction::from_call(&params));
let mut trace_info = substate.subtraces.as_ref().map(|_| (TraceAction::from_call(&params), self.depth));
let res = {
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::Return(output))
};
if let Some(TraceAction::Call(ref mut c)) = action {
if let Some((TraceAction::Call(ref mut c), _)) = trace_info {
c.result = res.as_ref().ok().map(|gas_left| (c.gas - *gas_left, vec![]));
}
trace!("exec: sstore-clears={}\n", unconfirmed_substate.sstore_clears_count);
trace!("exec: substate={:?}; unconfirmed_substate={:?}\n", substate, unconfirmed_substate);
self.enact_result(&res, substate, unconfirmed_substate, action);
self.enact_result(&res, substate, unconfirmed_substate, trace_info);
trace!("exec: new substate={:?}\n", substate);
res
} else {
@ -292,18 +292,18 @@ impl<'a> Executive<'a> {
self.state.new_contract(&params.address, prev_bal);
}
let mut action = substate.subtraces.as_ref().map(|_| TraceAction::from_create(&params));
let mut trace_info = substate.subtraces.as_ref().map(|_| (TraceAction::from_create(&params), self.depth));
let created = params.address.clone();
let res = {
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::InitContract)
};
if let Some(TraceAction::Create(ref mut c)) = action {
if let Some((TraceAction::Create(ref mut c), _)) = trace_info {
c.result = res.as_ref().ok().map(|gas_left| (c.gas - *gas_left, created, vec![]));
}
self.enact_result(&res, substate, unconfirmed_substate, action);
self.enact_result(&res, substate, unconfirmed_substate, trace_info);
res
}
@ -366,7 +366,7 @@ impl<'a> Executive<'a> {
}
}
fn enact_result(&mut self, result: &evm::Result, substate: &mut Substate, un_substate: Substate, maybe_action: Option<TraceAction>) {
fn enact_result(&mut self, result: &evm::Result, substate: &mut Substate, un_substate: Substate, maybe_info: Option<(TraceAction, usize)>) {
match *result {
Err(evm::Error::OutOfGas)
| Err(evm::Error::BadJumpDestination {..})
@ -377,7 +377,7 @@ impl<'a> Executive<'a> {
},
Ok(_) | Err(evm::Error::Internal) => {
self.state.clear_snapshot();
substate.accrue(un_substate, maybe_action)
substate.accrue(un_substate, maybe_info)
}
}
}

View File

@ -50,14 +50,15 @@ impl Substate {
}
/// Merge secondary substate `s` into self, accruing each element correspondingly.
pub fn accrue(&mut self, s: Substate, maybe_action: Option<TraceAction>) {
pub fn accrue(&mut self, s: Substate, maybe_info: Option<(TraceAction, usize)>) {
self.suicides.extend(s.suicides.into_iter());
self.logs.extend(s.logs.into_iter());
self.sstore_clears_count = self.sstore_clears_count + s.sstore_clears_count;
self.contracts_created.extend(s.contracts_created.into_iter());
if let Some(action) = maybe_action {
if let Some(info) = maybe_info {
self.subtraces.as_mut().expect("maybe_action is Some: so we must be tracing: qed").push(Trace {
action: action,
action: info.0,
depth: info.1,
subs: s.subtraces.expect("maybe_action is Some: so we must be tracing: qed"),
});
}

View File

@ -65,6 +65,9 @@ pub enum TraceAction {
#[derive(Debug, Clone)]
/// A trace; includes a description of the action being traced and sub traces of each interior action.
pub struct Trace {
/// The number of EVM execution environments active when this action happened; 0 if it's
/// the outer action of the transaction.
pub depth: usize,
/// The action being performed.
pub action: TraceAction,
/// The sub traces for each interior action performed as part of this call.
@ -74,6 +77,7 @@ pub struct Trace {
impl Default for Trace {
fn default() -> Trace {
Trace {
depth: 0,
action: TraceAction::Unknown,
subs: vec![],
}