propagate trace error to the top
This commit is contained in:
parent
dcc695dda5
commit
14b6b389f2
@ -21,7 +21,7 @@ use std::path::PathBuf;
|
||||
use util::*;
|
||||
use util::panics::*;
|
||||
use views::BlockView;
|
||||
use error::*;
|
||||
use error::{Error, ImportError, ExecutionError, BlockError, ImportResult};
|
||||
use header::{BlockNumber, Header};
|
||||
use state::State;
|
||||
use spec::Spec;
|
||||
@ -38,6 +38,7 @@ use log_entry::LocalizedLogEntry;
|
||||
use block_queue::{BlockQueue, BlockQueueInfo};
|
||||
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute};
|
||||
use client::{BlockId, TransactionId, UncleId, TraceId, ClientConfig, BlockChainClient, TraceFilter};
|
||||
use client::Error as ClientError;
|
||||
use env_info::EnvInfo;
|
||||
use executive::{Executive, Executed, TransactOptions, contract_address};
|
||||
use receipt::LocalizedReceipt;
|
||||
@ -99,7 +100,7 @@ const CLIENT_DB_VER_STR: &'static str = "5.3";
|
||||
|
||||
impl Client<CanonVerifier> {
|
||||
/// Create a new client with given spec and DB path.
|
||||
pub fn new(config: ClientConfig, spec: Spec, path: &Path, message_channel: IoChannel<NetSyncMessage> ) -> Arc<Client> {
|
||||
pub fn new(config: ClientConfig, spec: Spec, path: &Path, message_channel: IoChannel<NetSyncMessage> ) -> Result<Arc<Client>, ClientError> {
|
||||
Client::<CanonVerifier>::new_with_verifier(config, spec, path, message_channel)
|
||||
}
|
||||
}
|
||||
@ -123,11 +124,11 @@ pub fn append_path(path: &Path, item: &str) -> String {
|
||||
|
||||
impl<V> Client<V> where V: Verifier {
|
||||
/// Create a new client with given spec and DB path and custom verifier.
|
||||
pub fn new_with_verifier(config: ClientConfig, spec: Spec, path: &Path, message_channel: IoChannel<NetSyncMessage> ) -> Arc<Client<V>> {
|
||||
pub fn new_with_verifier(config: ClientConfig, spec: Spec, path: &Path, message_channel: IoChannel<NetSyncMessage> ) -> Result<Arc<Client<V>>, ClientError> {
|
||||
let path = get_db_path(path, config.pruning, spec.genesis_header().hash());
|
||||
let gb = spec.genesis_block();
|
||||
let chain = Arc::new(BlockChain::new(config.blockchain, &gb, &path));
|
||||
let tracedb = Arc::new(TraceDB::new(config.tracing, &path, chain.clone()));
|
||||
let tracedb = Arc::new(try!(TraceDB::new(config.tracing, &path, chain.clone())));
|
||||
|
||||
let mut state_db = journaldb::new(&append_path(&path, "state"), config.pruning);
|
||||
|
||||
@ -141,7 +142,7 @@ impl<V> Client<V> where V: Verifier {
|
||||
let panic_handler = PanicHandler::new_in_arc();
|
||||
panic_handler.forward_from(&block_queue);
|
||||
|
||||
Arc::new(Client {
|
||||
let client = Client {
|
||||
chain: chain,
|
||||
tracedb: tracedb,
|
||||
engine: engine,
|
||||
@ -151,7 +152,9 @@ impl<V> Client<V> where V: Verifier {
|
||||
import_lock: Mutex::new(()),
|
||||
panic_handler: panic_handler,
|
||||
verifier: PhantomData,
|
||||
})
|
||||
};
|
||||
|
||||
Ok(Arc::new(client))
|
||||
}
|
||||
|
||||
/// Flush the block import queue.
|
||||
|
23
ethcore/src/client/error.rs
Normal file
23
ethcore/src/client/error.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use trace::Error as TraceError;
|
||||
use std::fmt::{Display, Formatter, Error as FmtError};
|
||||
|
||||
/// Client configuration errors.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
/// TraceDB configuration error.
|
||||
Trace(TraceError),
|
||||
}
|
||||
|
||||
impl From<TraceError> for Error {
|
||||
fn from(err: TraceError) -> Self {
|
||||
Error::Trace(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||
match *self {
|
||||
Error::Trace(ref err) => write!(f, "{}", err)
|
||||
}
|
||||
}
|
||||
}
|
@ -18,11 +18,13 @@
|
||||
|
||||
mod client;
|
||||
mod config;
|
||||
mod error;
|
||||
mod test_client;
|
||||
mod trace;
|
||||
|
||||
pub use self::client::*;
|
||||
pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig, Switch};
|
||||
pub use self::error::Error;
|
||||
pub use types::ids::*;
|
||||
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
||||
pub use self::trace::Filter as TraceFilter;
|
||||
|
@ -19,6 +19,7 @@
|
||||
use util::*;
|
||||
use header::BlockNumber;
|
||||
use basic_types::LogBloom;
|
||||
use client::Error as ClientError;
|
||||
|
||||
pub use types::executed::ExecutionError;
|
||||
|
||||
@ -134,6 +135,8 @@ pub enum ImportError {
|
||||
#[derive(Debug)]
|
||||
/// General error type which should be capable of representing all errors in ethcore.
|
||||
pub enum Error {
|
||||
/// Client configuration error.
|
||||
Client(ClientError),
|
||||
/// Error concerning a utility.
|
||||
Util(UtilError),
|
||||
/// Error concerning block processing.
|
||||
@ -155,6 +158,12 @@ pub enum Error {
|
||||
/// Result of import block operation.
|
||||
pub type ImportResult = Result<H256, Error>;
|
||||
|
||||
impl From<ClientError> for Error {
|
||||
fn from(err: ClientError) -> Error {
|
||||
Error::Client(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransactionError> for Error {
|
||||
fn from(err: TransactionError) -> Error {
|
||||
Error::Transaction(err)
|
||||
|
@ -61,7 +61,7 @@ impl ClientService {
|
||||
|
||||
info!("Starting {}", net_service.host_info());
|
||||
info!("Configured for {} using {:?} engine", spec.name, spec.engine.name());
|
||||
let client = Client::new(config, spec, db_path, net_service.io().channel());
|
||||
let client = try!(Client::new(config, spec, db_path, net_service.io().channel()));
|
||||
panic_handler.forward_from(client.deref());
|
||||
let client_io = Arc::new(ClientIoHandler {
|
||||
client: client.clone()
|
||||
|
@ -23,7 +23,7 @@ use devtools::*;
|
||||
#[test]
|
||||
fn imports_from_empty() {
|
||||
let dir = RandomTempPath::new();
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected());
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||
client.import_verified_blocks(&IoChannel::disconnected());
|
||||
client.flush_queue();
|
||||
}
|
||||
@ -41,7 +41,7 @@ fn returns_state_root_basic() {
|
||||
#[test]
|
||||
fn imports_good_block() {
|
||||
let dir = RandomTempPath::new();
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected());
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||
let good_block = get_good_dummy_block();
|
||||
if let Err(_) = client.import_block(good_block) {
|
||||
panic!("error importing block being good by definition");
|
||||
@ -56,7 +56,7 @@ fn imports_good_block() {
|
||||
#[test]
|
||||
fn query_none_block() {
|
||||
let dir = RandomTempPath::new();
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected());
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||
|
||||
let non_existant = client.block_header(BlockId::Number(188));
|
||||
assert!(non_existant.is_none());
|
||||
|
@ -145,7 +145,7 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[&SignedTrans
|
||||
pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>> {
|
||||
let dir = RandomTempPath::new();
|
||||
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected());
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||
let test_spec = get_test_spec();
|
||||
let test_engine = &test_spec.engine;
|
||||
let state_root = test_spec.genesis_header().state_root;
|
||||
@ -211,7 +211,7 @@ pub fn push_blocks_to_client(client: &Arc<Client>, timestamp_salt: u64, starting
|
||||
|
||||
pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<Client>> {
|
||||
let dir = RandomTempPath::new();
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected());
|
||||
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||
for block in &blocks {
|
||||
if let Err(_) = client.import_block(block.clone()) {
|
||||
panic!("panic importing block which is well-formed");
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
//! Traces config.
|
||||
use bloomchain::Config as BloomConfig;
|
||||
use trace::Error;
|
||||
|
||||
/// 3-value enum.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
@ -30,10 +31,10 @@ pub enum Switch {
|
||||
|
||||
impl Switch {
|
||||
/// Tries to turn old switch to new value.
|
||||
pub fn turn_to(&self, to: Switch) -> Result<bool, &'static str> {
|
||||
pub fn turn_to(&self, to: Switch) -> Result<bool, Error> {
|
||||
match (*self, to) {
|
||||
(Switch::On, Switch::On) | (Switch::On, Switch::Auto) | (Switch::Auto, Switch::On) => Ok(true),
|
||||
(Switch::Off, Switch::On) => Err("Tracing can't be enabled"),
|
||||
(Switch::Off, Switch::On) => Err(Error::ResyncRequired),
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ use bloomchain::group::{BloomGroupDatabase, BloomGroupChain, GroupPosition, Bloo
|
||||
use util::{FixedHash, H256, H264, Database, DBTransaction};
|
||||
use header::BlockNumber;
|
||||
use trace::{BlockTraces, LocalizedTrace, Config, Switch, Filter, Database as TraceDatabase, ImportRequest,
|
||||
DatabaseExtras};
|
||||
DatabaseExtras, Error};
|
||||
use db::{Key, Writable, Readable, CacheUpdatePolicy};
|
||||
use super::bloom::{TraceGroupPosition, BlockTracesBloom, BlockTracesBloomGroup};
|
||||
use super::flat::{FlatTrace, FlatBlockTraces, FlatTransactionTraces};
|
||||
@ -103,7 +103,7 @@ impl<T> BloomGroupDatabase for TraceDB<T> where T: DatabaseExtras {
|
||||
|
||||
impl<T> TraceDB<T> where T: DatabaseExtras {
|
||||
/// Creates new instance of `TraceDB`.
|
||||
pub fn new(config: Config, path: &Path, extras: Arc<T>) -> Self {
|
||||
pub fn new(config: Config, path: &Path, extras: Arc<T>) -> Result<Self, Error> {
|
||||
let mut tracedb_path = path.to_path_buf();
|
||||
tracedb_path.push("tracedb");
|
||||
let tracesdb = Database::open_default(tracedb_path.to_str().unwrap()).unwrap();
|
||||
@ -116,7 +116,7 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
|
||||
None => Switch::Auto,
|
||||
};
|
||||
|
||||
let enabled = old_tracing.turn_to(config.enabled).expect("Tracing can't be enabled. Resync required.");
|
||||
let enabled = try!(old_tracing.turn_to(config.enabled));
|
||||
|
||||
let encoded_tracing = match enabled {
|
||||
true => [0x1],
|
||||
@ -126,14 +126,16 @@ impl<T> TraceDB<T> where T: DatabaseExtras {
|
||||
tracesdb.put(b"enabled", &encoded_tracing).unwrap();
|
||||
tracesdb.put(b"version", TRACE_DB_VER).unwrap();
|
||||
|
||||
TraceDB {
|
||||
let db = TraceDB {
|
||||
traces: RwLock::new(HashMap::new()),
|
||||
blooms: RwLock::new(HashMap::new()),
|
||||
tracesdb: tracesdb,
|
||||
bloom_config: config.blooms,
|
||||
enabled: enabled,
|
||||
extras: extras,
|
||||
}
|
||||
};
|
||||
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
/// Returns traces for block with hash.
|
||||
@ -401,19 +403,19 @@ mod tests {
|
||||
config.enabled = Switch::Auto;
|
||||
|
||||
{
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras));
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras)).unwrap();
|
||||
assert_eq!(tracedb.tracing_enabled(), false);
|
||||
}
|
||||
|
||||
{
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras));
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras)).unwrap();
|
||||
assert_eq!(tracedb.tracing_enabled(), false);
|
||||
}
|
||||
|
||||
config.enabled = Switch::Off;
|
||||
|
||||
{
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras));
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras)).unwrap();
|
||||
assert_eq!(tracedb.tracing_enabled(), false);
|
||||
}
|
||||
}
|
||||
@ -427,26 +429,26 @@ mod tests {
|
||||
config.enabled = Switch::On;
|
||||
|
||||
{
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras));
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras)).unwrap();
|
||||
assert_eq!(tracedb.tracing_enabled(), true);
|
||||
}
|
||||
|
||||
{
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras));
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras)).unwrap();
|
||||
assert_eq!(tracedb.tracing_enabled(), true);
|
||||
}
|
||||
|
||||
config.enabled = Switch::Auto;
|
||||
|
||||
{
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras));
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras)).unwrap();
|
||||
assert_eq!(tracedb.tracing_enabled(), true);
|
||||
}
|
||||
|
||||
config.enabled = Switch::Off;
|
||||
|
||||
{
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras));
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras)).unwrap();
|
||||
assert_eq!(tracedb.tracing_enabled(), false);
|
||||
}
|
||||
}
|
||||
@ -461,12 +463,12 @@ mod tests {
|
||||
config.enabled = Switch::Off;
|
||||
|
||||
{
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras));
|
||||
let tracedb = TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras)).unwrap();
|
||||
assert_eq!(tracedb.tracing_enabled(), true);
|
||||
}
|
||||
|
||||
config.enabled = Switch::On;
|
||||
TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras)); // should panic!
|
||||
TraceDB::new(config.clone(), temp.as_path(), Arc::new(NoopExtras)).unwrap(); // should panic!
|
||||
}
|
||||
|
||||
fn create_simple_import_request(block_number: BlockNumber, block_hash: H256) -> ImportRequest {
|
||||
@ -526,7 +528,7 @@ mod tests {
|
||||
extras.transaction_hashes.insert(0, vec![tx_0.clone()]);
|
||||
extras.transaction_hashes.insert(1, vec![tx_1.clone()]);
|
||||
|
||||
let tracedb = TraceDB::new(config, temp.as_path(), Arc::new(extras));
|
||||
let tracedb = TraceDB::new(config, temp.as_path(), Arc::new(extras)).unwrap();
|
||||
|
||||
// import block 0
|
||||
let request = create_simple_import_request(0, block_0.clone());
|
||||
|
48
ethcore/src/trace/error.rs
Normal file
48
ethcore/src/trace/error.rs
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2015, 2016 Ethcore (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::{Debug, 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.
|
||||
pub enum Error {
|
||||
/// Returned when tracing is enabled,
|
||||
/// but database does not contain traces of old transactions.
|
||||
ResyncRequired,
|
||||
}
|
||||
|
||||
/// TODO: replace `Debug` with default implementation,
|
||||
/// once we stop using it to display errors to user.
|
||||
impl Debug for Error {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||
write!(f, "{}", RESYNC_ERR)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
|
||||
write!(f, "{}", RESYNC_ERR)
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ mod block;
|
||||
mod bloom;
|
||||
mod config;
|
||||
mod db;
|
||||
mod error;
|
||||
mod executive_tracer;
|
||||
pub mod flat;
|
||||
mod import;
|
||||
@ -29,6 +30,7 @@ pub use types::trace_types::*;
|
||||
pub use self::block::BlockTraces;
|
||||
pub use self::config::{Config, Switch};
|
||||
pub use self::db::TraceDB;
|
||||
pub use self::error::Error;
|
||||
pub use types::trace_types::trace::Trace;
|
||||
pub use self::noop_tracer::NoopTracer;
|
||||
pub use self::executive_tracer::ExecutiveTracer;
|
||||
|
@ -28,7 +28,7 @@ use util::numbers::*;
|
||||
use util::sha3::*;
|
||||
use util::bytes::{ToPretty};
|
||||
use util::rlp::{encode, UntrustedRlp, View};
|
||||
use ethcore::client::*;
|
||||
use ethcore::client::{BlockChainClient, BlockId, TransactionId, UncleId};
|
||||
use ethcore::block::IsBlock;
|
||||
use ethcore::views::*;
|
||||
use ethcore::ethereum::Ethash;
|
||||
|
Loading…
Reference in New Issue
Block a user