Merge pull request #6842 from paritytech/td-evm-json
Fix JSON tracing for sub-calls.
This commit is contained in:
@@ -1142,7 +1142,7 @@ impl Client {
|
||||
state_diff: bool,
|
||||
transaction: &SignedTransaction,
|
||||
options: TransactOptions<T, V>,
|
||||
) -> Result<Executed, CallError> where
|
||||
) -> Result<Executed<T::Output, V::Output>, CallError> where
|
||||
T: trace::Tracer,
|
||||
V: trace::VMTracer,
|
||||
{
|
||||
|
||||
@@ -197,7 +197,7 @@ impl<'a> EvmTestClient<'a> {
|
||||
env_info: &client::EnvInfo,
|
||||
transaction: transaction::SignedTransaction,
|
||||
vm_tracer: T,
|
||||
) -> TransactResult {
|
||||
) -> TransactResult<T::Output> {
|
||||
let initial_gas = transaction.gas;
|
||||
// Verify transaction
|
||||
let is_ok = transaction.verify_basic(true, None, env_info.number >= self.spec.engine.params().eip86_transition);
|
||||
@@ -218,7 +218,8 @@ impl<'a> EvmTestClient<'a> {
|
||||
TransactResult::Ok {
|
||||
state_root: *self.state.root(),
|
||||
gas_left: initial_gas - result.receipt.gas_used,
|
||||
output: result.output
|
||||
output: result.output,
|
||||
vm_trace: result.vm_trace,
|
||||
}
|
||||
},
|
||||
Err(error) => TransactResult::Err {
|
||||
@@ -230,7 +231,7 @@ impl<'a> EvmTestClient<'a> {
|
||||
}
|
||||
|
||||
/// A result of applying transaction to the state.
|
||||
pub enum TransactResult {
|
||||
pub enum TransactResult<T> {
|
||||
/// Successful execution
|
||||
Ok {
|
||||
/// State root
|
||||
@@ -239,6 +240,8 @@ pub enum TransactResult {
|
||||
gas_left: U256,
|
||||
/// Output
|
||||
output: Vec<u8>,
|
||||
/// VM Traces
|
||||
vm_trace: Option<T>,
|
||||
},
|
||||
/// Transaction failed to run
|
||||
Err {
|
||||
|
||||
@@ -29,7 +29,7 @@ use std::fmt;
|
||||
|
||||
/// Transaction execution receipt.
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Executed {
|
||||
pub struct Executed<T = FlatTrace, V = VMTrace> {
|
||||
/// True if the outer call/create resulted in an exceptional exit.
|
||||
pub exception: Option<vm::Error>,
|
||||
|
||||
@@ -63,9 +63,9 @@ pub struct Executed {
|
||||
/// Transaction output.
|
||||
pub output: Bytes,
|
||||
/// The trace of this transaction.
|
||||
pub trace: Vec<FlatTrace>,
|
||||
pub trace: Vec<T>,
|
||||
/// The VM trace of this transaction.
|
||||
pub vm_trace: Option<VMTrace>,
|
||||
pub vm_trace: Option<V>,
|
||||
/// The state diff, if we traced it.
|
||||
pub state_diff: Option<StateDiff>,
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ use evm::{CallType, Factory, Finalize, FinalizationResult};
|
||||
use vm::{self, Ext, CreateContractAddress, ReturnData, CleanDustMode, ActionParams, ActionValue};
|
||||
use wasm;
|
||||
use externalities::*;
|
||||
use trace::{self, FlatTrace, VMTrace, Tracer, VMTracer};
|
||||
use trace::{self, Tracer, VMTracer};
|
||||
use transaction::{Action, SignedTransaction};
|
||||
use crossbeam;
|
||||
pub use executed::{Executed, ExecutionResult};
|
||||
@@ -214,7 +214,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
|
||||
/// This function should be used to execute transaction.
|
||||
pub fn transact<T, V>(&'a mut self, t: &SignedTransaction, options: TransactOptions<T, V>)
|
||||
-> Result<Executed, ExecutionError> where T: Tracer, V: VMTracer,
|
||||
-> Result<Executed<T::Output, V::Output>, ExecutionError> where T: Tracer, V: VMTracer,
|
||||
{
|
||||
self.transact_with_tracer(t, options.check_nonce, options.output_from_init_contract, options.tracer, options.vm_tracer)
|
||||
}
|
||||
@@ -223,7 +223,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
/// This will ensure the caller has enough balance to execute the desired transaction.
|
||||
/// Used for extra-block executions for things like consensus contracts and RPCs
|
||||
pub fn transact_virtual<T, V>(&'a mut self, t: &SignedTransaction, options: TransactOptions<T, V>)
|
||||
-> Result<Executed, ExecutionError> where T: Tracer, V: VMTracer,
|
||||
-> Result<Executed<T::Output, V::Output>, ExecutionError> where T: Tracer, V: VMTracer,
|
||||
{
|
||||
let sender = t.sender();
|
||||
let balance = self.state.balance(&sender)?;
|
||||
@@ -244,7 +244,7 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
output_from_create: bool,
|
||||
mut tracer: T,
|
||||
mut vm_tracer: V
|
||||
) -> Result<Executed, ExecutionError> where T: Tracer, V: VMTracer {
|
||||
) -> Result<Executed<T::Output, V::Output>, ExecutionError> where T: Tracer, V: VMTracer {
|
||||
let sender = t.sender();
|
||||
let nonce = self.state.nonce(&sender)?;
|
||||
|
||||
@@ -587,15 +587,15 @@ impl<'a, B: 'a + StateBackend> Executive<'a, B> {
|
||||
}
|
||||
|
||||
/// Finalizes the transaction (does refunds and suicides).
|
||||
fn finalize(
|
||||
fn finalize<T, V>(
|
||||
&mut self,
|
||||
t: &SignedTransaction,
|
||||
mut substate: Substate,
|
||||
result: vm::Result<FinalizationResult>,
|
||||
output: Bytes,
|
||||
trace: Vec<FlatTrace>,
|
||||
vm_trace: Option<VMTrace>
|
||||
) -> ExecutionResult {
|
||||
trace: Vec<T>,
|
||||
vm_trace: Option<V>
|
||||
) -> Result<Executed<T, V>, ExecutionError> {
|
||||
let schedule = self.machine.schedule(self.info.number);
|
||||
|
||||
// refunds from SSTORE nonzero -> zero
|
||||
|
||||
@@ -62,19 +62,19 @@ pub use self::backend::Backend;
|
||||
pub use self::substate::Substate;
|
||||
|
||||
/// Used to return information about an `State::apply` operation.
|
||||
pub struct ApplyOutcome {
|
||||
pub struct ApplyOutcome<T, V> {
|
||||
/// The receipt for the applied transaction.
|
||||
pub receipt: Receipt,
|
||||
/// The output of the applied transaction.
|
||||
pub output: Bytes,
|
||||
/// The trace for the applied transaction, empty if tracing was not produced.
|
||||
pub trace: Vec<FlatTrace>,
|
||||
pub trace: Vec<T>,
|
||||
/// The VM trace for the applied transaction, None if tracing was not produced.
|
||||
pub vm_trace: Option<VMTrace>
|
||||
pub vm_trace: Option<V>
|
||||
}
|
||||
|
||||
/// Result type for the execution ("application") of a transaction.
|
||||
pub type ApplyResult = Result<ApplyOutcome, Error>;
|
||||
pub type ApplyResult<T, V> = Result<ApplyOutcome<T, V>, Error>;
|
||||
|
||||
/// Return type of proof validity check.
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -668,7 +668,7 @@ impl<B: Backend> State<B> {
|
||||
|
||||
/// Execute a given transaction, producing a receipt and an optional trace.
|
||||
/// This will change the state accordingly.
|
||||
pub fn apply(&mut self, env_info: &EnvInfo, machine: &Machine, t: &SignedTransaction, tracing: bool) -> ApplyResult {
|
||||
pub fn apply(&mut self, env_info: &EnvInfo, machine: &Machine, t: &SignedTransaction, tracing: bool) -> ApplyResult<FlatTrace, VMTrace> {
|
||||
if tracing {
|
||||
let options = TransactOptions::with_tracing();
|
||||
self.apply_with_tracing(env_info, machine, t, options.tracer, options.vm_tracer)
|
||||
@@ -687,7 +687,7 @@ impl<B: Backend> State<B> {
|
||||
t: &SignedTransaction,
|
||||
tracer: T,
|
||||
vm_tracer: V,
|
||||
) -> ApplyResult where
|
||||
) -> ApplyResult<T::Output, V::Output> where
|
||||
T: trace::Tracer,
|
||||
V: trace::VMTracer,
|
||||
{
|
||||
@@ -728,7 +728,7 @@ impl<B: Backend> State<B> {
|
||||
// `virt` signals that we are executing outside of a block set and restrictions like
|
||||
// gas limits and gas costs should be lifted.
|
||||
fn execute<T, V>(&mut self, env_info: &EnvInfo, machine: &Machine, t: &SignedTransaction, options: TransactOptions<T, V>, virt: bool)
|
||||
-> Result<Executed, ExecutionError> where T: trace::Tracer, V: trace::VMTracer,
|
||||
-> Result<Executed<T::Output, V::Output>, ExecutionError> where T: trace::Tracer, V: trace::VMTracer,
|
||||
{
|
||||
let mut e = Executive::new(self, env_info, machine);
|
||||
|
||||
|
||||
@@ -83,6 +83,8 @@ fn should_prefix_address_properly() {
|
||||
}
|
||||
|
||||
impl Tracer for ExecutiveTracer {
|
||||
type Output = FlatTrace;
|
||||
|
||||
fn prepare_trace_call(&self, params: &ActionParams) -> Option<Call> {
|
||||
Some(Call::from(params.clone()))
|
||||
}
|
||||
@@ -201,6 +203,8 @@ impl ExecutiveVMTracer {
|
||||
}
|
||||
|
||||
impl VMTracer for ExecutiveVMTracer {
|
||||
type Output = VMTrace;
|
||||
|
||||
fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8) -> bool { true }
|
||||
|
||||
fn trace_prepare_execute(&mut self, pc: usize, instruction: u8, gas_cost: U256) {
|
||||
|
||||
@@ -48,6 +48,9 @@ use header::BlockNumber;
|
||||
|
||||
/// This trait is used by executive to build traces.
|
||||
pub trait Tracer: Send {
|
||||
/// Data returned when draining the Tracer.
|
||||
type Output;
|
||||
|
||||
/// Prepares call trace for given params. Noop tracer should return None.
|
||||
fn prepare_trace_call(&self, params: &ActionParams) -> Option<Call>;
|
||||
|
||||
@@ -63,7 +66,7 @@ pub trait Tracer: Send {
|
||||
call: Option<Call>,
|
||||
gas_used: U256,
|
||||
output: Option<Bytes>,
|
||||
subs: Vec<FlatTrace>,
|
||||
subs: Vec<Self::Output>,
|
||||
);
|
||||
|
||||
/// Stores trace create info.
|
||||
@@ -73,14 +76,14 @@ pub trait Tracer: Send {
|
||||
gas_used: U256,
|
||||
code: Option<Bytes>,
|
||||
address: Address,
|
||||
subs: Vec<FlatTrace>
|
||||
subs: Vec<Self::Output>
|
||||
);
|
||||
|
||||
/// Stores failed call trace.
|
||||
fn trace_failed_call(&mut self, call: Option<Call>, subs: Vec<FlatTrace>, error: TraceError);
|
||||
fn trace_failed_call(&mut self, call: Option<Call>, subs: Vec<Self::Output>, error: TraceError);
|
||||
|
||||
/// Stores failed create trace.
|
||||
fn trace_failed_create(&mut self, create: Option<Create>, subs: Vec<FlatTrace>, error: TraceError);
|
||||
fn trace_failed_create(&mut self, create: Option<Create>, subs: Vec<Self::Output>, error: TraceError);
|
||||
|
||||
/// Stores suicide info.
|
||||
fn trace_suicide(&mut self, address: Address, balance: U256, refund_address: Address);
|
||||
@@ -92,12 +95,15 @@ pub trait Tracer: Send {
|
||||
fn subtracer(&self) -> Self where Self: Sized;
|
||||
|
||||
/// Consumes self and returns all traces.
|
||||
fn drain(self) -> Vec<FlatTrace>;
|
||||
fn drain(self) -> Vec<Self::Output>;
|
||||
}
|
||||
|
||||
/// Used by executive to build VM traces.
|
||||
pub trait VMTracer: Send {
|
||||
|
||||
/// Data returned when draining the VMTracer.
|
||||
type Output;
|
||||
|
||||
/// Trace the progression of interpreter to next instruction.
|
||||
/// If tracer returns `false` it won't be called again.
|
||||
/// @returns true if `trace_prepare_execute` and `trace_executed` should be called.
|
||||
@@ -116,7 +122,7 @@ pub trait VMTracer: Send {
|
||||
fn done_subtrace(&mut self, sub: Self) where Self: Sized;
|
||||
|
||||
/// Consumes self and returns the VM trace.
|
||||
fn drain(self) -> Option<VMTrace>;
|
||||
fn drain(self) -> Option<Self::Output>;
|
||||
}
|
||||
|
||||
/// `DbExtras` provides an interface to query extra data which is not stored in tracesdb,
|
||||
|
||||
@@ -27,6 +27,8 @@ use trace::trace::{Call, Create, VMTrace, RewardType};
|
||||
pub struct NoopTracer;
|
||||
|
||||
impl Tracer for NoopTracer {
|
||||
type Output = FlatTrace;
|
||||
|
||||
fn prepare_trace_call(&self, _: &ActionParams) -> Option<Call> {
|
||||
None
|
||||
}
|
||||
@@ -76,6 +78,8 @@ impl Tracer for NoopTracer {
|
||||
pub struct NoopVMTracer;
|
||||
|
||||
impl VMTracer for NoopVMTracer {
|
||||
type Output = VMTrace;
|
||||
|
||||
fn trace_next_instruction(&mut self, _pc: usize, _instruction: u8) -> bool { false }
|
||||
|
||||
fn trace_prepare_execute(&mut self, _pc: usize, _instruction: u8, _gas_cost: U256) {}
|
||||
|
||||
Reference in New Issue
Block a user