Die error_chain, die (#10747)

* Replace error chain for network error

* Fix usages and add manual From impls

* OnDemand Error and remove remaining dependencies

* Die error_chain, die.

* DIE

* Hasta la vista, baby
This commit is contained in:
Andrew Jones 2019-06-17 07:44:59 +01:00 committed by David
parent dbdb57a8c0
commit bf55db4c7e
29 changed files with 214 additions and 225 deletions

5
Cargo.lock generated
View File

@ -1013,6 +1013,7 @@ version = "1.12.0"
dependencies = [
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"common-types 0.1.0",
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.12.0",
"ethcore-blockchain 0.1.0",
@ -1106,7 +1107,7 @@ name = "ethcore-network"
version = "1.12.0"
dependencies = [
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore-io 1.12.0",
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethkey 0.3.0",
@ -1243,7 +1244,7 @@ name = "ethcore-service"
version = "0.1.0"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
"derive_more 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ethcore 1.12.0",
"ethcore-blockchain 0.1.0",
"ethcore-db 0.1.0",

View File

@ -10,6 +10,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
log = "0.4"
parity-bytes = "0.1"
common-types = { path = "../types" }
derive_more = "0.14.0"
ethcore = { path = ".."}
ethcore-db = { path = "../db" }
ethcore-blockchain = { path = "../blockchain" }

View File

@ -260,7 +260,7 @@ impl HeaderChain {
let best_block = {
let era = match candidates.get(&curr.best_num) {
Some(era) => era,
None => bail!("Database corrupt: highest block referenced but no data."),
None => return Err("Database corrupt: highest block referenced but no data.".into()),
};
let best = &era.candidates[0];
@ -582,7 +582,7 @@ impl HeaderChain {
} else {
let msg = format!("header of block #{} not found in DB ; database in an \
inconsistent state", h_num);
bail!(msg);
return Err(msg.into());
};
let decoded = header.decode().expect("decoding db value failed");

View File

@ -86,8 +86,7 @@ extern crate keccak_hash as hash;
extern crate triehash_ethereum as triehash;
extern crate kvdb;
extern crate memory_cache;
#[macro_use]
extern crate error_chain;
extern crate derive_more;
#[cfg(test)]
extern crate kvdb_memorydb;

View File

@ -66,32 +66,31 @@ pub const DEFAULT_NUM_CONSECUTIVE_FAILED_REQUESTS: usize = 1;
/// OnDemand related errors
pub mod error {
// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting`
// https://github.com/paritytech/parity-ethereum/issues/10302
#![allow(deprecated)]
use futures::sync::oneshot::Canceled;
error_chain! {
/// OnDemand Error
#[derive(Debug, derive_more::Display, derive_more::From)]
pub enum Error {
/// Canceled oneshot channel
ChannelCanceled(Canceled),
/// Timeout bad response
BadResponse(String),
/// OnDemand requests limit exceeded
#[display(fmt = "OnDemand request maximum backoff iterations exceeded")]
RequestLimit,
}
foreign_links {
ChannelCanceled(Canceled) #[doc = "Canceled oneshot channel"];
}
errors {
#[doc = "Timeout bad response"]
BadResponse(err: String) {
description("Max response evaluation time exceeded")
display("{}", err)
}
#[doc = "OnDemand requests limit exceeded"]
RequestLimit {
description("OnDemand request maximum backoff iterations exceeded")
display("OnDemand request maximum backoff iterations exceeded")
impl std::error::Error for Error {
fn source(&self) -> Option<&(std::error::Error + 'static)> {
match self {
Error::ChannelCanceled(err) => Some(err),
_ => None,
}
}
}
/// OnDemand Result
pub type Result<T> = std::result::Result<T, Error>;
}
/// Public interface for performing network requests `OnDemand`
@ -272,7 +271,7 @@ impl Pending {
response_err
);
let err = self::error::ErrorKind::BadResponse(err);
let err = self::error::Error::BadResponse(err);
if self.sender.send(Err(err.into())).is_err() {
debug!(target: "on_demand", "Dropped oneshot channel receiver on no response");
}
@ -280,7 +279,7 @@ impl Pending {
// returning a peer discovery timeout during query attempts
fn request_limit_reached(self) {
let err = self::error::ErrorKind::RequestLimit;
let err = self::error::Error::RequestLimit;
if self.sender.send(Err(err.into())).is_err() {
debug!(target: "on_demand", "Dropped oneshot channel receiver on time out");
}

View File

@ -16,10 +16,6 @@
//! Private transactions module.
// Recursion limit required because of
// error_chain foreign_links.
#![recursion_limit="256"]
mod encryptor;
mod key_server_keys;
mod private_transactions;

View File

@ -5,7 +5,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
ansi_term = "0.10"
error-chain = { version = "0.12", default-features = false }
derive_more = "0.14.0"
ethcore = { path = ".." }
ethcore-blockchain = { path = "../blockchain" }
ethcore-io = { path = "../../util/io" }

View File

@ -14,18 +14,26 @@
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting`
// https://github.com/paritytech/parity-ethereum/issues/10302
#![allow(deprecated)]
use ethcore;
use io;
use ethcore_private_tx;
error_chain! {
foreign_links {
Ethcore(ethcore::error::Error);
IoError(io::IoError);
PrivateTransactions(ethcore_private_tx::Error);
#[derive(Debug, derive_more::Display, derive_more::From)]
pub enum Error {
/// Ethcore Error
Ethcore(ethcore::error::Error),
/// Io Error
IoError(io::IoError),
/// Private Transactions Error
PrivateTransactions(ethcore_private_tx::Error),
}
impl std::error::Error for Error {
fn source(&self) -> Option<&(std::error::Error + 'static)> {
match self {
Error::Ethcore(err) => Some(err),
Error::IoError(err) => Some(err),
Error::PrivateTransactions(err) => Some(err),
}
}
}

View File

@ -23,8 +23,7 @@ extern crate ethcore_sync as sync;
extern crate ethereum_types;
extern crate kvdb;
#[macro_use]
extern crate error_chain;
extern crate derive_more;
#[macro_use]
extern crate log;
#[macro_use]
@ -42,5 +41,5 @@ mod stop_guard;
#[cfg(test)]
extern crate kvdb_rocksdb;
pub use error::{Error, ErrorKind};
pub use error::Error;
pub use service::{ClientService, PrivateTxService};

View File

@ -59,7 +59,7 @@ impl PrivateTxHandler for PrivateTxService {
Ok(import_result) => Ok(import_result),
Err(err) => {
warn!(target: "privatetx", "Unable to import private transaction packet: {}", err);
bail!(err.to_string())
return Err(err.to_string())
}
}
}
@ -69,7 +69,7 @@ impl PrivateTxHandler for PrivateTxService {
Ok(import_result) => Ok(import_result),
Err(err) => {
warn!(target: "privatetx", "Unable to import signed private transaction packet: {}", err);
bail!(err.to_string())
return Err(err.to_string())
}
}
}

View File

@ -54,10 +54,6 @@
//! cargo build --release
//! ```
// Recursion limit required because of
// error_chain foreign_links.
#![recursion_limit="128"]
extern crate ansi_term;
extern crate bn;
extern crate byteorder;

View File

@ -22,7 +22,7 @@ use std::time::Duration;
use bytes::Bytes;
use devp2p::NetworkService;
use network::{NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId,
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error, ErrorKind,
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error,
ConnectionFilter};
use network::client_version::ClientVersion;
@ -593,7 +593,7 @@ impl ChainNotify for EthSync {
match self.network.start() {
Err((err, listen_address)) => {
match err.into() {
ErrorKind::Io(ref e) if e.kind() == io::ErrorKind::AddrInUse => {
Error::Io(ref e) if e.kind() == io::ErrorKind::AddrInUse => {
warn!("Network port {:?} is already in use, make sure that another instance of an Ethereum client is not running or change the port using the --port option.", listen_address.expect("Listen address is not set."))
},
err => warn!("Error starting network: {}", err),
@ -983,7 +983,7 @@ impl ManageNetwork for LightSync {
match self.network.start() {
Err((err, listen_address)) => {
match err.into() {
ErrorKind::Io(ref e) if e.kind() == io::ErrorKind::AddrInUse => {
Error::Io(ref e) if e.kind() == io::ErrorKind::AddrInUse => {
warn!("Network port {:?} is already in use, make sure that another instance of an Ethereum client is not running or change the port using the --port option.", listen_address.expect("Listen address is not set."))
},
err => warn!("Error starting network: {}", err),

View File

@ -435,13 +435,13 @@ impl BlockCollection {
},
None => {
warn!("Got body with no header {}", h);
Err(network::ErrorKind::BadProtocol.into())
Err(network::Error::BadProtocol)
}
}
}
None => {
trace!(target: "sync", "Ignored unknown/stale block body. tx_root = {:?}, uncles = {:?}", header_id.transactions_root, header_id.uncles);
Err(network::ErrorKind::BadProtocol.into())
Err(network::Error::BadProtocol)
}
}
}
@ -463,7 +463,7 @@ impl BlockCollection {
},
None => {
warn!("Got receipt with no header {}", h);
return Err(network::ErrorKind::BadProtocol.into())
return Err(network::Error::BadProtocol)
}
}
}
@ -471,7 +471,7 @@ impl BlockCollection {
},
hash_map::Entry::Vacant(_) => {
trace!(target: "sync", "Ignored unknown/stale block receipt {:?}", receipt_root);
Err(network::ErrorKind::BadProtocol.into())
Err(network::Error::BadProtocol)
}
}
}

View File

@ -76,5 +76,5 @@ mod api;
pub use api::*;
pub use chain::{SyncStatus, SyncState};
pub use devp2p::validate_node_url;
pub use network::{NonReservedPeerMode, Error, ErrorKind, ConnectionFilter, ConnectionDirection};
pub use network::{NonReservedPeerMode, Error, ConnectionFilter, ConnectionDirection};
pub use private_tx::{PrivateTxHandler, NoopPrivateTxHandler, SimplePrivateTxHandler};

View File

@ -41,8 +41,6 @@ extern crate ethabi_contract;
#[macro_use]
extern crate ethabi_derive;
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;

View File

@ -168,7 +168,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
if self.client.transaction_already_included(&hash) {
trace!(target: "txqueue", "[{:?}] Rejected tx already in the blockchain", hash);
bail!(transaction::Error::AlreadyImported)
return Err(transaction::Error::AlreadyImported)
}
let gas_limit = cmp::min(self.options.tx_gas_limit, self.options.block_gas_limit);
@ -181,7 +181,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
self.options.block_gas_limit,
self.options.tx_gas_limit,
);
bail!(transaction::Error::GasLimitExceeded {
return Err(transaction::Error::GasLimitExceeded {
limit: gas_limit,
got: *tx.gas(),
});
@ -196,7 +196,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
minimal_gas,
);
bail!(transaction::Error::InsufficientGas {
return Err(transaction::Error::InsufficientGas {
minimal: minimal_gas,
got: *tx.gas(),
})
@ -216,7 +216,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
tx.gas_price(),
self.options.minimal_gas_price,
);
bail!(transaction::Error::InsufficientGasPrice {
return Err(transaction::Error::InsufficientGasPrice {
minimal: self.options.minimal_gas_price,
got: *tx.gas_price(),
});
@ -231,7 +231,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
tx.gas_price(),
vtx.transaction.gas_price,
);
bail!(transaction::Error::InsufficientGasPrice {
return Err(transaction::Error::InsufficientGasPrice {
minimal: vtx.transaction.gas_price,
got: *tx.gas_price(),
});
@ -247,7 +247,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
Ok(signed) => signed.into(),
Err(err) => {
debug!(target: "txqueue", "[{:?}] Rejected tx {:?}", hash, err);
bail!(err)
return Err(err)
},
},
Transaction::Local(tx) => tx,
@ -256,7 +256,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
// Verify RLP payload
if let Err(err) = self.client.decode_transaction(&transaction.rlp_bytes()) {
debug!(target: "txqueue", "[{:?}] Rejected transaction's rlp payload", err);
bail!(err)
return Err(err)
}
let sender = transaction.sender();
@ -276,7 +276,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
transaction.gas_price,
self.options.minimal_gas_price,
);
bail!(transaction::Error::InsufficientGasPrice {
return Err(transaction::Error::InsufficientGasPrice {
minimal: self.options.minimal_gas_price,
got: transaction.gas_price,
});
@ -291,7 +291,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
"[{:?}] Rejected tx, price overflow",
hash
);
bail!(transaction::Error::InsufficientBalance {
return Err(transaction::Error::InsufficientBalance {
cost: U256::max_value(),
balance: account_details.balance,
});
@ -304,7 +304,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
account_details.balance,
cost,
);
bail!(transaction::Error::InsufficientBalance {
return Err(transaction::Error::InsufficientBalance {
cost: cost,
balance: account_details.balance,
});
@ -318,7 +318,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
transaction.nonce,
account_details.nonce,
);
bail!(transaction::Error::Old);
return Err(transaction::Error::Old);
}
let priority = match (is_own || account_details.is_local, is_retracted) {

View File

@ -710,7 +710,7 @@ impl Configuration {
for line in &lines {
match validate_node_url(line).map(Into::into) {
None => continue,
Some(sync::ErrorKind::AddressResolve(_)) => return Err(format!("Failed to resolve hostname of a boot node: {}", line)),
Some(sync::Error::AddressResolve(_)) => return Err(format!("Failed to resolve hostname of a boot node: {}", line)),
Some(_) => return Err(format!("Invalid node address format given for a boot node: {}", line)),
}
}

View File

@ -186,7 +186,7 @@ pub fn to_bootnodes(bootnodes: &Option<String>) -> Result<Vec<String>, String> {
Some(ref x) if !x.is_empty() => x.split(',').map(|s| {
match validate_node_url(s).map(Into::into) {
None => Ok(s.to_owned()),
Some(sync::ErrorKind::AddressResolve(_)) => Err(format!("Failed to resolve hostname of a boot node: {}", s)),
Some(sync::Error::AddressResolve(_)) => Err(format!("Failed to resolve hostname of a boot node: {}", s)),
Some(_) => Err(format!("Invalid node address format given for a boot node: {}", s)),
}
}).collect(),

View File

@ -25,7 +25,7 @@ use rlp::DecoderError;
use types::transaction::Error as TransactionError;
use ethcore_private_tx::Error as PrivateTransactionError;
use vm::Error as VMError;
use light::on_demand::error::{Error as OnDemandError, ErrorKind as OnDemandErrorKind};
use light::on_demand::error::{Error as OnDemandError};
use ethcore::client::BlockChainClient;
use types::blockchain_info::BlockChainInfo;
use v1::types::BlockNumber;
@ -555,10 +555,9 @@ pub fn filter_block_not_found(id: BlockId) -> Error {
pub fn on_demand_error(err: OnDemandError) -> Error {
match err {
OnDemandError(OnDemandErrorKind::ChannelCanceled(e), _) => on_demand_cancel(e),
OnDemandError(OnDemandErrorKind::RequestLimit, _) => timeout_new_peer(&err),
OnDemandError(OnDemandErrorKind::BadResponse(_), _) => max_attempts_reached(&err),
_ => on_demand_others(&err),
OnDemandError::ChannelCanceled(e) => on_demand_cancel(e),
OnDemandError::RequestLimit => timeout_new_peer(&err),
OnDemandError::BadResponse(_) => max_attempts_reached(&err),
}
}
@ -583,14 +582,6 @@ pub fn timeout_new_peer(err: &OnDemandError) -> Error {
}
}
pub fn on_demand_others(err: &OnDemandError) -> Error {
Error {
code: ErrorCode::ServerError(codes::UNKNOWN_ERROR),
message: err.to_string(),
data: None,
}
}
pub fn status_error(has_peers: bool) -> Error {
if has_peers {
no_work()

View File

@ -37,7 +37,7 @@ use tiny_keccak::Keccak;
use ethkey::crypto;
use handshake::Handshake;
use io::{IoContext, StreamToken};
use network::{Error, ErrorKind};
use network::Error;
const ENCRYPTED_HEADER_LEN: usize = 32;
const RECEIVE_PAYLOAD: Duration = Duration::from_secs(30);
@ -358,7 +358,7 @@ impl EncryptedConnection {
let mut header = RlpStream::new();
let len = payload.len();
if len > MAX_PAYLOAD_SIZE {
bail!(ErrorKind::OversizedPacket);
return Err(Error::OversizedPacket);
}
header.append_raw(&[(len >> 16) as u8, (len >> 8) as u8, len as u8], 1);
header.append_raw(&[0xc2u8, 0x80u8, 0x80u8], 1);
@ -386,14 +386,14 @@ impl EncryptedConnection {
/// Decrypt and authenticate an incoming packet header. Prepare for receiving payload.
fn read_header(&mut self, header: &[u8]) -> Result<(), Error> {
if header.len() != ENCRYPTED_HEADER_LEN {
return Err(ErrorKind::Auth.into());
return Err(Error::Auth);
}
EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &header[0..16]);
let mac = &header[16..];
let mut expected = H256::zero();
self.ingress_mac.clone().finalize(expected.as_bytes_mut());
if mac != &expected[0..16] {
return Err(ErrorKind::Auth.into());
return Err(Error::Auth);
}
let mut hdec = H128::default();
@ -422,7 +422,7 @@ impl EncryptedConnection {
let padding = (16 - (self.payload_len % 16)) % 16;
let full_length = self.payload_len + padding + 16;
if payload.len() != full_length {
return Err(ErrorKind::Auth.into());
return Err(Error::Auth);
}
self.ingress_mac.update(&payload[0..payload.len() - 16]);
EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &[0u8; 0]);
@ -430,7 +430,7 @@ impl EncryptedConnection {
let mut expected = H128::default();
self.ingress_mac.clone().finalize(expected.as_bytes_mut());
if mac != &expected[..] {
return Err(ErrorKind::Auth.into());
return Err(Error::Auth);
}
let mut packet = vec![0u8; self.payload_len];

View File

@ -27,7 +27,7 @@ use parity_bytes::Bytes;
use rlp::{Rlp, RlpStream};
use ethkey::{KeyPair, recover, Secret, sign};
use network::{Error, ErrorKind};
use network::Error;
use network::IpFilter;
use node_table::*;
use PROTOCOL_VERSION;
@ -482,12 +482,12 @@ impl<'a> Discovery<'a> {
pub fn on_packet(&mut self, packet: &[u8], from: SocketAddr) -> Result<Option<TableUpdates>, Error> {
// validate packet
if packet.len() < 32 + 65 + 4 + 1 {
return Err(ErrorKind::BadProtocol.into());
return Err(Error::BadProtocol);
}
let hash_signed = keccak(&packet[32..]);
if hash_signed[..] != packet[0..32] {
return Err(ErrorKind::BadProtocol.into());
return Err(Error::BadProtocol);
}
let signed = &packet[(32 + 65)..];
@ -512,7 +512,7 @@ impl<'a> Discovery<'a> {
let secs_since_epoch = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();
if self.check_timestamps && timestamp < secs_since_epoch {
debug!(target: "discovery", "Expired packet");
return Err(ErrorKind::Expired.into());
return Err(Error::Expired);
}
Ok(())
}

View File

@ -28,7 +28,7 @@ use ethkey::{Generator, KeyPair, Public, Random, recover, Secret, sign};
use ethkey::crypto::{ecdh, ecies};
use host::HostInfo;
use io::{IoContext, StreamToken};
use network::{Error, ErrorKind};
use network::Error;
use node_table::NodeId;
#[derive(PartialEq, Eq, Debug)]
@ -166,7 +166,7 @@ impl Handshake {
trace!(target: "network", "Received handshake auth from {:?}", self.connection.remote_addr_str());
if data.len() != V4_AUTH_PACKET_SIZE {
debug!(target: "network", "Wrong auth packet size");
return Err(ErrorKind::BadProtocol.into());
return Err(Error::BadProtocol);
}
self.auth_cipher = data.to_vec();
match ecies::decrypt(secret, &[], data) {
@ -183,7 +183,7 @@ impl Handshake {
let total = ((u16::from(data[0]) << 8 | (u16::from(data[1]))) as usize) + 2;
if total < V4_AUTH_PACKET_SIZE {
debug!(target: "network", "Wrong EIP8 auth packet size");
return Err(ErrorKind::BadProtocol.into());
return Err(Error::BadProtocol);
}
let rest = total - data.len();
self.state = HandshakeState::ReadingAuthEip8;
@ -212,7 +212,7 @@ impl Handshake {
trace!(target: "network", "Received handshake ack from {:?}", self.connection.remote_addr_str());
if data.len() != V4_ACK_PACKET_SIZE {
debug!(target: "network", "Wrong ack packet size");
return Err(ErrorKind::BadProtocol.into());
return Err(Error::BadProtocol);
}
self.ack_cipher = data.to_vec();
match ecies::decrypt(secret, &[], data) {
@ -226,7 +226,7 @@ impl Handshake {
let total = (((u16::from(data[0])) << 8 | (u16::from(data[1]))) as usize) + 2;
if total < V4_ACK_PACKET_SIZE {
debug!(target: "network", "Wrong EIP8 ack packet size");
return Err(ErrorKind::BadProtocol.into());
return Err(Error::BadProtocol);
}
let rest = total - data.len();
self.state = HandshakeState::ReadingAckEip8;

View File

@ -44,7 +44,7 @@ use io::*;
use ip_utils::{map_external_address, select_public_address};
use network::{NetworkConfiguration, NetworkIoMessage, PacketId, PeerId, ProtocolId};
use network::{NetworkContext as NetworkContextTrait, NonReservedPeerMode};
use network::{DisconnectReason, Error, ErrorKind, NetworkProtocolHandler, SessionInfo};
use network::{DisconnectReason, Error, NetworkProtocolHandler, SessionInfo};
use network::{ConnectionDirection, ConnectionFilter};
use network::client_version::ClientVersion;
use node_table::*;
@ -157,7 +157,7 @@ impl<'s> NetworkContextTrait for NetworkContext<'s> {
fn respond(&self, packet_id: PacketId, data: Vec<u8>) -> Result<(), Error> {
assert!(self.session.is_some(), "Respond called without network context");
self.session_id.map_or_else(|| Err(ErrorKind::Expired.into()), |id| self.send(id, packet_id, data))
self.session_id.map_or_else(|| Err(Error::Expired), |id| self.send(id, packet_id, data))
}
fn disable_peer(&self, peer: PeerId) {
@ -719,8 +719,8 @@ impl Host {
Err(e) => {
let s = session.lock();
trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e);
match *e.kind() {
ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) | ErrorKind::Disconnect(DisconnectReason::UselessPeer) => {
match e {
Error::Disconnect(DisconnectReason::IncompatibleProtocol) | Error::Disconnect(DisconnectReason::UselessPeer) => {
if let Some(id) = s.id() {
if !self.reserved_nodes.read().contains(id) {
let mut nodes = self.nodes.write();

View File

@ -68,8 +68,6 @@ extern crate bytes;
extern crate crypto as rcrypto;
#[cfg(test)]
extern crate env_logger;
#[macro_use]
extern crate error_chain;
extern crate ethcore_io as io;
extern crate ethcore_network as network;
extern crate ethereum_types;

View File

@ -31,7 +31,7 @@ use serde_json;
use discovery::{NodeEntry, TableUpdates};
use ip_utils::*;
use network::{AllowIP, Error, ErrorKind, IpFilter};
use network::{AllowIP, Error, IpFilter};
/// Node public key
pub type NodeId = H512;
@ -133,8 +133,8 @@ impl FromStr for NodeEndpoint {
address: a,
udp_port: a.port()
}),
Ok(None) => bail!(ErrorKind::AddressResolve(None)),
Err(_) => Err(ErrorKind::AddressParse.into()) // always an io::Error of InvalidInput kind
Ok(None) => return Err(Error::AddressResolve(None.into())),
Err(_) => Err(Error::AddressParse) // always an io::Error of InvalidInput kind
}
}
}
@ -216,7 +216,7 @@ impl FromStr for Node {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (id, endpoint) = if s.len() > 136 && &s[0..8] == "enode://" && &s[136..137] == "@" {
(s[8..136].parse().map_err(|_| ErrorKind::InvalidNodeId)?, NodeEndpoint::from_str(&s[137..])?)
(s[8..136].parse().map_err(|_| Error::InvalidNodeId)?, NodeEndpoint::from_str(&s[137..])?)
}
else {
(NodeId::default(), NodeEndpoint::from_str(s)?)
@ -629,21 +629,21 @@ mod tests {
fn endpoint_parse_empty_ip_string_returns_error() {
let endpoint = NodeEndpoint::from_str("");
assert!(endpoint.is_err());
assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse);
assert_matches!(endpoint.unwrap_err(), Error::AddressParse);
}
#[test]
fn endpoint_parse_invalid_ip_string_returns_error() {
let endpoint = NodeEndpoint::from_str("beef");
assert!(endpoint.is_err());
assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse);
assert_matches!(endpoint.unwrap_err(), Error::AddressParse);
}
#[test]
fn endpoint_parse_valid_ip_without_port_returns_error() {
let endpoint = NodeEndpoint::from_str("123.123.123.123");
assert!(endpoint.is_err());
assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse);
assert_matches!(endpoint.unwrap_err(), Error::AddressParse);
let endpoint = NodeEndpoint::from_str("123.123.123.123:123");
assert!(endpoint.is_ok())
}
@ -668,11 +668,11 @@ mod tests {
fn node_parse_fails_for_invalid_urls() {
let node = Node::from_str("foo");
assert!(node.is_err());
assert_matches!(node.unwrap_err().kind(), &ErrorKind::AddressParse);
assert_matches!(node.unwrap_err(), Error::AddressParse);
let node = Node::from_str("enode://foo@bar");
assert!(node.is_err());
assert_matches!(node.unwrap_err().kind(), &ErrorKind::AddressParse);
assert_matches!(node.unwrap_err(), Error::AddressParse);
}
#[test]

View File

@ -30,7 +30,7 @@ use connection::{Connection, EncryptedConnection, MAX_PAYLOAD_SIZE, Packet};
use handshake::Handshake;
use host::*;
use io::{IoContext, StreamToken};
use network::{DisconnectReason, Error, ErrorKind, PeerCapabilityInfo, ProtocolId, SessionInfo};
use network::{DisconnectReason, Error, PeerCapabilityInfo, ProtocolId, SessionInfo};
use network::client_version::ClientVersion;
use network::SessionCapabilityInfo;
use node_table::NodeId;
@ -256,10 +256,10 @@ impl Session {
where Message: Send + Sync + Clone {
if protocol.is_some() && (self.info.capabilities.is_empty() || !self.had_hello) {
debug!(target: "network", "Sending to unconfirmed session {}, protocol: {:?}, packet: {}", self.token(), protocol.as_ref().map(|p| str::from_utf8(&p[..]).unwrap_or("??")), packet_id);
bail!(ErrorKind::BadProtocol);
return Err(Error::BadProtocol);
}
if self.expired() {
return Err(ErrorKind::Expired.into());
return Err(Error::Expired);
}
let mut i = 0usize;
let pid = match protocol {
@ -281,7 +281,7 @@ impl Session {
let mut payload = data; // create a reference with local lifetime
if self.compression {
if payload.len() > MAX_PAYLOAD_SIZE {
bail!(ErrorKind::OversizedPacket);
return Err(Error::OversizedPacket);
}
let len = snappy::compress_into(&payload, &mut compressed);
trace!(target: "network", "compressed {} to {}", payload.len(), len);
@ -331,16 +331,16 @@ impl Session {
fn read_packet<Message>(&mut self, io: &IoContext<Message>, packet: &Packet, host: &HostInfo) -> Result<SessionData, Error>
where Message: Send + Sync + Clone {
if packet.data.len() < 2 {
return Err(ErrorKind::BadProtocol.into());
return Err(Error::BadProtocol);
}
let packet_id = packet.data[0];
if packet_id != PACKET_HELLO && packet_id != PACKET_DISCONNECT && !self.had_hello {
return Err(ErrorKind::BadProtocol.into());
return Err(Error::BadProtocol);
}
let data = if self.compression {
let compressed = &packet.data[1..];
if snappy::decompressed_len(&compressed)? > MAX_PAYLOAD_SIZE {
bail!(ErrorKind::OversizedPacket);
return Err(Error::OversizedPacket);
}
snappy::decompress(&compressed)?
} else {
@ -358,7 +358,7 @@ impl Session {
if self.had_hello {
debug!(target:"network", "Disconnected: {}: {:?}", self.token(), DisconnectReason::from_u8(reason));
}
Err(ErrorKind::Disconnect(DisconnectReason::from_u8(reason)).into())
Err(Error::Disconnect(DisconnectReason::from_u8(reason)))
}
PACKET_PING => {
self.send_pong(io)?;
@ -500,7 +500,7 @@ impl Session {
rlp.append(&(reason as u32));
self.send_packet(io, None, PACKET_DISCONNECT, &rlp.drain()).ok();
}
ErrorKind::Disconnect(reason).into()
Error::Disconnect(reason)
}
fn send<Message>(&mut self, io: &IoContext<Message>, data: &[u8]) -> Result<(), Error> where Message: Send + Sync + Clone {

View File

@ -7,7 +7,7 @@ version = "1.12.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
error-chain = { version = "0.12", default-features = false }
derive_more = "0.14.0"
parity-crypto = "0.4.0"
ethcore-io = { path = "../io" }
ethereum-types = "0.6.0"

View File

@ -14,11 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
// Silence: `use of deprecated item 'std::error::Error::cause': replaced by Error::source, which can support downcasting`
// https://github.com/paritytech/parity-ethereum/issues/10302
#![allow(deprecated)]
use std::{io, net, fmt};
use std::{error, io, net, fmt};
use libc::{ENFILE, EMFILE};
use io::IoError;
use {rlp, ethkey, crypto, snappy};
@ -85,118 +81,127 @@ impl fmt::Display for DisconnectReason {
}
}
error_chain! {
foreign_links {
SocketIo(IoError) #[doc = "Socket IO error."];
Decompression(snappy::InvalidInput) #[doc = "Decompression error."];
Rlp(rlp::DecoderError) #[doc = "Rlp decoder error."];
/// Queue error
#[derive(Debug, derive_more::Display)]
pub enum Error {
/// Socket IO error.
SocketIo(IoError),
/// Decompression error.
Decompression(snappy::InvalidInput),
/// Rlp decoder error.
Rlp(rlp::DecoderError),
/// Error concerning the network address parsing subsystem.
#[display(fmt = "Failed to parse network address")]
AddressParse,
/// Error concerning the network address resolution subsystem.
#[display(fmt = "Failed to resolve network address {}", _0)]
AddressResolve(AddressResolveError),
/// Authentication failure
#[display(fmt = "Authentication failure")]
Auth,
/// Unrecognised protocol
#[display(fmt = "Bad protocol")]
BadProtocol,
/// Expired message
#[display(fmt = "Expired message")]
Expired,
/// Peer not found
#[display(fmt = "Peer not found")]
PeerNotFound,
/// Peer is disconnected
#[display(fmt = "Peer disconnected: {}", _0)]
Disconnect(DisconnectReason),
/// Invalid node id
#[display(fmt = "Invalid node id")]
InvalidNodeId,
/// Packet size is over the protocol limit
#[display(fmt = "Packet is too large")]
OversizedPacket,
/// Reached system resource limits for this process
#[display(fmt = "Too many open files in this process. Check your resource limits and restart parity")]
ProcessTooManyFiles,
/// Reached system wide resource limits
#[display(fmt = "Too many open files on system. Consider closing some processes/release some file handlers or increas the system-wide resource limits and restart parity.")]
SystemTooManyFiles,
/// An unknown IO error occurred.
#[display(fmt = "Unexpected IO error: {}", _0)]
Io(io::Error),
}
/// Wraps io::Error for Display impl
#[derive(Debug)]
pub struct AddressResolveError(Option<io::Error>);
impl fmt::Display for AddressResolveError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.0.as_ref().map_or("".to_string(), |e| e.to_string()))
}
}
errors {
#[doc = "Error concerning the network address parsing subsystem."]
AddressParse {
description("Failed to parse network address"),
display("Failed to parse network address"),
}
impl From<Option<io::Error>> for AddressResolveError {
fn from(err: Option<io::Error>) -> Self {
AddressResolveError(err)
}
}
#[doc = "Error concerning the network address resolution subsystem."]
AddressResolve(err: Option<io::Error>) {
description("Failed to resolve network address"),
display("Failed to resolve network address {}", err.as_ref().map_or("".to_string(), |e| e.to_string())),
impl error::Error for Error {
fn source(&self) -> Option<&(error::Error + 'static)> {
match self {
Error::Decompression(e) => Some(e),
Error::Rlp(e) => Some(e),
_ => None,
}
}
}
#[doc = "Authentication failure"]
Auth {
description("Authentication failure"),
display("Authentication failure"),
}
impl From<IoError> for Error {
fn from(err: IoError) -> Self {
Error::SocketIo(err)
}
}
#[doc = "Unrecognised protocol"]
BadProtocol {
description("Bad protocol"),
display("Bad protocol"),
}
impl From<snappy::InvalidInput> for Error {
fn from(err: snappy::InvalidInput) -> Self {
Error::Decompression(err)
}
}
#[doc = "Expired message"]
Expired {
description("Expired message"),
display("Expired message"),
}
#[doc = "Peer not found"]
PeerNotFound {
description("Peer not found"),
display("Peer not found"),
}
#[doc = "Peer is disconnected"]
Disconnect(reason: DisconnectReason) {
description("Peer disconnected"),
display("Peer disconnected: {}", reason),
}
#[doc = "Invalid node id"]
InvalidNodeId {
description("Invalid node id"),
display("Invalid node id"),
}
#[doc = "Packet size is over the protocol limit"]
OversizedPacket {
description("Packet is too large"),
display("Packet is too large"),
}
#[doc = "Reached system resource limits for this process"]
ProcessTooManyFiles {
description("Too many open files in process."),
display("Too many open files in this process. Check your resource limits and restart parity"),
}
#[doc = "Reached system wide resource limits"]
SystemTooManyFiles {
description("Too many open files on system."),
display("Too many open files on system. Consider closing some processes/release some file handlers or increas the system-wide resource limits and restart parity."),
}
#[doc = "An unknown IO error occurred."]
Io(err: io::Error) {
description("IO Error"),
display("Unexpected IO error: {}", err),
}
impl From<rlp::DecoderError> for Error {
fn from(err: rlp::DecoderError) -> Self {
Error::Rlp(err)
}
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
match err.raw_os_error() {
Some(ENFILE) => ErrorKind::ProcessTooManyFiles.into(),
Some(EMFILE) => ErrorKind::SystemTooManyFiles.into(),
_ => Error::from_kind(ErrorKind::Io(err))
Some(ENFILE) => Error::ProcessTooManyFiles,
Some(EMFILE) => Error::SystemTooManyFiles,
_ => Error::Io(err)
}
}
}
impl From<ethkey::Error> for Error {
fn from(_err: ethkey::Error) -> Self {
ErrorKind::Auth.into()
Error::Auth
}
}
impl From<ethkey::crypto::Error> for Error {
fn from(_err: ethkey::crypto::Error) -> Self {
ErrorKind::Auth.into()
Error::Auth
}
}
impl From<crypto::error::SymmError> for Error {
fn from(_err: crypto::error::SymmError) -> Self {
ErrorKind::Auth.into()
Error::Auth
}
}
impl From<net::AddrParseError> for Error {
fn from(_err: net::AddrParseError) -> Self { ErrorKind::AddressParse.into() }
fn from(_err: net::AddrParseError) -> Self { Error::AddressParse }
}
#[test]
@ -208,13 +213,13 @@ fn test_errors() {
}
assert_eq!(DisconnectReason::Unknown, r);
match *<Error as From<rlp::DecoderError>>::from(rlp::DecoderError::RlpIsTooBig).kind() {
ErrorKind::Rlp(_) => {},
match <Error as From<rlp::DecoderError>>::from(rlp::DecoderError::RlpIsTooBig) {
Error::Rlp(_) => {},
_ => panic!("Unexpected error"),
}
match *<Error as From<ethkey::crypto::Error>>::from(ethkey::crypto::Error::InvalidMessage).kind() {
ErrorKind::Auth => {},
match <Error as From<ethkey::crypto::Error>>::from(ethkey::crypto::Error::InvalidMessage) {
Error::Auth => {},
_ => panic!("Unexpected error"),
}
}
@ -226,18 +231,18 @@ fn test_io_errors() {
assert_matches!(
<Error as From<io::Error>>::from(
io::Error::from_raw_os_error(ENFILE)
).kind(),
ErrorKind::ProcessTooManyFiles);
),
Error::ProcessTooManyFiles);
assert_matches!(
<Error as From<io::Error>>::from(
io::Error::from_raw_os_error(EMFILE)
).kind(),
ErrorKind::SystemTooManyFiles);
),
Error::SystemTooManyFiles);
assert_matches!(
<Error as From<io::Error>>::from(
io::Error::from_raw_os_error(0)
).kind(),
ErrorKind::Io(_));
),
Error::Io(_));
}

View File

@ -32,9 +32,7 @@ extern crate serde_derive;
#[cfg(test)] #[macro_use]
extern crate assert_matches;
#[macro_use]
extern crate error_chain;
extern crate derive_more;
#[macro_use]
extern crate lazy_static;
@ -46,7 +44,7 @@ mod error;
pub use connection_filter::{ConnectionFilter, ConnectionDirection};
pub use io::TimerToken;
pub use error::{Error, ErrorKind, DisconnectReason};
pub use error::{Error, DisconnectReason};
use client_version::ClientVersion;
use std::cmp::Ordering;