Traces error handling (#4849)
This commit is contained in:
parent
7c45178076
commit
2dca24cc28
@ -14,7 +14,6 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use trace::Error as TraceError;
|
|
||||||
use util::UtilError;
|
use util::UtilError;
|
||||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
use std::fmt::{Display, Formatter, Error as FmtError};
|
||||||
|
|
||||||
@ -23,8 +22,6 @@ use util::trie::TrieError;
|
|||||||
/// Client configuration errors.
|
/// Client configuration errors.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// TraceDB configuration error.
|
|
||||||
Trace(TraceError),
|
|
||||||
/// TrieDB-related error.
|
/// TrieDB-related error.
|
||||||
Trie(TrieError),
|
Trie(TrieError),
|
||||||
/// Database error
|
/// Database error
|
||||||
@ -33,12 +30,6 @@ pub enum Error {
|
|||||||
Util(UtilError),
|
Util(UtilError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TraceError> for Error {
|
|
||||||
fn from(err: TraceError) -> Self {
|
|
||||||
Error::Trace(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<TrieError> for Error {
|
impl From<TrieError> for Error {
|
||||||
fn from(err: TrieError) -> Self {
|
fn from(err: TrieError) -> Self {
|
||||||
Error::Trie(err)
|
Error::Trie(err)
|
||||||
@ -60,7 +51,6 @@ impl<E> From<Box<E>> for Error where Error: From<E> {
|
|||||||
impl Display for Error {
|
impl Display for Error {
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Trace(ref err) => write!(f, "{}", err),
|
|
||||||
Error::Trie(ref err) => write!(f, "{}", err),
|
Error::Trie(ref err) => write!(f, "{}", err),
|
||||||
Error::Util(ref err) => write!(f, "{}", err),
|
Error::Util(ref err) => write!(f, "{}", err),
|
||||||
Error::Database(ref s) => write!(f, "Database error: {}", s),
|
Error::Database(ref s) => write!(f, "Database error: {}", s),
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! `TraceDB` errors.
|
|
||||||
|
|
||||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
|
||||||
|
|
||||||
const RESYNC_ERR: &'static str =
|
|
||||||
"Your current parity installation has synced without transaction tracing.
|
|
||||||
To use Parity with transaction tracing, you'll need to resync with tracing.
|
|
||||||
To do this, remove or move away your current database and restart parity. e.g.:
|
|
||||||
|
|
||||||
> mv ~/.parity/906a34e69aec8c0d /tmp
|
|
||||||
> parity";
|
|
||||||
|
|
||||||
/// `TraceDB` errors.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
/// Returned when tracing is enabled,
|
|
||||||
/// but database does not contain traces of old transactions.
|
|
||||||
ResyncRequired,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Error {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
|
||||||
write!(f, "{}", RESYNC_ERR)
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,7 +19,6 @@
|
|||||||
mod bloom;
|
mod bloom;
|
||||||
mod config;
|
mod config;
|
||||||
mod db;
|
mod db;
|
||||||
mod error;
|
|
||||||
mod executive_tracer;
|
mod executive_tracer;
|
||||||
mod import;
|
mod import;
|
||||||
mod noop_tracer;
|
mod noop_tracer;
|
||||||
@ -28,7 +27,6 @@ pub use types::trace_types::{filter, flat, localized, trace};
|
|||||||
pub use types::trace_types::error::Error as TraceError;
|
pub use types::trace_types::error::Error as TraceError;
|
||||||
pub use self::config::Config;
|
pub use self::config::Config;
|
||||||
pub use self::db::TraceDB;
|
pub use self::db::TraceDB;
|
||||||
pub use self::error::Error;
|
|
||||||
pub use types::trace_types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff};
|
pub use types::trace_types::trace::{VMTrace, VMOperation, VMExecutedOperation, MemoryDiff, StorageDiff};
|
||||||
pub use types::trace_types::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces};
|
pub use types::trace_types::flat::{FlatTrace, FlatTransactionTraces, FlatBlockTraces};
|
||||||
pub use self::noop_tracer::{NoopTracer, NoopVMTracer};
|
pub use self::noop_tracer::{NoopTracer, NoopVMTracer};
|
||||||
|
@ -32,7 +32,6 @@ mod codes {
|
|||||||
pub const NO_WORK: i64 = -32001;
|
pub const NO_WORK: i64 = -32001;
|
||||||
pub const NO_AUTHOR: i64 = -32002;
|
pub const NO_AUTHOR: i64 = -32002;
|
||||||
pub const NO_NEW_WORK: i64 = -32003;
|
pub const NO_NEW_WORK: i64 = -32003;
|
||||||
pub const NOT_ENOUGH_DATA: i64 = -32006;
|
|
||||||
pub const UNKNOWN_ERROR: i64 = -32009;
|
pub const UNKNOWN_ERROR: i64 = -32009;
|
||||||
pub const TRANSACTION_ERROR: i64 = -32010;
|
pub const TRANSACTION_ERROR: i64 = -32010;
|
||||||
pub const EXECUTION_ERROR: i64 = -32015;
|
pub const EXECUTION_ERROR: i64 = -32015;
|
||||||
@ -41,9 +40,6 @@ mod codes {
|
|||||||
pub const ACCOUNT_LOCKED: i64 = -32020;
|
pub const ACCOUNT_LOCKED: i64 = -32020;
|
||||||
pub const PASSWORD_INVALID: i64 = -32021;
|
pub const PASSWORD_INVALID: i64 = -32021;
|
||||||
pub const ACCOUNT_ERROR: i64 = -32023;
|
pub const ACCOUNT_ERROR: i64 = -32023;
|
||||||
pub const SIGNER_DISABLED: i64 = -32030;
|
|
||||||
pub const DAPPS_DISABLED: i64 = -32031;
|
|
||||||
pub const NETWORK_DISABLED: i64 = -32035;
|
|
||||||
pub const REQUEST_REJECTED: i64 = -32040;
|
pub const REQUEST_REJECTED: i64 = -32040;
|
||||||
pub const REQUEST_REJECTED_LIMIT: i64 = -32041;
|
pub const REQUEST_REJECTED_LIMIT: i64 = -32041;
|
||||||
pub const REQUEST_NOT_FOUND: i64 = -32042;
|
pub const REQUEST_NOT_FOUND: i64 = -32042;
|
||||||
@ -174,9 +170,9 @@ pub fn no_author() -> Error {
|
|||||||
|
|
||||||
pub fn not_enough_data() -> Error {
|
pub fn not_enough_data() -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::NOT_ENOUGH_DATA),
|
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||||
message: "The node does not have enough data to compute the given statistic.".into(),
|
message: "The node does not have enough data to compute the given statistic.".into(),
|
||||||
data: None
|
data: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,25 +186,25 @@ pub fn token(e: String) -> Error {
|
|||||||
|
|
||||||
pub fn signer_disabled() -> Error {
|
pub fn signer_disabled() -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::SIGNER_DISABLED),
|
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||||
message: "Trusted Signer is disabled. This API is not available.".into(),
|
message: "Trusted Signer is disabled. This API is not available.".into(),
|
||||||
data: None
|
data: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dapps_disabled() -> Error {
|
pub fn dapps_disabled() -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::DAPPS_DISABLED),
|
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||||
message: "Dapps Server is disabled. This API is not available.".into(),
|
message: "Dapps Server is disabled. This API is not available.".into(),
|
||||||
data: None
|
data: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn network_disabled() -> Error {
|
pub fn network_disabled() -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::NETWORK_DISABLED),
|
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
||||||
message: "Network is disabled or not yet up.".into(),
|
message: "Network is disabled or not yet up.".into(),
|
||||||
data: None
|
data: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +317,7 @@ pub fn from_call_error(error: CallError) -> Error {
|
|||||||
|
|
||||||
pub fn unknown_block() -> Error {
|
pub fn unknown_block() -> Error {
|
||||||
Error {
|
Error {
|
||||||
code: ErrorCode::ServerError(codes::UNSUPPORTED_REQUEST),
|
code: ErrorCode::InvalidParams,
|
||||||
message: "Unknown block number".into(),
|
message: "Unknown block number".into(),
|
||||||
data: None,
|
data: None,
|
||||||
}
|
}
|
||||||
|
43
rpc/src/v1/helpers/fake_sign.rs
Normal file
43
rpc/src/v1/helpers/fake_sign.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::sync::Weak;
|
||||||
|
use ethcore::client::MiningBlockChainClient;
|
||||||
|
use ethcore::miner::MinerService;
|
||||||
|
use ethcore::transaction::{Transaction, SignedTransaction, Action};
|
||||||
|
|
||||||
|
use jsonrpc_core::Error;
|
||||||
|
use v1::helpers::CallRequest;
|
||||||
|
use v1::helpers::dispatch::default_gas_price;
|
||||||
|
|
||||||
|
pub fn sign_call<B: MiningBlockChainClient, M: MinerService>(
|
||||||
|
client: &Weak<B>,
|
||||||
|
miner: &Weak<M>,
|
||||||
|
request: CallRequest,
|
||||||
|
) -> Result<SignedTransaction, Error> {
|
||||||
|
let client = take_weak!(client);
|
||||||
|
let miner = take_weak!(miner);
|
||||||
|
let from = request.from.unwrap_or(0.into());
|
||||||
|
|
||||||
|
Ok(Transaction {
|
||||||
|
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
||||||
|
action: request.to.map_or(Action::Create, Action::Call),
|
||||||
|
gas: request.gas.unwrap_or(50_000_000.into()),
|
||||||
|
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&*client, &*miner)),
|
||||||
|
value: request.value.unwrap_or(0.into()),
|
||||||
|
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
||||||
|
}.fake_sign(from))
|
||||||
|
}
|
@ -19,6 +19,7 @@ pub mod errors;
|
|||||||
|
|
||||||
pub mod block_import;
|
pub mod block_import;
|
||||||
pub mod dispatch;
|
pub mod dispatch;
|
||||||
|
pub mod fake_sign;
|
||||||
pub mod informant;
|
pub mod informant;
|
||||||
|
|
||||||
mod network_settings;
|
mod network_settings;
|
||||||
|
@ -23,7 +23,7 @@ use std::sync::{Arc, Weak};
|
|||||||
use futures::{self, future, BoxFuture, Future};
|
use futures::{self, future, BoxFuture, Future};
|
||||||
use rlp::{self, UntrustedRlp, View};
|
use rlp::{self, UntrustedRlp, View};
|
||||||
use time::get_time;
|
use time::get_time;
|
||||||
use util::{H160, H256, Address, U256, H64, Uint};
|
use util::{H160, H256, Address, U256, H64};
|
||||||
use util::sha3::Hashable;
|
use util::sha3::Hashable;
|
||||||
use util::Mutex;
|
use util::Mutex;
|
||||||
|
|
||||||
@ -36,14 +36,14 @@ use ethcore::filter::Filter as EthcoreFilter;
|
|||||||
use ethcore::header::{Header as BlockHeader, BlockNumber as EthBlockNumber};
|
use ethcore::header::{Header as BlockHeader, BlockNumber as EthBlockNumber};
|
||||||
use ethcore::log_entry::LogEntry;
|
use ethcore::log_entry::LogEntry;
|
||||||
use ethcore::miner::{MinerService, ExternalMinerService};
|
use ethcore::miner::{MinerService, ExternalMinerService};
|
||||||
use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action};
|
use ethcore::transaction::SignedTransaction;
|
||||||
use ethcore::snapshot::SnapshotService;
|
use ethcore::snapshot::SnapshotService;
|
||||||
use ethsync::{SyncProvider};
|
use ethsync::{SyncProvider};
|
||||||
|
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use jsonrpc_macros::Trailing;
|
use jsonrpc_macros::Trailing;
|
||||||
|
|
||||||
use v1::helpers::{CallRequest as CRequest, errors, limit_logs};
|
use v1::helpers::{errors, limit_logs, fake_sign};
|
||||||
use v1::helpers::dispatch::{Dispatcher, FullDispatcher, default_gas_price};
|
use v1::helpers::dispatch::{Dispatcher, FullDispatcher, default_gas_price};
|
||||||
use v1::helpers::block_import::is_major_importing;
|
use v1::helpers::block_import::is_major_importing;
|
||||||
use v1::traits::Eth;
|
use v1::traits::Eth;
|
||||||
@ -222,19 +222,6 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> EthClient<C, SN, S, M, EM> where
|
|||||||
Ok(Some(block))
|
Ok(Some(block))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sign_call(&self, request: CRequest) -> Result<SignedTransaction, Error> {
|
|
||||||
let (client, miner) = (take_weak!(self.client), take_weak!(self.miner));
|
|
||||||
let from = request.from.unwrap_or(Address::zero());
|
|
||||||
Ok(EthTransaction {
|
|
||||||
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
|
||||||
action: request.to.map_or(Action::Create, Action::Call),
|
|
||||||
gas: request.gas.unwrap_or(U256::from(50_000_000)),
|
|
||||||
gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&*client, &*miner)),
|
|
||||||
value: request.value.unwrap_or_else(U256::zero),
|
|
||||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
|
||||||
}.fake_sign(from))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dapp_accounts(&self, dapp: DappId) -> Result<Vec<H160>, Error> {
|
fn dapp_accounts(&self, dapp: DappId) -> Result<Vec<H160>, Error> {
|
||||||
let store = take_weak!(self.accounts);
|
let store = take_weak!(self.accounts);
|
||||||
store
|
store
|
||||||
@ -654,7 +641,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
|
|
||||||
fn call(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
|
fn call(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<Bytes, Error> {
|
||||||
let request = CallRequest::into(request);
|
let request = CallRequest::into(request);
|
||||||
let signed = match self.sign_call(request) {
|
let signed = match fake_sign::sign_call(&self.client, &self.miner, request) {
|
||||||
Ok(signed) => signed,
|
Ok(signed) => signed,
|
||||||
Err(e) => return future::err(e).boxed(),
|
Err(e) => return future::err(e).boxed(),
|
||||||
};
|
};
|
||||||
@ -672,7 +659,7 @@ impl<C, SN: ?Sized, S: ?Sized, M, EM> Eth for EthClient<C, SN, S, M, EM> where
|
|||||||
|
|
||||||
fn estimate_gas(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
fn estimate_gas(&self, request: CallRequest, num: Trailing<BlockNumber>) -> BoxFuture<RpcU256, Error> {
|
||||||
let request = CallRequest::into(request);
|
let request = CallRequest::into(request);
|
||||||
let signed = match self.sign_call(request) {
|
let signed = match fake_sign::sign_call(&self.client, &self.miner, request) {
|
||||||
Ok(signed) => signed,
|
Ok(signed) => signed,
|
||||||
Err(e) => return future::err(e).boxed(),
|
Err(e) => return future::err(e).boxed(),
|
||||||
};
|
};
|
||||||
|
@ -27,15 +27,15 @@ use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, By
|
|||||||
pub struct TracesClient;
|
pub struct TracesClient;
|
||||||
|
|
||||||
impl Traces for TracesClient {
|
impl Traces for TracesClient {
|
||||||
fn filter(&self, _filter: TraceFilter) -> Result<Vec<LocalizedTrace>, Error> {
|
fn filter(&self, _filter: TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_traces(&self, _block_number: BlockNumber) -> Result<Vec<LocalizedTrace>, Error> {
|
fn block_traces(&self, _block_number: BlockNumber) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_traces(&self, _transaction_hash: H256) -> Result<Vec<LocalizedTrace>, Error> {
|
fn transaction_traces(&self, _transaction_hash: H256) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,15 +43,15 @@ impl Traces for TracesClient {
|
|||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, _request: CallRequest, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> {
|
fn call(&self, _request: CallRequest, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raw_transaction(&self, _raw_transaction: Bytes, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> {
|
fn raw_transaction(&self, _raw_transaction: Bytes, _flags: Vec<String>, _block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replay_transaction(&self, _transaction_hash: H256, _flags: Vec<String>) -> Result<Option<TraceResults>, Error> {
|
fn replay_transaction(&self, _transaction_hash: H256, _flags: Vec<String>) -> Result<TraceResults, Error> {
|
||||||
Err(errors::light_unimplemented(None))
|
Err(errors::light_unimplemented(None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,14 @@
|
|||||||
use std::sync::{Weak, Arc};
|
use std::sync::{Weak, Arc};
|
||||||
|
|
||||||
use rlp::{UntrustedRlp, View};
|
use rlp::{UntrustedRlp, View};
|
||||||
use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId};
|
use ethcore::client::{MiningBlockChainClient, CallAnalytics, TransactionId, TraceId};
|
||||||
use ethcore::miner::MinerService;
|
use ethcore::miner::MinerService;
|
||||||
use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action};
|
use ethcore::transaction::SignedTransaction;
|
||||||
|
|
||||||
use jsonrpc_core::Error;
|
use jsonrpc_core::Error;
|
||||||
use jsonrpc_macros::Trailing;
|
use jsonrpc_macros::Trailing;
|
||||||
use v1::traits::Traces;
|
use v1::traits::Traces;
|
||||||
use v1::helpers::{errors, CallRequest as CRequest};
|
use v1::helpers::{errors, fake_sign};
|
||||||
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256};
|
||||||
|
|
||||||
fn to_call_analytics(flags: Vec<String>) -> CallAnalytics {
|
fn to_call_analytics(flags: Vec<String>) -> CallAnalytics {
|
||||||
@ -38,12 +38,12 @@ fn to_call_analytics(flags: Vec<String>) -> CallAnalytics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Traces api implementation.
|
/// Traces api implementation.
|
||||||
pub struct TracesClient<C, M> where C: BlockChainClient, M: MinerService {
|
pub struct TracesClient<C, M> {
|
||||||
client: Weak<C>,
|
client: Weak<C>,
|
||||||
miner: Weak<M>,
|
miner: Weak<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> TracesClient<C, M> where C: BlockChainClient, M: MinerService {
|
impl<C, M> TracesClient<C, M> {
|
||||||
/// Creates new Traces client.
|
/// Creates new Traces client.
|
||||||
pub fn new(client: &Arc<C>, miner: &Arc<M>) -> Self {
|
pub fn new(client: &Arc<C>, miner: &Arc<M>) -> Self {
|
||||||
TracesClient {
|
TracesClient {
|
||||||
@ -51,86 +51,59 @@ impl<C, M> TracesClient<C, M> where C: BlockChainClient, M: MinerService {
|
|||||||
miner: Arc::downgrade(miner),
|
miner: Arc::downgrade(miner),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: share with eth.rs
|
|
||||||
fn sign_call(&self, request: CRequest) -> Result<SignedTransaction, Error> {
|
|
||||||
let client = take_weak!(self.client);
|
|
||||||
let miner = take_weak!(self.miner);
|
|
||||||
let from = request.from.unwrap_or(0.into());
|
|
||||||
Ok(EthTransaction {
|
|
||||||
nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)),
|
|
||||||
action: request.to.map_or(Action::Create, Action::Call),
|
|
||||||
gas: request.gas.unwrap_or(50_000_000.into()),
|
|
||||||
gas_price: request.gas_price.unwrap_or_else(|| miner.sensible_gas_price()),
|
|
||||||
value: request.value.unwrap_or(0.into()),
|
|
||||||
data: request.data.map_or_else(Vec::new, |d| d.to_vec())
|
|
||||||
}.fake_sign(from))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> Traces for TracesClient<C, M> where C: BlockChainClient + 'static, M: MinerService + 'static {
|
impl<C, M> Traces for TracesClient<C, M> where C: MiningBlockChainClient + 'static, M: MinerService + 'static {
|
||||||
fn filter(&self, filter: TraceFilter) -> Result<Vec<LocalizedTrace>, Error> {
|
fn filter(&self, filter: TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
let client = take_weak!(self.client);
|
Ok(take_weak!(self.client).filter_traces(filter.into())
|
||||||
let traces = client.filter_traces(filter.into());
|
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
||||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
|
||||||
Ok(traces)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_traces(&self, block_number: BlockNumber) -> Result<Vec<LocalizedTrace>, Error> {
|
fn block_traces(&self, block_number: BlockNumber) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
let client = take_weak!(self.client);
|
Ok(take_weak!(self.client).block_traces(block_number.into())
|
||||||
let traces = client.block_traces(block_number.into());
|
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
||||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
|
||||||
Ok(traces)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_traces(&self, transaction_hash: H256) -> Result<Vec<LocalizedTrace>, Error> {
|
fn transaction_traces(&self, transaction_hash: H256) -> Result<Option<Vec<LocalizedTrace>>, Error> {
|
||||||
let client = take_weak!(self.client);
|
Ok(take_weak!(self.client).transaction_traces(TransactionId::Hash(transaction_hash.into()))
|
||||||
let traces = client.transaction_traces(TransactionId::Hash(transaction_hash.into()));
|
.map(|traces| traces.into_iter().map(LocalizedTrace::from).collect()))
|
||||||
let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect());
|
|
||||||
Ok(traces)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trace(&self, transaction_hash: H256, address: Vec<Index>) -> Result<Option<LocalizedTrace>, Error> {
|
fn trace(&self, transaction_hash: H256, address: Vec<Index>) -> Result<Option<LocalizedTrace>, Error> {
|
||||||
let client = take_weak!(self.client);
|
|
||||||
let id = TraceId {
|
let id = TraceId {
|
||||||
transaction: TransactionId::Hash(transaction_hash.into()),
|
transaction: TransactionId::Hash(transaction_hash.into()),
|
||||||
address: address.into_iter().map(|i| i.value()).collect()
|
address: address.into_iter().map(|i| i.value()).collect()
|
||||||
};
|
};
|
||||||
let trace = client.trace(id);
|
|
||||||
let trace = trace.map(LocalizedTrace::from);
|
|
||||||
|
|
||||||
Ok(trace)
|
Ok(take_weak!(self.client).trace(id)
|
||||||
|
.map(LocalizedTrace::from))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&self, request: CallRequest, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> {
|
fn call(&self, request: CallRequest, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||||
let block = block.0;
|
let block = block.0;
|
||||||
|
|
||||||
let request = CallRequest::into(request);
|
let request = CallRequest::into(request);
|
||||||
let signed = self.sign_call(request)?;
|
let signed = fake_sign::sign_call(&self.client, &self.miner, request)?;
|
||||||
Ok(match take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags)) {
|
|
||||||
Ok(e) => Some(TraceResults::from(e)),
|
take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags))
|
||||||
_ => None,
|
.map(TraceResults::from)
|
||||||
})
|
.map_err(errors::from_call_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn raw_transaction(&self, raw_transaction: Bytes, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> {
|
fn raw_transaction(&self, raw_transaction: Bytes, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<TraceResults, Error> {
|
||||||
let block = block.0;
|
let block = block.0;
|
||||||
|
|
||||||
UntrustedRlp::new(&raw_transaction.into_vec()).as_val()
|
let tx = UntrustedRlp::new(&raw_transaction.into_vec()).as_val().map_err(|e| errors::invalid_params("Transaction is not valid RLP", e))?;
|
||||||
.map_err(|e| errors::invalid_params("Transaction is not valid RLP", e))
|
let signed = SignedTransaction::new(tx).map_err(errors::from_transaction_error)?;
|
||||||
.and_then(|tx| SignedTransaction::new(tx).map_err(errors::from_transaction_error))
|
|
||||||
.and_then(|signed| {
|
take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags))
|
||||||
Ok(match take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags)) {
|
.map(TraceResults::from)
|
||||||
Ok(e) => Some(TraceResults::from(e)),
|
.map_err(errors::from_call_error)
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replay_transaction(&self, transaction_hash: H256, flags: Vec<String>) -> Result<Option<TraceResults>, Error> {
|
fn replay_transaction(&self, transaction_hash: H256, flags: Vec<String>) -> Result<TraceResults, Error> {
|
||||||
Ok(match take_weak!(self.client).replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags)) {
|
take_weak!(self.client).replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags))
|
||||||
Ok(e) => Some(TraceResults::from(e)),
|
.map(TraceResults::from)
|
||||||
_ => None,
|
.map_err(errors::from_call_error)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,7 +357,7 @@ fn rpc_parity_unsigned_transactions_count_when_signer_disabled() {
|
|||||||
let io = deps.default_client();
|
let io = deps.default_client();
|
||||||
|
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_unsignedTransactionsCount", "params":[], "id": 1}"#;
|
||||||
let response = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
||||||
|
|
||||||
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
@ -393,7 +393,7 @@ fn rpc_parity_signer_port() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_signerPort", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_signerPort", "params": [], "id": 1}"#;
|
||||||
let response1 = r#"{"jsonrpc":"2.0","result":18180,"id":1}"#;
|
let response1 = r#"{"jsonrpc":"2.0","result":18180,"id":1}"#;
|
||||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
||||||
@ -411,7 +411,7 @@ fn rpc_parity_dapps_port() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsPort", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsPort", "params": [], "id": 1}"#;
|
||||||
let response1 = r#"{"jsonrpc":"2.0","result":18080,"id":1}"#;
|
let response1 = r#"{"jsonrpc":"2.0","result":18080,"id":1}"#;
|
||||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32031,"message":"Dapps Server is disabled. This API is not available.","data":null},"id":1}"#;
|
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Dapps Server is disabled. This API is not available.","data":null},"id":1}"#;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
||||||
@ -429,7 +429,7 @@ fn rpc_parity_dapps_interface() {
|
|||||||
// when
|
// when
|
||||||
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsInterface", "params": [], "id": 1}"#;
|
let request = r#"{"jsonrpc": "2.0", "method": "parity_dappsInterface", "params": [], "id": 1}"#;
|
||||||
let response1 = r#"{"jsonrpc":"2.0","result":"127.0.0.1","id":1}"#;
|
let response1 = r#"{"jsonrpc":"2.0","result":"127.0.0.1","id":1}"#;
|
||||||
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32031,"message":"Dapps Server is disabled. This API is not available.","data":null},"id":1}"#;
|
let response2 = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"Dapps Server is disabled. This API is not available.","data":null},"id":1}"#;
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
assert_eq!(io1.handle_request_sync(request), Some(response1.to_owned()));
|
||||||
|
@ -16,17 +16,17 @@
|
|||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ethcore::executed::{CallType, Executed};
|
use ethcore::executed::{CallType, Executed, CallError};
|
||||||
use ethcore::trace::trace::{Action, Res, Call};
|
use ethcore::trace::trace::{Action, Res, Call};
|
||||||
use ethcore::trace::LocalizedTrace;
|
use ethcore::trace::LocalizedTrace;
|
||||||
use ethcore::client::{TestBlockChainClient};
|
use ethcore::client::TestBlockChainClient;
|
||||||
|
|
||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
use v1::tests::helpers::{TestMinerService};
|
use v1::tests::helpers::{TestMinerService};
|
||||||
use v1::{Traces, TracesClient};
|
use v1::{Traces, TracesClient};
|
||||||
|
|
||||||
struct Tester {
|
struct Tester {
|
||||||
_client: Arc<TestBlockChainClient>,
|
client: Arc<TestBlockChainClient>,
|
||||||
_miner: Arc<TestMinerService>,
|
_miner: Arc<TestMinerService>,
|
||||||
io: IoHandler,
|
io: IoHandler,
|
||||||
}
|
}
|
||||||
@ -69,7 +69,7 @@ fn io() -> Tester {
|
|||||||
io.extend_with(traces.to_delegate());
|
io.extend_with(traces.to_delegate());
|
||||||
|
|
||||||
Tester {
|
Tester {
|
||||||
_client: client,
|
client: client,
|
||||||
_miner: miner,
|
_miner: miner,
|
||||||
io: io,
|
io: io,
|
||||||
}
|
}
|
||||||
@ -85,6 +85,17 @@ fn rpc_trace_filter() {
|
|||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_trace_filter_missing_trace() {
|
||||||
|
let tester = io();
|
||||||
|
*tester.client.traces.write() = None;
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc":"2.0","method":"trace_filter","params": [{}],"id":1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_trace_block() {
|
fn rpc_trace_block() {
|
||||||
let tester = io();
|
let tester = io();
|
||||||
@ -95,6 +106,17 @@ fn rpc_trace_block() {
|
|||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_trace_block_missing_traces() {
|
||||||
|
let tester = io();
|
||||||
|
*tester.client.traces.write() = None;
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc":"2.0","method":"trace_block","params": ["0x10"],"id":1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_trace_transaction() {
|
fn rpc_trace_transaction() {
|
||||||
let tester = io();
|
let tester = io();
|
||||||
@ -105,6 +127,17 @@ fn rpc_trace_transaction() {
|
|||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_trace_transaction_missing_trace() {
|
||||||
|
let tester = io();
|
||||||
|
*tester.client.traces.write() = None;
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc":"2.0","method":"trace_transaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005"],"id":1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_trace_get() {
|
fn rpc_trace_get() {
|
||||||
let tester = io();
|
let tester = io();
|
||||||
@ -115,6 +148,16 @@ fn rpc_trace_get() {
|
|||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_trace_get_missing_trace() {
|
||||||
|
let tester = io();
|
||||||
|
*tester.client.traces.write() = None;
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc":"2.0","method":"trace_get","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["0","0","0"]],"id":1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_trace_call() {
|
fn rpc_trace_call() {
|
||||||
let tester = io();
|
let tester = io();
|
||||||
@ -125,6 +168,17 @@ fn rpc_trace_call() {
|
|||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_trace_call_state_pruned() {
|
||||||
|
let tester = io();
|
||||||
|
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc":"2.0","method":"trace_call","params":[{}, ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive.","data":null},"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_trace_raw_transaction() {
|
fn rpc_trace_raw_transaction() {
|
||||||
let tester = io();
|
let tester = io();
|
||||||
@ -135,6 +189,17 @@ fn rpc_trace_raw_transaction() {
|
|||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_trace_raw_transaction_state_pruned() {
|
||||||
|
let tester = io();
|
||||||
|
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc":"2.0","method":"trace_rawTransaction","params":["0xf869018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72a801ba0617f39c1a107b63302449c476d96a6cb17a5842fc98ff0c5bcf4d5c4d8166b95a009fdb6097c6196b9bbafc3a59f02f38d91baeef23d0c60a8e4f23c7714cea3a9", ["stateDiff", "vmTrace", "trace"]],"id":1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive.","data":null},"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rpc_trace_replay_transaction() {
|
fn rpc_trace_replay_transaction() {
|
||||||
let tester = io();
|
let tester = io();
|
||||||
@ -144,3 +209,14 @@ fn rpc_trace_replay_transaction() {
|
|||||||
|
|
||||||
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_trace_replay_transaction_state_pruned() {
|
||||||
|
let tester = io();
|
||||||
|
*tester.client.execution_result.write() = Some(Err(CallError::StatePruned));
|
||||||
|
|
||||||
|
let request = r#"{"jsonrpc":"2.0","method":"trace_replayTransaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["trace", "stateDiff", "vmTrace"]],"id":1}"#;
|
||||||
|
let response = r#"{"jsonrpc":"2.0","error":{"code":-32000,"message":"This request is not supported because your node is running with state pruning. Run with --pruning=archive.","data":null},"id":1}"#;
|
||||||
|
|
||||||
|
assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned()));
|
||||||
|
}
|
||||||
|
@ -25,7 +25,7 @@ build_rpc_trait! {
|
|||||||
pub trait Traces {
|
pub trait Traces {
|
||||||
/// Returns traces matching given filter.
|
/// Returns traces matching given filter.
|
||||||
#[rpc(name = "trace_filter")]
|
#[rpc(name = "trace_filter")]
|
||||||
fn filter(&self, TraceFilter) -> Result<Vec<LocalizedTrace>, Error>;
|
fn filter(&self, TraceFilter) -> Result<Option<Vec<LocalizedTrace>>, Error>;
|
||||||
|
|
||||||
/// Returns transaction trace at given index.
|
/// Returns transaction trace at given index.
|
||||||
#[rpc(name = "trace_get")]
|
#[rpc(name = "trace_get")]
|
||||||
@ -33,22 +33,22 @@ build_rpc_trait! {
|
|||||||
|
|
||||||
/// Returns all traces of given transaction.
|
/// Returns all traces of given transaction.
|
||||||
#[rpc(name = "trace_transaction")]
|
#[rpc(name = "trace_transaction")]
|
||||||
fn transaction_traces(&self, H256) -> Result<Vec<LocalizedTrace>, Error>;
|
fn transaction_traces(&self, H256) -> Result<Option<Vec<LocalizedTrace>>, Error>;
|
||||||
|
|
||||||
/// Returns all traces produced at given block.
|
/// Returns all traces produced at given block.
|
||||||
#[rpc(name = "trace_block")]
|
#[rpc(name = "trace_block")]
|
||||||
fn block_traces(&self, BlockNumber) -> Result<Vec<LocalizedTrace>, Error>;
|
fn block_traces(&self, BlockNumber) -> Result<Option<Vec<LocalizedTrace>>, Error>;
|
||||||
|
|
||||||
/// Executes the given call and returns a number of possible traces for it.
|
/// Executes the given call and returns a number of possible traces for it.
|
||||||
#[rpc(name = "trace_call")]
|
#[rpc(name = "trace_call")]
|
||||||
fn call(&self, CallRequest, Vec<String>, Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error>;
|
fn call(&self, CallRequest, Vec<String>, Trailing<BlockNumber>) -> Result<TraceResults, Error>;
|
||||||
|
|
||||||
/// Executes the given raw transaction and returns a number of possible traces for it.
|
/// Executes the given raw transaction and returns a number of possible traces for it.
|
||||||
#[rpc(name = "trace_rawTransaction")]
|
#[rpc(name = "trace_rawTransaction")]
|
||||||
fn raw_transaction(&self, Bytes, Vec<String>, Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error>;
|
fn raw_transaction(&self, Bytes, Vec<String>, Trailing<BlockNumber>) -> Result<TraceResults, Error>;
|
||||||
|
|
||||||
/// Executes the transaction with the given hash and returns a number of possible traces for it.
|
/// Executes the transaction with the given hash and returns a number of possible traces for it.
|
||||||
#[rpc(name = "trace_replayTransaction")]
|
#[rpc(name = "trace_replayTransaction")]
|
||||||
fn replay_transaction(&self, H256, Vec<String>) -> Result<Option<TraceResults>, Error>;
|
fn replay_transaction(&self, H256, Vec<String>) -> Result<TraceResults, Error>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user