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 // part of substate that may be reverted
let mut unconfirmed_substate = Substate::new(substate.subtraces.is_some()); 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 = { let res = {
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::Return(output)) 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![])); 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: sstore-clears={}\n", unconfirmed_substate.sstore_clears_count);
trace!("exec: substate={:?}; unconfirmed_substate={:?}\n", substate, unconfirmed_substate); 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); trace!("exec: new substate={:?}\n", substate);
res res
} else { } else {
@ -292,18 +292,18 @@ impl<'a> Executive<'a> {
self.state.new_contract(&params.address, prev_bal); 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 created = params.address.clone();
let res = { let res = {
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::InitContract) 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![])); 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 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 { match *result {
Err(evm::Error::OutOfGas) Err(evm::Error::OutOfGas)
| Err(evm::Error::BadJumpDestination {..}) | Err(evm::Error::BadJumpDestination {..})
@ -377,7 +377,7 @@ impl<'a> Executive<'a> {
}, },
Ok(_) | Err(evm::Error::Internal) => { Ok(_) | Err(evm::Error::Internal) => {
self.state.clear_snapshot(); 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. /// 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.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(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 { 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"), 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)] #[derive(Debug, Clone)]
/// A trace; includes a description of the action being traced and sub traces of each interior action. /// A trace; includes a description of the action being traced and sub traces of each interior action.
pub struct Trace { 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. /// The action being performed.
pub action: TraceAction, pub action: TraceAction,
/// The sub traces for each interior action performed as part of this call. /// The sub traces for each interior action performed as part of this call.
@ -74,6 +77,7 @@ pub struct Trace {
impl Default for Trace { impl Default for Trace {
fn default() -> Trace { fn default() -> Trace {
Trace { Trace {
depth: 0,
action: TraceAction::Unknown, action: TraceAction::Unknown,
subs: vec![], subs: vec![],
} }