diff --git a/ethcore/src/executive.rs b/ethcore/src/executive.rs index bd6199867..d7c0ced0a 100644 --- a/ethcore/src/executive.rs +++ b/ethcore/src/executive.rs @@ -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(¶ms)); + let mut trace_info = substate.subtraces.as_ref().map(|_| (TraceAction::from_call(¶ms), 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(¶ms.address, prev_bal); } - let mut action = substate.subtraces.as_ref().map(|_| TraceAction::from_create(¶ms)); + let mut trace_info = substate.subtraces.as_ref().map(|_| (TraceAction::from_create(¶ms), 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) { + 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) } } } diff --git a/ethcore/src/substate.rs b/ethcore/src/substate.rs index b2056d1b9..59f61e433 100644 --- a/ethcore/src/substate.rs +++ b/ethcore/src/substate.rs @@ -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) { + 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"), }); } diff --git a/ethcore/src/trace.rs b/ethcore/src/trace.rs index 546404e96..d2b28b556 100644 --- a/ethcore/src/trace.rs +++ b/ethcore/src/trace.rs @@ -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![], }