Groundwork for basic VM tracing.
This commit is contained in:
parent
098f9b6ebb
commit
42e4c2d51c
@ -40,6 +40,9 @@ pub enum MessageCallResult {
|
|||||||
Failed
|
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
|
/// Externalities interface for EVMs
|
||||||
pub trait Ext {
|
pub trait Ext {
|
||||||
/// Returns a value for given key.
|
/// Returns a value for given key.
|
||||||
@ -105,4 +108,7 @@ pub trait Ext {
|
|||||||
|
|
||||||
/// Increments sstore refunds count by 1.
|
/// Increments sstore refunds count by 1.
|
||||||
fn inc_sstore_clears(&mut self);
|
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
|
// Execute instruction
|
||||||
let result = try!(self.exec_instruction(
|
let result = try!(self.exec_instruction(
|
||||||
current_gas, ¶ms, ext, instruction, &mut reader, &mut mem, &mut stack
|
current_gas, ¶ms, ext, instruction, &mut reader, &mut mem, &mut stack
|
||||||
@ -833,10 +839,12 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_instructions_requirements(&self,
|
fn verify_instructions_requirements(
|
||||||
info: &instructions::InstructionInfo,
|
&self,
|
||||||
stack_limit: usize,
|
info: &instructions::InstructionInfo,
|
||||||
stack: &Stack<U256>) -> Result<(), evm::Error> {
|
stack_limit: usize,
|
||||||
|
stack: &Stack<U256>
|
||||||
|
) -> Result<(), evm::Error> {
|
||||||
if !stack.has(info.args) {
|
if !stack.has(info.args) {
|
||||||
Err(evm::Error::StackUnderflow {
|
Err(evm::Error::StackUnderflow {
|
||||||
instruction: info.name,
|
instruction: info.name,
|
||||||
|
@ -30,6 +30,6 @@ mod jit;
|
|||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
pub use self::evm::{Evm, Error, Result};
|
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::factory::{Factory, VMType};
|
||||||
pub use self::schedule::Schedule;
|
pub use self::schedule::Schedule;
|
||||||
|
@ -19,7 +19,7 @@ use common::*;
|
|||||||
use state::*;
|
use state::*;
|
||||||
use engine::*;
|
use engine::*;
|
||||||
use executive::*;
|
use executive::*;
|
||||||
use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, Factory};
|
use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult, Factory, VMTraceFunctionBox};
|
||||||
use substate::*;
|
use substate::*;
|
||||||
use trace::Tracer;
|
use trace::Tracer;
|
||||||
|
|
||||||
@ -66,10 +66,10 @@ pub struct Externalities<'a, T> where T: 'a + Tracer {
|
|||||||
schedule: Schedule,
|
schedule: Schedule,
|
||||||
output: OutputPolicy<'a, 'a>,
|
output: OutputPolicy<'a, 'a>,
|
||||||
tracer: &'a mut T,
|
tracer: &'a mut T,
|
||||||
|
vm_tracer: Option<VMTraceFunctionBox>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Externalities<'a, T> where T: 'a + Tracer {
|
impl<'a, T> Externalities<'a, T> where T: 'a + Tracer {
|
||||||
|
|
||||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
||||||
/// Basic `Externalities` constructor.
|
/// Basic `Externalities` constructor.
|
||||||
pub fn new(state: &'a mut State,
|
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),
|
schedule: engine.schedule(env_info),
|
||||||
output: output,
|
output: output,
|
||||||
tracer: tracer,
|
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) {
|
fn inc_sstore_clears(&mut self) {
|
||||||
self.substate.sstore_clears_count = self.substate.sstore_clears_count + U256::one();
|
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)]
|
#[cfg(test)]
|
||||||
|
Loading…
Reference in New Issue
Block a user