Merge pull request #3844 from ethcore/trace-macros
Converting traces API to AutoArgs
This commit is contained in:
		
						commit
						817a58cf64
					
				| @ -90,6 +90,8 @@ pub struct TestBlockChainClient { | |||||||
| 	pub ancient_block: RwLock<Option<(H256, u64)>>, | 	pub ancient_block: RwLock<Option<(H256, u64)>>, | ||||||
| 	/// First block info.
 | 	/// First block info.
 | ||||||
| 	pub first_block: RwLock<Option<(H256, u64)>>, | 	pub first_block: RwLock<Option<(H256, u64)>>, | ||||||
|  | 	/// Traces to return
 | ||||||
|  | 	pub traces: RwLock<Option<Vec<LocalizedTrace>>>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Used for generating test client blocks.
 | /// Used for generating test client blocks.
 | ||||||
| @ -151,6 +153,7 @@ impl TestBlockChainClient { | |||||||
| 			latest_block_timestamp: RwLock::new(10_000_000), | 			latest_block_timestamp: RwLock::new(10_000_000), | ||||||
| 			ancient_block: RwLock::new(None), | 			ancient_block: RwLock::new(None), | ||||||
| 			first_block: RwLock::new(None), | 			first_block: RwLock::new(None), | ||||||
|  | 			traces: RwLock::new(None), | ||||||
| 		}; | 		}; | ||||||
| 		client.add_blocks(1, EachBlockWith::Nothing); // add genesis block
 | 		client.add_blocks(1, EachBlockWith::Nothing); // add genesis block
 | ||||||
| 		client.genesis_hash = client.last_hash.read().clone(); | 		client.genesis_hash = client.last_hash.read().clone(); | ||||||
| @ -654,19 +657,19 @@ impl BlockChainClient for TestBlockChainClient { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn filter_traces(&self, _filter: TraceFilter) -> Option<Vec<LocalizedTrace>> { | 	fn filter_traces(&self, _filter: TraceFilter) -> Option<Vec<LocalizedTrace>> { | ||||||
| 		unimplemented!(); | 		self.traces.read().clone() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn trace(&self, _trace: TraceId) -> Option<LocalizedTrace> { | 	fn trace(&self, _trace: TraceId) -> Option<LocalizedTrace> { | ||||||
| 		unimplemented!(); | 		self.traces.read().clone().and_then(|vec| vec.into_iter().next()) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn transaction_traces(&self, _trace: TransactionId) -> Option<Vec<LocalizedTrace>> { | 	fn transaction_traces(&self, _trace: TransactionId) -> Option<Vec<LocalizedTrace>> { | ||||||
| 		unimplemented!(); | 		self.traces.read().clone() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn block_traces(&self, _trace: BlockId) -> Option<Vec<LocalizedTrace>> { | 	fn block_traces(&self, _trace: BlockId) -> Option<Vec<LocalizedTrace>> { | ||||||
| 		unimplemented!(); | 		self.traces.read().clone() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn queue_transactions(&self, transactions: Vec<Bytes>, _peer_id: usize) { | 	fn queue_transactions(&self, transactions: Vec<Bytes>, _peer_id: usize) { | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ use super::trace::{Action, Res}; | |||||||
| use header::BlockNumber; | use header::BlockNumber; | ||||||
| 
 | 
 | ||||||
| /// Localized trace.
 | /// Localized trace.
 | ||||||
| #[derive(Debug, PartialEq, Binary)] | #[derive(Debug, PartialEq, Clone, Binary)] | ||||||
| pub struct LocalizedTrace { | pub struct LocalizedTrace { | ||||||
| 	/// Type of action performed by a transaction.
 | 	/// Type of action performed by a transaction.
 | ||||||
| 	pub action: Action, | 	pub action: Action, | ||||||
|  | |||||||
| @ -17,14 +17,14 @@ | |||||||
| //! Traces api implementation.
 | //! Traces api implementation.
 | ||||||
| 
 | 
 | ||||||
| use std::sync::{Weak, Arc}; | use std::sync::{Weak, Arc}; | ||||||
| use jsonrpc_core::*; |  | ||||||
| use serde; |  | ||||||
| 
 | 
 | ||||||
| use rlp::{UntrustedRlp, View}; | use rlp::{UntrustedRlp, View}; | ||||||
| use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId}; | use ethcore::client::{BlockChainClient, CallAnalytics, TransactionId, TraceId}; | ||||||
| use ethcore::miner::MinerService; | use ethcore::miner::MinerService; | ||||||
| use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action}; | use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Action}; | ||||||
| 
 | 
 | ||||||
|  | use jsonrpc_core::Error; | ||||||
|  | use jsonrpc_macros::Trailing; | ||||||
| use v1::traits::Traces; | use v1::traits::Traces; | ||||||
| use v1::helpers::{errors, CallRequest as CRequest}; | use v1::helpers::{errors, CallRequest as CRequest}; | ||||||
| use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256}; | use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256}; | ||||||
| @ -37,22 +37,6 @@ fn to_call_analytics(flags: Vec<String>) -> CallAnalytics { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Returns number of different parameters in given `Params` object.
 |  | ||||||
| fn params_len(params: &Params) -> usize { |  | ||||||
| 	match params { |  | ||||||
| 		&Params::Array(ref vec) => vec.len(), |  | ||||||
| 		_ => 0, |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// Deserialize request parameters with optional third parameter `BlockNumber` defaulting to `BlockNumber::Latest`.
 |  | ||||||
| fn from_params_default_third<F1, F2>(params: Params) -> Result<(F1, F2, BlockNumber, ), Error> where F1: serde::de::Deserialize, F2: serde::de::Deserialize { |  | ||||||
| 	match params_len(¶ms) { |  | ||||||
| 		2 => from_params::<(F1, F2, )>(params).map(|(f1, f2)| (f1, f2, BlockNumber::Latest)), |  | ||||||
| 		_ => from_params::<(F1, F2, BlockNumber)>(params) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// Traces api implementation.
 | /// Traces api implementation.
 | ||||||
| pub struct TracesClient<C, M> where C: BlockChainClient, M: MinerService { | pub struct TracesClient<C, M> where C: BlockChainClient, M: MinerService { | ||||||
| 	client: Weak<C>, | 	client: Weak<C>, | ||||||
| @ -91,90 +75,77 @@ impl<C, M> TracesClient<C, M> where C: BlockChainClient, M: MinerService { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 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: BlockChainClient + 'static, M: MinerService + 'static { | ||||||
| 	fn filter(&self, params: Params) -> Result<Value, Error> { | 	fn filter(&self, filter: TraceFilter) -> Result<Vec<LocalizedTrace>, Error> { | ||||||
| 		try!(self.active()); | 		try!(self.active()); | ||||||
| 		from_params::<(TraceFilter,)>(params) | 
 | ||||||
| 			.and_then(|(filter, )| { | 		let client = take_weak!(self.client); | ||||||
| 				let client = take_weak!(self.client); | 		let traces = client.filter_traces(filter.into()); | ||||||
| 				let traces = client.filter_traces(filter.into()); | 		let traces = traces.map_or_else(Vec::new, |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) | ||||||
| 				Ok(to_value(&traces)) |  | ||||||
| 			}) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn block_traces(&self, params: Params) -> Result<Value, Error> { | 	fn block_traces(&self, block_number: BlockNumber) -> Result<Vec<LocalizedTrace>, Error> { | ||||||
| 		try!(self.active()); | 		try!(self.active()); | ||||||
| 		from_params::<(BlockNumber,)>(params) | 		let client = take_weak!(self.client); | ||||||
| 			.and_then(|(block_number,)| { | 		let traces = client.block_traces(block_number.into()); | ||||||
| 				let client = take_weak!(self.client); | 		let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect()); | ||||||
| 				let traces = client.block_traces(block_number.into()); | 		Ok(traces) | ||||||
| 				let traces = traces.map_or_else(Vec::new, |traces| traces.into_iter().map(LocalizedTrace::from).collect()); |  | ||||||
| 				Ok(to_value(&traces)) |  | ||||||
| 			}) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn transaction_traces(&self, params: Params) -> Result<Value, Error> { | 	fn transaction_traces(&self, transaction_hash: H256) -> Result<Vec<LocalizedTrace>, Error> { | ||||||
| 		try!(self.active()); | 		try!(self.active()); | ||||||
| 		from_params::<(H256,)>(params) | 
 | ||||||
| 			.and_then(|(transaction_hash,)| { | 		let client = take_weak!(self.client); | ||||||
| 				let client = take_weak!(self.client); | 		let traces = client.transaction_traces(TransactionId::Hash(transaction_hash.into())); | ||||||
| 				let traces = client.transaction_traces(TransactionId::Hash(transaction_hash.into())); | 		let traces = traces.map_or_else(Vec::new, |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) | ||||||
| 				Ok(to_value(&traces)) |  | ||||||
| 			}) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn trace(&self, params: Params) -> Result<Value, Error> { | 	fn trace(&self, transaction_hash: H256, address: Vec<Index>) -> Result<Option<LocalizedTrace>, Error> { | ||||||
| 		try!(self.active()); | 		try!(self.active()); | ||||||
| 		from_params::<(H256, Vec<Index>)>(params) | 		let client = take_weak!(self.client); | ||||||
| 			.and_then(|(transaction_hash, address)| { | 		let id = TraceId { | ||||||
| 				let client = take_weak!(self.client); | 			transaction: TransactionId::Hash(transaction_hash.into()), | ||||||
| 				let id = TraceId { | 			address: address.into_iter().map(|i| i.value()).collect() | ||||||
| 					transaction: TransactionId::Hash(transaction_hash.into()), | 		}; | ||||||
| 					address: address.into_iter().map(|i| i.value()).collect() | 		let trace = client.trace(id); | ||||||
| 				}; | 		let trace = trace.map(LocalizedTrace::from); | ||||||
| 				let trace = client.trace(id); | 
 | ||||||
| 				let trace = trace.map(LocalizedTrace::from); | 		Ok(trace) | ||||||
| 				Ok(to_value(&trace)) |  | ||||||
| 			}) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn call(&self, params: Params) -> Result<Value, Error> { | 	fn call(&self, request: CallRequest, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> { | ||||||
| 		try!(self.active()); | 		try!(self.active()); | ||||||
| 		from_params_default_third(params) | 		let block = block.0; | ||||||
| 			.and_then(|(request, flags, block)| { | 
 | ||||||
| 				let request = CallRequest::into(request); | 		let request = CallRequest::into(request); | ||||||
| 				let signed = try!(self.sign_call(request)); | 		let signed = try!(self.sign_call(request)); | ||||||
| 				match 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)) { | ||||||
| 					Ok(e) => Ok(to_value(&TraceResults::from(e))), | 			Ok(e) => Some(TraceResults::from(e)), | ||||||
| 					_ => Ok(Value::Null), | 			_ => None, | ||||||
| 				} | 		}) | ||||||
| 			}) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn raw_transaction(&self, params: Params) -> Result<Value, Error> { | 	fn raw_transaction(&self, raw_transaction: Bytes, flags: Vec<String>, block: Trailing<BlockNumber>) -> Result<Option<TraceResults>, Error> { | ||||||
| 		try!(self.active()); | 		try!(self.active()); | ||||||
| 		from_params_default_third(params) | 		let block = block.0; | ||||||
| 			.and_then(|(raw_transaction, flags, block)| { | 
 | ||||||
| 				let raw_transaction = Bytes::to_vec(raw_transaction); | 		let raw_transaction = Bytes::to_vec(raw_transaction); | ||||||
| 				match UntrustedRlp::new(&raw_transaction).as_val() { | 		match UntrustedRlp::new(&raw_transaction).as_val() { | ||||||
| 					Ok(signed) => match take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags)) { | 			Ok(signed) => Ok(match take_weak!(self.client).call(&signed, block.into(), to_call_analytics(flags)) { | ||||||
| 						Ok(e) => Ok(to_value(&TraceResults::from(e))), | 				Ok(e) => Some(TraceResults::from(e)), | ||||||
| 						_ => Ok(Value::Null), | 				_ => None, | ||||||
| 					}, | 			}), | ||||||
| 					Err(e) => Err(errors::invalid_params("Transaction is not valid RLP", e)), | 			Err(e) => Err(errors::invalid_params("Transaction is not valid RLP", e)), | ||||||
| 				} | 		} | ||||||
| 			}) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	fn replay_transaction(&self, params: Params) -> Result<Value, Error> { | 	fn replay_transaction(&self, transaction_hash: H256, flags: Vec<String>) -> Result<Option<TraceResults>, Error> { | ||||||
| 		try!(self.active()); | 		try!(self.active()); | ||||||
| 		from_params::<(H256, _)>(params) | 
 | ||||||
| 			.and_then(|(transaction_hash, flags)| { | 		Ok(match take_weak!(self.client).replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags)) { | ||||||
| 				match take_weak!(self.client).replay(TransactionId::Hash(transaction_hash.into()), to_call_analytics(flags)) { | 			Ok(e) => Some(TraceResults::from(e)), | ||||||
| 					Ok(e) => Ok(to_value(&TraceResults::from(e))), | 			_ => None, | ||||||
| 					_ => Ok(Value::Null), | 		}) | ||||||
| 				} |  | ||||||
| 			}) |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,13 +18,14 @@ | |||||||
| //! method calls properly.
 | //! method calls properly.
 | ||||||
| 
 | 
 | ||||||
| mod eth; | mod eth; | ||||||
|  | mod manage_network; | ||||||
| mod net; | mod net; | ||||||
| mod web3; |  | ||||||
| mod personal; |  | ||||||
| mod parity; | mod parity; | ||||||
| mod parity_accounts; | mod parity_accounts; | ||||||
| mod parity_set; | mod parity_set; | ||||||
|  | mod personal; | ||||||
| mod rpc; | mod rpc; | ||||||
| mod signer; | mod signer; | ||||||
| mod signing; | mod signing; | ||||||
| mod manage_network; | mod traces; | ||||||
|  | mod web3; | ||||||
|  | |||||||
							
								
								
									
										145
									
								
								rpc/src/v1/tests/mocked/traces.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								rpc/src/v1/tests/mocked/traces.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,145 @@ | |||||||
|  | // Copyright 2015, 2016 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::Arc; | ||||||
|  | 
 | ||||||
|  | use ethcore::executed::{CallType, Executed}; | ||||||
|  | use ethcore::trace::trace::{Action, Res, Call}; | ||||||
|  | use ethcore::trace::LocalizedTrace; | ||||||
|  | use ethcore::client::{TestBlockChainClient}; | ||||||
|  | 
 | ||||||
|  | use jsonrpc_core::{IoHandler, GenericIoHandler}; | ||||||
|  | use v1::tests::helpers::{TestMinerService}; | ||||||
|  | use v1::{Traces, TracesClient}; | ||||||
|  | 
 | ||||||
|  | struct Tester { | ||||||
|  | 	_client: Arc<TestBlockChainClient>, | ||||||
|  | 	_miner: Arc<TestMinerService>, | ||||||
|  | 	io: IoHandler, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn io() -> Tester { | ||||||
|  | 	let client = Arc::new(TestBlockChainClient::new()); | ||||||
|  | 	*client.traces.write() = Some(vec![LocalizedTrace { | ||||||
|  | 		action: Action::Call(Call { | ||||||
|  | 			from: 0xf.into(), | ||||||
|  | 			to: 0x10.into(), | ||||||
|  | 			value: 0x1.into(), | ||||||
|  | 			gas: 0x100.into(), | ||||||
|  | 			input: vec![1, 2, 3], | ||||||
|  | 			call_type: CallType::Call, | ||||||
|  | 		}), | ||||||
|  | 		result: Res::None, | ||||||
|  | 		subtraces: 0, | ||||||
|  | 		trace_address: vec![0], | ||||||
|  | 		transaction_number: 0, | ||||||
|  | 		transaction_hash: 5.into(), | ||||||
|  | 		block_number: 10, | ||||||
|  | 		block_hash: 10.into(), | ||||||
|  | 	}]); | ||||||
|  | 	*client.execution_result.write() = Some(Ok(Executed { | ||||||
|  | 		gas: 20_000.into(), | ||||||
|  | 		gas_used: 10_000.into(), | ||||||
|  | 		refunded: 0.into(), | ||||||
|  | 		cumulative_gas_used: 10_000.into(), | ||||||
|  | 		logs: vec![], | ||||||
|  | 		contracts_created: vec![], | ||||||
|  | 		output: vec![1, 2, 3], | ||||||
|  | 		trace: vec![], | ||||||
|  | 		vm_trace: None, | ||||||
|  | 		state_diff: None, | ||||||
|  | 	})); | ||||||
|  | 	let miner = Arc::new(TestMinerService::default()); | ||||||
|  | 	let traces = TracesClient::new(&client, &miner); | ||||||
|  | 	let io = IoHandler::new(); | ||||||
|  | 	io.add_delegate(traces.to_delegate()); | ||||||
|  | 
 | ||||||
|  | 	Tester { | ||||||
|  | 		_client: client, | ||||||
|  | 		_miner: miner, | ||||||
|  | 		io: io, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn rpc_trace_filter() { | ||||||
|  | 	let tester = io(); | ||||||
|  | 
 | ||||||
|  | 	let request = r#"{"jsonrpc":"2.0","method":"trace_filter","params": [{}],"id":1}"#; | ||||||
|  | 	let response = r#"{"jsonrpc":"2.0","result":[{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"}],"id":1}"#; | ||||||
|  | 
 | ||||||
|  | 	assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn rpc_trace_block() { | ||||||
|  | 	let tester = io(); | ||||||
|  | 
 | ||||||
|  | 	let request = r#"{"jsonrpc":"2.0","method":"trace_block","params": ["0x10"],"id":1}"#; | ||||||
|  | 	let response = r#"{"jsonrpc":"2.0","result":[{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"}],"id":1}"#; | ||||||
|  | 
 | ||||||
|  | 	assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn rpc_trace_transaction() { | ||||||
|  | 	let tester = io(); | ||||||
|  | 
 | ||||||
|  | 	let request = r#"{"jsonrpc":"2.0","method":"trace_transaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005"],"id":1}"#; | ||||||
|  | 	let response = r#"{"jsonrpc":"2.0","result":[{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"}],"id":1}"#; | ||||||
|  | 
 | ||||||
|  | 	assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn rpc_trace_get() { | ||||||
|  | 	let tester = io(); | ||||||
|  | 
 | ||||||
|  | 	let request = r#"{"jsonrpc":"2.0","method":"trace_get","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["0","0","0"]],"id":1}"#; | ||||||
|  | 	let response = r#"{"jsonrpc":"2.0","result":{"action":{"callType":"call","from":"0x000000000000000000000000000000000000000f","gas":"0x100","input":"0x010203","to":"0x0000000000000000000000000000000000000010","value":"0x1"},"blockHash":"0x000000000000000000000000000000000000000000000000000000000000000a","blockNumber":10,"result":null,"subtraces":0,"traceAddress":[0],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000005","transactionPosition":0,"type":"call"},"id":1}"#; | ||||||
|  | 
 | ||||||
|  | 	assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn rpc_trace_call() { | ||||||
|  | 	let tester = io(); | ||||||
|  | 
 | ||||||
|  | 	let request = r#"{"jsonrpc":"2.0","method":"trace_call","params":[{}, ["stateDiff", "vmTrace", "trace"]],"id":1}"#; | ||||||
|  | 	let response = r#"{"jsonrpc":"2.0","result":{"output":"0x010203","stateDiff":null,"trace":[],"vmTrace":null},"id":1}"#; | ||||||
|  | 
 | ||||||
|  | 	assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn rpc_trace_raw_transaction() { | ||||||
|  | 	let tester = io(); | ||||||
|  | 
 | ||||||
|  | 	let request = r#"{"jsonrpc":"2.0","method":"trace_rawTransaction","params":["0xf869018609184e72a0008276c094d46e8dd67c5d32be8058bb8eb970870f07244567849184e72a801ba0617f39c1a107b63302449c476d96a6cb17a5842fc98ff0c5bcf4d5c4d8166b95a009fdb6097c6196b9bbafc3a59f02f38d91baeef23d0c60a8e4f23c7714cea3a9", ["stateDiff", "vmTrace", "trace"]],"id":1}"#; | ||||||
|  | 	let response = r#"{"jsonrpc":"2.0","result":{"output":"0x010203","stateDiff":null,"trace":[],"vmTrace":null},"id":1}"#; | ||||||
|  | 
 | ||||||
|  | 	assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[test] | ||||||
|  | fn rpc_trace_replay_transaction() { | ||||||
|  | 	let tester = io(); | ||||||
|  | 
 | ||||||
|  | 	let request = r#"{"jsonrpc":"2.0","method":"trace_replayTransaction","params":["0x0000000000000000000000000000000000000000000000000000000000000005", ["trace", "stateDiff", "vmTrace"]],"id":1}"#; | ||||||
|  | 	let response = r#"{"jsonrpc":"2.0","result":{"output":"0x010203","stateDiff":null,"trace":[],"vmTrace":null},"id":1}"#; | ||||||
|  | 
 | ||||||
|  | 	assert_eq!(tester.io.handle_request_sync(request), Some(response.to_owned())); | ||||||
|  | } | ||||||
| @ -16,43 +16,39 @@ | |||||||
| 
 | 
 | ||||||
| //! Traces specific rpc interface.
 | //! Traces specific rpc interface.
 | ||||||
| 
 | 
 | ||||||
| use std::sync::Arc; | use jsonrpc_core::Error; | ||||||
| use jsonrpc_core::{Params, Value, Error, IoDelegate}; | use jsonrpc_macros::Trailing; | ||||||
|  | use v1::types::{TraceFilter, LocalizedTrace, BlockNumber, Index, CallRequest, Bytes, TraceResults, H256}; | ||||||
| 
 | 
 | ||||||
| /// Traces specific rpc interface.
 | build_rpc_trait! { | ||||||
| pub trait Traces: Sized + Send + Sync + 'static { | 	/// Traces specific rpc interface.
 | ||||||
| 	/// Returns traces matching given filter.
 | 	pub trait Traces { | ||||||
| 	fn filter(&self, _: Params) -> Result<Value, Error>; | 		/// Returns traces matching given filter.
 | ||||||
|  | 		#[rpc(name = "trace_filter")] | ||||||
|  | 		fn filter(&self, TraceFilter) -> Result<Vec<LocalizedTrace>, Error>; | ||||||
| 
 | 
 | ||||||
| 	/// Returns transaction trace at given index.
 | 		/// Returns transaction trace at given index.
 | ||||||
| 	fn trace(&self, _: Params) -> Result<Value, Error>; | 		#[rpc(name = "trace_get")] | ||||||
|  | 		fn trace(&self, H256, Vec<Index>) -> Result<Option<LocalizedTrace>, Error>; | ||||||
| 
 | 
 | ||||||
| 	/// Returns all traces of given transaction.
 | 		/// Returns all traces of given transaction.
 | ||||||
| 	fn transaction_traces(&self, _: Params) -> Result<Value, Error>; | 		#[rpc(name = "trace_transaction")] | ||||||
|  | 		fn transaction_traces(&self, H256) -> Result<Vec<LocalizedTrace>, Error>; | ||||||
| 
 | 
 | ||||||
| 	/// Returns all traces produced at given block.
 | 		/// Returns all traces produced at given block.
 | ||||||
| 	fn block_traces(&self, _: Params) -> Result<Value, Error>; | 		#[rpc(name = "trace_block")] | ||||||
|  | 		fn block_traces(&self, BlockNumber) -> Result<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.
 | ||||||
| 	fn call(&self, _: Params) -> Result<Value, Error>; | 		#[rpc(name = "trace_call")] | ||||||
|  | 		fn call(&self, CallRequest, Vec<String>, Trailing<BlockNumber>) -> Result<Option<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.
 | ||||||
| 	fn raw_transaction(&self, _: Params) -> Result<Value, Error>; | 		#[rpc(name = "trace_rawTransaction")] | ||||||
|  | 		fn raw_transaction(&self, Bytes, Vec<String>, Trailing<BlockNumber>) -> Result<Option<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.
 | ||||||
| 	fn replay_transaction(&self, _: Params) -> Result<Value, Error>; | 		#[rpc(name = "trace_replayTransaction")] | ||||||
| 
 | 		fn replay_transaction(&self, H256, Vec<String>) -> Result<Option<TraceResults>, Error>; | ||||||
| 	/// Should be used to convert object to io delegate.
 |  | ||||||
| 	fn to_delegate(self) -> IoDelegate<Self> { |  | ||||||
| 		let mut delegate = IoDelegate::new(Arc::new(self)); |  | ||||||
| 		delegate.add_method("trace_filter", Traces::filter); |  | ||||||
| 		delegate.add_method("trace_get", Traces::trace); |  | ||||||
| 		delegate.add_method("trace_transaction", Traces::transaction_traces); |  | ||||||
| 		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 |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user