Tracedb interface && cli (#997)

* traces cli and jsonrpc api

* missing if in docs

* adding traces to modules
This commit is contained in:
Marek Kotewicz
2016-05-02 12:17:30 +02:00
committed by Gav Wood
parent e22e4b9b8b
commit 7c2adc4137
15 changed files with 572 additions and 10 deletions

View File

@@ -37,12 +37,14 @@ use filter::Filter;
use log_entry::LocalizedLogEntry;
use block_queue::{BlockQueue, BlockQueueInfo};
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute};
use client::{BlockId, TransactionId, UncleId, ClientConfig, BlockChainClient};
use client::{BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient, TraceFilter};
use env_info::EnvInfo;
use executive::{Executive, Executed, TransactOptions, contract_address};
use receipt::LocalizedReceipt;
pub use blockchain::CacheSize as BlockChainCacheSize;
use trace::{TraceDB, Database as TraceDatabase};
use trace::{TraceDB, ImportRequest as TraceImportRequest, LocalizedTrace, Database as TraceDatabase, Filter as
TracedbFilter};
use trace;
/// General block status
#[derive(Debug, Eq, PartialEq)]
@@ -309,6 +311,8 @@ impl<V> Client<V> where V: Verifier {
// Commit results
let closed_block = closed_block.unwrap();
let receipts = closed_block.block().receipts().clone();
let traces = From::from(closed_block.block().traces().clone().unwrap_or_else(Vec::new));
closed_block.drain()
.commit(header.number(), &header.hash(), ancient)
.expect("State DB commit failed.");
@@ -316,6 +320,14 @@ impl<V> Client<V> where V: Verifier {
// And update the chain after commit to prevent race conditions
// (when something is in chain but you are not able to fetch details)
let route = self.chain.insert_block(&block.bytes, receipts);
self.tracedb.import(TraceImportRequest {
traces: traces,
block_hash: header.hash(),
block_number: header.number(),
enacted: route.enacted.clone(),
retracted: route.retracted.len()
});
import_results.push(route);
self.report.write().unwrap().accrue_block(&block);
@@ -707,6 +719,46 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
.collect()
}
fn filter_traces(&self, filter: TraceFilter) -> Option<Vec<LocalizedTrace>> {
let start = self.block_number(filter.range.start);
let end = self.block_number(filter.range.end);
if start.is_some() && end.is_some() {
let filter = trace::Filter {
range: start.unwrap() as usize..end.unwrap() as usize,
from_address: From::from(filter.from_address),
to_address: From::from(filter.to_address),
};
let traces = self.tracedb.filter(&filter);
Some(traces)
} else {
None
}
}
fn trace(&self, trace: TraceId) -> Option<LocalizedTrace> {
let trace_address = trace.address;
self.transaction_address(trace.transaction)
.and_then(|tx_address| {
self.block_number(BlockId::Hash(tx_address.block_hash))
.and_then(|number| self.tracedb.trace(number, tx_address.index, trace_address))
})
}
fn transaction_traces(&self, transaction: TransactionId) -> Option<Vec<LocalizedTrace>> {
self.transaction_address(transaction)
.and_then(|tx_address| {
self.block_number(BlockId::Hash(tx_address.block_hash))
.and_then(|number| self.tracedb.transaction_traces(number, tx_address.index))
})
}
fn block_traces(&self, block: BlockId) -> Option<Vec<LocalizedTrace>> {
self.block_number(block)
.and_then(|number| self.tracedb.block_traces(number))
}
fn last_hashes(&self) -> LastHashes {
self.build_last_hashes(self.chain.best_block_hash())
}

View File

@@ -44,6 +44,14 @@ pub enum TransactionId {
Location(BlockId, usize)
}
/// Uniquely identifies Trace.
pub struct TraceId {
/// Transaction
pub transaction: TransactionId,
/// Trace address within transaction.
pub address: Vec<usize>,
}
/// Uniquely identifies Uncle.
pub struct UncleId (
/// Block id.

View File

@@ -23,9 +23,10 @@ mod test_client;
mod trace;
pub use self::client::*;
pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig};
pub use self::ids::{BlockId, TransactionId, UncleId};
pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig, Switch};
pub use self::ids::{BlockId, TransactionId, UncleId, TraceId};
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
pub use self::trace::Filter as TraceFilter;
pub use executive::{Executed, Executive, TransactOptions};
pub use env_info::{LastHashes, EnvInfo};
@@ -43,6 +44,7 @@ use filter::Filter;
use error::{ImportResult, Error};
use receipt::LocalizedReceipt;
use engine::{Engine};
use trace::LocalizedTrace;
/// Blockchain database client. Owns and manages a blockchain and a block queue.
pub trait BlockChainClient : Sync + Send {
@@ -135,6 +137,18 @@ pub trait BlockChainClient : Sync + Send {
/// Executes a function providing it with a reference to an engine.
fn engine(&self) -> &Engine;
/// Returns traces matching given filter.
fn filter_traces(&self, filter: TraceFilter) -> Option<Vec<LocalizedTrace>>;
/// Returns trace with given id.
fn trace(&self, trace: TraceId) -> Option<LocalizedTrace>;
/// Returns traces created by transaction.
fn transaction_traces(&self, trace: TransactionId) -> Option<Vec<LocalizedTrace>>;
/// Returns traces created by transaction from block.
fn block_traces(&self, trace: BlockId) -> Option<Vec<LocalizedTrace>>;
/// Get last hashes starting from best block.
fn last_hashes(&self) -> LastHashes;
}

View File

@@ -20,7 +20,7 @@ use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrder};
use util::*;
use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action};
use blockchain::TreeRoute;
use client::{BlockChainClient, BlockChainInfo, BlockStatus, BlockId, TransactionId, UncleId, LastHashes};
use client::{BlockChainClient, BlockChainInfo, BlockStatus, BlockId, TransactionId, UncleId, TraceId, TraceFilter, LastHashes};
use header::{Header as BlockHeader, BlockNumber};
use filter::Filter;
use log_entry::LocalizedLogEntry;
@@ -33,6 +33,7 @@ use block::{SealedBlock, ClosedBlock, LockedBlock};
use executive::Executed;
use error::Error;
use engine::Engine;
use trace::LocalizedTrace;
/// Test client.
pub struct TestBlockChainClient {
@@ -432,4 +433,20 @@ impl BlockChainClient for TestBlockChainClient {
fn engine(&self) -> &Engine {
unimplemented!();
}
fn filter_traces(&self, _filter: TraceFilter) -> Option<Vec<LocalizedTrace>> {
unimplemented!();
}
fn trace(&self, _trace: TraceId) -> Option<LocalizedTrace> {
unimplemented!();
}
fn transaction_traces(&self, _trace: TransactionId) -> Option<Vec<LocalizedTrace>> {
unimplemented!();
}
fn block_traces(&self, _trace: BlockId) -> Option<Vec<LocalizedTrace>> {
unimplemented!();
}
}