Groundwork for basic VM tracing.
This commit is contained in:
parent
098f9b6ebb
commit
42e4c2d51c
@ -40,6 +40,9 @@ pub enum MessageCallResult {
|
||||
Failed
|
||||
}
|
||||
|
||||
/// The trace function callback for VM tracing (*not* transaction tracing - that's different).
|
||||
pub type VMTraceFunctionBox = Box<FnMut(usize, u8, U256, U256) + Send>;
|
||||
|
||||
/// Externalities interface for EVMs
|
||||
pub trait Ext {
|
||||
/// Returns a value for given key.
|
||||
@ -105,4 +108,7 @@ pub trait Ext {
|
||||
|
||||
/// Increments sstore refunds count by 1.
|
||||
fn inc_sstore_clears(&mut self);
|
||||
|
||||
/// Provide a tracer for VM tracing if the VM implementation supports it.
|
||||
fn vm_tracer(&mut self) -> Option<&mut VMTraceFunctionBox>;
|
||||
}
|
||||
|
@ -311,6 +311,12 @@ impl evm::Evm for Interpreter {
|
||||
);
|
||||
});
|
||||
|
||||
// Call trace
|
||||
// TODO: allow to be disabled at build time for max speed
|
||||
if let Some(ref mut trace_instruction) = ext.vm_tracer() {
|
||||
(*trace_instruction.deref_mut())(reader.position, instruction, gas_cost, current_gas);
|
||||
}
|
||||
|
||||
// Execute instruction
|
||||
let result = try!(self.exec_instruction(
|
||||
current_gas, ¶ms, ext, instruction, &mut reader, &mut mem, &mut stack
|
||||
@ -833,10 +839,12 @@ impl Interpreter {
|
||||
}
|
||||
}
|
||||
|
||||
fn verify_instructions_requirements(&self,
|
||||
info: &instructions::InstructionInfo,
|
||||
stack_limit: usize,
|
||||
stack: &Stack<U256>) -> Result<(), evm::Error> {
|
||||
fn verify_instructions_requirements(
|
||||
&self,
|
||||
info: &instructions::InstructionInfo,
|
||||
stack_limit: usize,
|
||||
stack: &Stack<U256>
|
||||
) -> Result<(), evm::Error> {
|
||||
if !stack.has(info.args) {
|
||||
Err(evm::Error::StackUnderflow {
|
||||
instruction: info.name,
|
||||
|
@ -30,6 +30,6 @@ mod jit;
|
||||
mod tests;
|
||||
|
||||
pub use self::evm::{Evm, Error, Result};
|
||||
pub use self::ext::{Ext, ContractCreateResult, MessageCallResult};
|
||||
pub use self::ext::{Ext, ContractCreateResult, MessageCallResult, VMTraceFunctionBox};
|
||||
pub use self::factory::{Factory, VMType};
|
||||
pub use self::schedule::Schedule;
|
||||
|
@ -19,7 +19,7 @@ use common::*;
|
||||
use state::*;
|
||||
use engine::*;
|
||||
use executive::*;
|
||||
use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, Factory};
|
||||
use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, Factory, VMTraceFunctionBox};
|
||||
use substate::*;
|
||||
use trace::Tracer;
|
||||
|
||||
@ -66,10 +66,10 @@ pub struct Externalities<'a, T> where T: 'a + Tracer {
|
||||
schedule: Schedule,
|
||||
output: OutputPolicy<'a, 'a>,
|
||||
tracer: &'a mut T,
|
||||
vm_tracer: Option<VMTraceFunctionBox>,
|
||||
}
|
||||
|
||||
impl<'a, T> Externalities<'a, T> where T: 'a + Tracer {
|
||||
|
||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
||||
/// Basic `Externalities` constructor.
|
||||
pub fn new(state: &'a mut State,
|
||||
@ -93,6 +93,35 @@ impl<'a, T> Externalities<'a, T> where T: 'a + Tracer {
|
||||
schedule: engine.schedule(env_info),
|
||||
output: output,
|
||||
tracer: tracer,
|
||||
vm_tracer: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
||||
/// Basic `Externalities` constructor.
|
||||
pub fn with_vm_tracer(state: &'a mut State,
|
||||
env_info: &'a EnvInfo,
|
||||
engine: &'a Engine,
|
||||
vm_factory: &'a Factory,
|
||||
depth: usize,
|
||||
origin_info: OriginInfo,
|
||||
substate: &'a mut Substate,
|
||||
output: OutputPolicy<'a, 'a>,
|
||||
tracer: &'a mut T,
|
||||
vm_tracer: VMTraceFunctionBox,
|
||||
) -> Self {
|
||||
Externalities {
|
||||
state: state,
|
||||
env_info: env_info,
|
||||
engine: engine,
|
||||
vm_factory: vm_factory,
|
||||
depth: depth,
|
||||
origin_info: origin_info,
|
||||
substate: substate,
|
||||
schedule: engine.schedule(env_info),
|
||||
output: output,
|
||||
tracer: tracer,
|
||||
vm_tracer: Some(vm_tracer),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -286,6 +315,8 @@ impl<'a, T> Ext for Externalities<'a, T> where T: 'a + Tracer {
|
||||
fn inc_sstore_clears(&mut self) {
|
||||
self.substate.sstore_clears_count = self.substate.sstore_clears_count + U256::one();
|
||||
}
|
||||
|
||||
fn vm_tracer(&mut self) -> Option<&mut VMTraceFunctionBox> { self.vm_tracer.as_mut() }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
Loading…
Reference in New Issue
Block a user