Add RPC & client call to replay a transaction. (#1734)

* Add RPC & client call to replay a transaction.

* Address grumbles
This commit is contained in:
Gav Wood
2016-07-27 21:34:32 +02:00
committed by GitHub
parent b9a08c36aa
commit eaa41ea568
9 changed files with 124 additions and 21 deletions

View File

@@ -26,6 +26,14 @@ use v1::traits::Traces;
use v1::helpers::CallRequest as CRequest;
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
fn to_call_analytics(flags: Vec<String>) -> CallAnalytics {
CallAnalytics {
transaction_tracing: flags.contains(&("trace".to_owned())),
vm_tracing: flags.contains(&("vmTrace".to_owned())),
state_diffing: flags.contains(&("stateDiff".to_owned())),
}
}
/// Traces api implementation.
pub struct TracesClient<C, M> where C: BlockChainClient, M: MinerService {
client: Weak<C>,
@@ -114,18 +122,11 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
fn call(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
trace!(target: "jsonrpc", "call: {:?}", params);
from_params(params)
.and_then(|(request, flags)| {
let request = CallRequest::into(request);
let flags: Vec<String> = flags;
let analytics = CallAnalytics {
transaction_tracing: flags.contains(&("trace".to_owned())),
vm_tracing: flags.contains(&("vmTrace".to_owned())),
state_diffing: flags.contains(&("stateDiff".to_owned())),
};
let signed = try!(self.sign_call(request));
match take_weak!(self.client).call(&signed, analytics) {
match take_weak!(self.client).call(&signed, to_call_analytics(flags)) {
Ok(e) => to_value(&TraceResults::from(e)),
_ => Ok(Value::Null),
}
@@ -134,17 +135,11 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
fn raw_transaction(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
trace!(target: "jsonrpc", "call: {:?}", params);
from_params::<(Bytes, Vec<String>)>(params)
from_params::<(Bytes, _)>(params)
.and_then(|(raw_transaction, flags)| {
let raw_transaction = raw_transaction.to_vec();
let analytics = CallAnalytics {
transaction_tracing: flags.contains(&("trace".to_owned())),
vm_tracing: flags.contains(&("vmTrace".to_owned())),
state_diffing: flags.contains(&("stateDiff".to_owned())),
};
match UntrustedRlp::new(&raw_transaction).as_val() {
Ok(signed) => match take_weak!(self.client).call(&signed, analytics) {
Ok(signed) => match take_weak!(self.client).call(&signed, to_call_analytics(flags)) {
Ok(e) => to_value(&TraceResults::from(e)),
_ => Ok(Value::Null),
},
@@ -152,4 +147,15 @@ impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M:
}
})
}
fn replay_transaction(&self, params: Params) -> Result<Value, Error> {
try!(self.active());
from_params::<(H256, _)>(params)
.and_then(|(transaction_hash, flags)| {
match take_weak!(self.client).replay(TransactionID::Hash(transaction_hash.into()), to_call_analytics(flags)) {
Ok(e) => to_value(&TraceResults::from(e)),
_ => Ok(Value::Null),
}
})
}
}

View File

@@ -38,6 +38,9 @@ pub trait Traces: Sized + Send + Sync + 'static {
/// Executes the given raw transaction and returns a number of possible traces for it.
fn raw_transaction(&self, _: Params) -> Result<Value, Error>;
/// Executes the transaction with the given hash and returns a number of possible traces for it.
fn replay_transaction(&self, _: Params) -> Result<Value, Error>;
/// Should be used to convert object to io delegate.
fn to_delegate(self) -> IoDelegate<Self> {
let mut delegate = IoDelegate::new(Arc::new(self));
@@ -47,6 +50,7 @@ pub trait Traces: Sized + Send + Sync + 'static {
delegate.add_method("trace_block", Traces::block_traces);
delegate.add_method("trace_call", Traces::call);
delegate.add_method("trace_rawTransaction", Traces::raw_transaction);
delegate.add_method("trace_replayTransaction", Traces::replay_transaction);
delegate
}