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:
parent
dbdb57a8c0
commit
bf55db4c7e
5
Cargo.lock
generated
5
Cargo.lock
generated
@ -1013,6 +1013,7 @@ version = "1.12.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"common-types 0.1.0",
|
"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)",
|
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethcore 1.12.0",
|
"ethcore 1.12.0",
|
||||||
"ethcore-blockchain 0.1.0",
|
"ethcore-blockchain 0.1.0",
|
||||||
@ -1106,7 +1107,7 @@ name = "ethcore-network"
|
|||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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",
|
"ethcore-io 1.12.0",
|
||||||
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ethereum-types 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ethkey 0.3.0",
|
"ethkey 0.3.0",
|
||||||
@ -1243,7 +1244,7 @@ name = "ethcore-service"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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 1.12.0",
|
||||||
"ethcore-blockchain 0.1.0",
|
"ethcore-blockchain 0.1.0",
|
||||||
"ethcore-db 0.1.0",
|
"ethcore-db 0.1.0",
|
||||||
|
@ -10,6 +10,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
log = "0.4"
|
log = "0.4"
|
||||||
parity-bytes = "0.1"
|
parity-bytes = "0.1"
|
||||||
common-types = { path = "../types" }
|
common-types = { path = "../types" }
|
||||||
|
derive_more = "0.14.0"
|
||||||
ethcore = { path = ".."}
|
ethcore = { path = ".."}
|
||||||
ethcore-db = { path = "../db" }
|
ethcore-db = { path = "../db" }
|
||||||
ethcore-blockchain = { path = "../blockchain" }
|
ethcore-blockchain = { path = "../blockchain" }
|
||||||
|
@ -260,7 +260,7 @@ impl HeaderChain {
|
|||||||
let best_block = {
|
let best_block = {
|
||||||
let era = match candidates.get(&curr.best_num) {
|
let era = match candidates.get(&curr.best_num) {
|
||||||
Some(era) => era,
|
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];
|
let best = &era.candidates[0];
|
||||||
@ -582,7 +582,7 @@ impl HeaderChain {
|
|||||||
} else {
|
} else {
|
||||||
let msg = format!("header of block #{} not found in DB ; database in an \
|
let msg = format!("header of block #{} not found in DB ; database in an \
|
||||||
inconsistent state", h_num);
|
inconsistent state", h_num);
|
||||||
bail!(msg);
|
return Err(msg.into());
|
||||||
};
|
};
|
||||||
|
|
||||||
let decoded = header.decode().expect("decoding db value failed");
|
let decoded = header.decode().expect("decoding db value failed");
|
||||||
|
@ -86,8 +86,7 @@ extern crate keccak_hash as hash;
|
|||||||
extern crate triehash_ethereum as triehash;
|
extern crate triehash_ethereum as triehash;
|
||||||
extern crate kvdb;
|
extern crate kvdb;
|
||||||
extern crate memory_cache;
|
extern crate memory_cache;
|
||||||
#[macro_use]
|
extern crate derive_more;
|
||||||
extern crate error_chain;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate kvdb_memorydb;
|
extern crate kvdb_memorydb;
|
||||||
|
@ -66,32 +66,31 @@ pub const DEFAULT_NUM_CONSECUTIVE_FAILED_REQUESTS: usize = 1;
|
|||||||
|
|
||||||
/// OnDemand related errors
|
/// OnDemand related errors
|
||||||
pub mod error {
|
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;
|
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 {
|
impl std::error::Error for Error {
|
||||||
ChannelCanceled(Canceled) #[doc = "Canceled oneshot channel"];
|
fn source(&self) -> Option<&(std::error::Error + 'static)> {
|
||||||
}
|
match self {
|
||||||
|
Error::ChannelCanceled(err) => Some(err),
|
||||||
errors {
|
_ => None,
|
||||||
#[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")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// OnDemand Result
|
||||||
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Public interface for performing network requests `OnDemand`
|
/// Public interface for performing network requests `OnDemand`
|
||||||
@ -272,7 +271,7 @@ impl Pending {
|
|||||||
response_err
|
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() {
|
if self.sender.send(Err(err.into())).is_err() {
|
||||||
debug!(target: "on_demand", "Dropped oneshot channel receiver on no response");
|
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
|
// returning a peer discovery timeout during query attempts
|
||||||
fn request_limit_reached(self) {
|
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() {
|
if self.sender.send(Err(err.into())).is_err() {
|
||||||
debug!(target: "on_demand", "Dropped oneshot channel receiver on time out");
|
debug!(target: "on_demand", "Dropped oneshot channel receiver on time out");
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,6 @@
|
|||||||
|
|
||||||
//! Private transactions module.
|
//! Private transactions module.
|
||||||
|
|
||||||
// Recursion limit required because of
|
|
||||||
// error_chain foreign_links.
|
|
||||||
#![recursion_limit="256"]
|
|
||||||
|
|
||||||
mod encryptor;
|
mod encryptor;
|
||||||
mod key_server_keys;
|
mod key_server_keys;
|
||||||
mod private_transactions;
|
mod private_transactions;
|
||||||
|
@ -5,7 +5,7 @@ authors = ["Parity Technologies <admin@parity.io>"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ansi_term = "0.10"
|
ansi_term = "0.10"
|
||||||
error-chain = { version = "0.12", default-features = false }
|
derive_more = "0.14.0"
|
||||||
ethcore = { path = ".." }
|
ethcore = { path = ".." }
|
||||||
ethcore-blockchain = { path = "../blockchain" }
|
ethcore-blockchain = { path = "../blockchain" }
|
||||||
ethcore-io = { path = "../../util/io" }
|
ethcore-io = { path = "../../util/io" }
|
||||||
|
@ -14,18 +14,26 @@
|
|||||||
// 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// 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 ethcore;
|
||||||
use io;
|
use io;
|
||||||
use ethcore_private_tx;
|
use ethcore_private_tx;
|
||||||
|
|
||||||
error_chain! {
|
#[derive(Debug, derive_more::Display, derive_more::From)]
|
||||||
foreign_links {
|
pub enum Error {
|
||||||
Ethcore(ethcore::error::Error);
|
/// Ethcore Error
|
||||||
IoError(io::IoError);
|
Ethcore(ethcore::error::Error),
|
||||||
PrivateTransactions(ethcore_private_tx::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),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,7 @@ extern crate ethcore_sync as sync;
|
|||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
extern crate kvdb;
|
extern crate kvdb;
|
||||||
|
|
||||||
#[macro_use]
|
extern crate derive_more;
|
||||||
extern crate error_chain;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -42,5 +41,5 @@ mod stop_guard;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate kvdb_rocksdb;
|
extern crate kvdb_rocksdb;
|
||||||
|
|
||||||
pub use error::{Error, ErrorKind};
|
pub use error::Error;
|
||||||
pub use service::{ClientService, PrivateTxService};
|
pub use service::{ClientService, PrivateTxService};
|
||||||
|
@ -59,7 +59,7 @@ impl PrivateTxHandler for PrivateTxService {
|
|||||||
Ok(import_result) => Ok(import_result),
|
Ok(import_result) => Ok(import_result),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(target: "privatetx", "Unable to import private transaction packet: {}", 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),
|
Ok(import_result) => Ok(import_result),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(target: "privatetx", "Unable to import signed private transaction packet: {}", err);
|
warn!(target: "privatetx", "Unable to import signed private transaction packet: {}", err);
|
||||||
bail!(err.to_string())
|
return Err(err.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,6 @@
|
|||||||
//! cargo build --release
|
//! cargo build --release
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
// Recursion limit required because of
|
|
||||||
// error_chain foreign_links.
|
|
||||||
#![recursion_limit="128"]
|
|
||||||
|
|
||||||
extern crate ansi_term;
|
extern crate ansi_term;
|
||||||
extern crate bn;
|
extern crate bn;
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
@ -22,7 +22,7 @@ use std::time::Duration;
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use devp2p::NetworkService;
|
use devp2p::NetworkService;
|
||||||
use network::{NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId,
|
use network::{NetworkProtocolHandler, NetworkContext, PeerId, ProtocolId,
|
||||||
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error, ErrorKind,
|
NetworkConfiguration as BasicNetworkConfiguration, NonReservedPeerMode, Error,
|
||||||
ConnectionFilter};
|
ConnectionFilter};
|
||||||
use network::client_version::ClientVersion;
|
use network::client_version::ClientVersion;
|
||||||
|
|
||||||
@ -593,7 +593,7 @@ impl ChainNotify for EthSync {
|
|||||||
match self.network.start() {
|
match self.network.start() {
|
||||||
Err((err, listen_address)) => {
|
Err((err, listen_address)) => {
|
||||||
match err.into() {
|
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."))
|
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),
|
err => warn!("Error starting network: {}", err),
|
||||||
@ -983,7 +983,7 @@ impl ManageNetwork for LightSync {
|
|||||||
match self.network.start() {
|
match self.network.start() {
|
||||||
Err((err, listen_address)) => {
|
Err((err, listen_address)) => {
|
||||||
match err.into() {
|
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."))
|
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),
|
err => warn!("Error starting network: {}", err),
|
||||||
|
@ -435,13 +435,13 @@ impl BlockCollection {
|
|||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
warn!("Got body with no header {}", h);
|
warn!("Got body with no header {}", h);
|
||||||
Err(network::ErrorKind::BadProtocol.into())
|
Err(network::Error::BadProtocol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
trace!(target: "sync", "Ignored unknown/stale block body. tx_root = {:?}, uncles = {:?}", header_id.transactions_root, header_id.uncles);
|
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 => {
|
None => {
|
||||||
warn!("Got receipt with no header {}", h);
|
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(_) => {
|
hash_map::Entry::Vacant(_) => {
|
||||||
trace!(target: "sync", "Ignored unknown/stale block receipt {:?}", receipt_root);
|
trace!(target: "sync", "Ignored unknown/stale block receipt {:?}", receipt_root);
|
||||||
Err(network::ErrorKind::BadProtocol.into())
|
Err(network::Error::BadProtocol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,5 +76,5 @@ mod api;
|
|||||||
pub use api::*;
|
pub use api::*;
|
||||||
pub use chain::{SyncStatus, SyncState};
|
pub use chain::{SyncStatus, SyncState};
|
||||||
pub use devp2p::validate_node_url;
|
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};
|
pub use private_tx::{PrivateTxHandler, NoopPrivateTxHandler, SimplePrivateTxHandler};
|
||||||
|
@ -41,8 +41,6 @@ extern crate ethabi_contract;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate ethabi_derive;
|
extern crate ethabi_derive;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate log;
|
extern crate log;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
@ -168,7 +168,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
|
|||||||
|
|
||||||
if self.client.transaction_already_included(&hash) {
|
if self.client.transaction_already_included(&hash) {
|
||||||
trace!(target: "txqueue", "[{:?}] Rejected tx already in the blockchain", 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);
|
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.block_gas_limit,
|
||||||
self.options.tx_gas_limit,
|
self.options.tx_gas_limit,
|
||||||
);
|
);
|
||||||
bail!(transaction::Error::GasLimitExceeded {
|
return Err(transaction::Error::GasLimitExceeded {
|
||||||
limit: gas_limit,
|
limit: gas_limit,
|
||||||
got: *tx.gas(),
|
got: *tx.gas(),
|
||||||
});
|
});
|
||||||
@ -196,7 +196,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
|
|||||||
minimal_gas,
|
minimal_gas,
|
||||||
);
|
);
|
||||||
|
|
||||||
bail!(transaction::Error::InsufficientGas {
|
return Err(transaction::Error::InsufficientGas {
|
||||||
minimal: minimal_gas,
|
minimal: minimal_gas,
|
||||||
got: *tx.gas(),
|
got: *tx.gas(),
|
||||||
})
|
})
|
||||||
@ -216,7 +216,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
|
|||||||
tx.gas_price(),
|
tx.gas_price(),
|
||||||
self.options.minimal_gas_price,
|
self.options.minimal_gas_price,
|
||||||
);
|
);
|
||||||
bail!(transaction::Error::InsufficientGasPrice {
|
return Err(transaction::Error::InsufficientGasPrice {
|
||||||
minimal: self.options.minimal_gas_price,
|
minimal: self.options.minimal_gas_price,
|
||||||
got: *tx.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(),
|
tx.gas_price(),
|
||||||
vtx.transaction.gas_price,
|
vtx.transaction.gas_price,
|
||||||
);
|
);
|
||||||
bail!(transaction::Error::InsufficientGasPrice {
|
return Err(transaction::Error::InsufficientGasPrice {
|
||||||
minimal: vtx.transaction.gas_price,
|
minimal: vtx.transaction.gas_price,
|
||||||
got: *tx.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(),
|
Ok(signed) => signed.into(),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
debug!(target: "txqueue", "[{:?}] Rejected tx {:?}", hash, err);
|
debug!(target: "txqueue", "[{:?}] Rejected tx {:?}", hash, err);
|
||||||
bail!(err)
|
return Err(err)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Transaction::Local(tx) => tx,
|
Transaction::Local(tx) => tx,
|
||||||
@ -256,7 +256,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
|
|||||||
// Verify RLP payload
|
// Verify RLP payload
|
||||||
if let Err(err) = self.client.decode_transaction(&transaction.rlp_bytes()) {
|
if let Err(err) = self.client.decode_transaction(&transaction.rlp_bytes()) {
|
||||||
debug!(target: "txqueue", "[{:?}] Rejected transaction's rlp payload", err);
|
debug!(target: "txqueue", "[{:?}] Rejected transaction's rlp payload", err);
|
||||||
bail!(err)
|
return Err(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
let sender = transaction.sender();
|
let sender = transaction.sender();
|
||||||
@ -276,7 +276,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
|
|||||||
transaction.gas_price,
|
transaction.gas_price,
|
||||||
self.options.minimal_gas_price,
|
self.options.minimal_gas_price,
|
||||||
);
|
);
|
||||||
bail!(transaction::Error::InsufficientGasPrice {
|
return Err(transaction::Error::InsufficientGasPrice {
|
||||||
minimal: self.options.minimal_gas_price,
|
minimal: self.options.minimal_gas_price,
|
||||||
got: transaction.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",
|
"[{:?}] Rejected tx, price overflow",
|
||||||
hash
|
hash
|
||||||
);
|
);
|
||||||
bail!(transaction::Error::InsufficientBalance {
|
return Err(transaction::Error::InsufficientBalance {
|
||||||
cost: U256::max_value(),
|
cost: U256::max_value(),
|
||||||
balance: account_details.balance,
|
balance: account_details.balance,
|
||||||
});
|
});
|
||||||
@ -304,7 +304,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
|
|||||||
account_details.balance,
|
account_details.balance,
|
||||||
cost,
|
cost,
|
||||||
);
|
);
|
||||||
bail!(transaction::Error::InsufficientBalance {
|
return Err(transaction::Error::InsufficientBalance {
|
||||||
cost: cost,
|
cost: cost,
|
||||||
balance: account_details.balance,
|
balance: account_details.balance,
|
||||||
});
|
});
|
||||||
@ -318,7 +318,7 @@ impl<C: Client> txpool::Verifier<Transaction> for Verifier<C, ::pool::scoring::N
|
|||||||
transaction.nonce,
|
transaction.nonce,
|
||||||
account_details.nonce,
|
account_details.nonce,
|
||||||
);
|
);
|
||||||
bail!(transaction::Error::Old);
|
return Err(transaction::Error::Old);
|
||||||
}
|
}
|
||||||
|
|
||||||
let priority = match (is_own || account_details.is_local, is_retracted) {
|
let priority = match (is_own || account_details.is_local, is_retracted) {
|
||||||
|
@ -710,7 +710,7 @@ impl Configuration {
|
|||||||
for line in &lines {
|
for line in &lines {
|
||||||
match validate_node_url(line).map(Into::into) {
|
match validate_node_url(line).map(Into::into) {
|
||||||
None => continue,
|
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)),
|
Some(_) => return Err(format!("Invalid node address format given for a boot node: {}", line)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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| {
|
Some(ref x) if !x.is_empty() => x.split(',').map(|s| {
|
||||||
match validate_node_url(s).map(Into::into) {
|
match validate_node_url(s).map(Into::into) {
|
||||||
None => Ok(s.to_owned()),
|
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)),
|
Some(_) => Err(format!("Invalid node address format given for a boot node: {}", s)),
|
||||||
}
|
}
|
||||||
}).collect(),
|
}).collect(),
|
||||||
|
@ -25,7 +25,7 @@ use rlp::DecoderError;
|
|||||||
use types::transaction::Error as TransactionError;
|
use types::transaction::Error as TransactionError;
|
||||||
use ethcore_private_tx::Error as PrivateTransactionError;
|
use ethcore_private_tx::Error as PrivateTransactionError;
|
||||||
use vm::Error as VMError;
|
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 ethcore::client::BlockChainClient;
|
||||||
use types::blockchain_info::BlockChainInfo;
|
use types::blockchain_info::BlockChainInfo;
|
||||||
use v1::types::BlockNumber;
|
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 {
|
pub fn on_demand_error(err: OnDemandError) -> Error {
|
||||||
match err {
|
match err {
|
||||||
OnDemandError(OnDemandErrorKind::ChannelCanceled(e), _) => on_demand_cancel(e),
|
OnDemandError::ChannelCanceled(e) => on_demand_cancel(e),
|
||||||
OnDemandError(OnDemandErrorKind::RequestLimit, _) => timeout_new_peer(&err),
|
OnDemandError::RequestLimit => timeout_new_peer(&err),
|
||||||
OnDemandError(OnDemandErrorKind::BadResponse(_), _) => max_attempts_reached(&err),
|
OnDemandError::BadResponse(_) => max_attempts_reached(&err),
|
||||||
_ => on_demand_others(&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 {
|
pub fn status_error(has_peers: bool) -> Error {
|
||||||
if has_peers {
|
if has_peers {
|
||||||
no_work()
|
no_work()
|
||||||
|
@ -37,7 +37,7 @@ use tiny_keccak::Keccak;
|
|||||||
use ethkey::crypto;
|
use ethkey::crypto;
|
||||||
use handshake::Handshake;
|
use handshake::Handshake;
|
||||||
use io::{IoContext, StreamToken};
|
use io::{IoContext, StreamToken};
|
||||||
use network::{Error, ErrorKind};
|
use network::Error;
|
||||||
|
|
||||||
const ENCRYPTED_HEADER_LEN: usize = 32;
|
const ENCRYPTED_HEADER_LEN: usize = 32;
|
||||||
const RECEIVE_PAYLOAD: Duration = Duration::from_secs(30);
|
const RECEIVE_PAYLOAD: Duration = Duration::from_secs(30);
|
||||||
@ -358,7 +358,7 @@ impl EncryptedConnection {
|
|||||||
let mut header = RlpStream::new();
|
let mut header = RlpStream::new();
|
||||||
let len = payload.len();
|
let len = payload.len();
|
||||||
if len > MAX_PAYLOAD_SIZE {
|
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(&[(len >> 16) as u8, (len >> 8) as u8, len as u8], 1);
|
||||||
header.append_raw(&[0xc2u8, 0x80u8, 0x80u8], 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.
|
/// Decrypt and authenticate an incoming packet header. Prepare for receiving payload.
|
||||||
fn read_header(&mut self, header: &[u8]) -> Result<(), Error> {
|
fn read_header(&mut self, header: &[u8]) -> Result<(), Error> {
|
||||||
if header.len() != ENCRYPTED_HEADER_LEN {
|
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]);
|
EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &header[0..16]);
|
||||||
let mac = &header[16..];
|
let mac = &header[16..];
|
||||||
let mut expected = H256::zero();
|
let mut expected = H256::zero();
|
||||||
self.ingress_mac.clone().finalize(expected.as_bytes_mut());
|
self.ingress_mac.clone().finalize(expected.as_bytes_mut());
|
||||||
if mac != &expected[0..16] {
|
if mac != &expected[0..16] {
|
||||||
return Err(ErrorKind::Auth.into());
|
return Err(Error::Auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut hdec = H128::default();
|
let mut hdec = H128::default();
|
||||||
@ -422,7 +422,7 @@ impl EncryptedConnection {
|
|||||||
let padding = (16 - (self.payload_len % 16)) % 16;
|
let padding = (16 - (self.payload_len % 16)) % 16;
|
||||||
let full_length = self.payload_len + padding + 16;
|
let full_length = self.payload_len + padding + 16;
|
||||||
if payload.len() != full_length {
|
if payload.len() != full_length {
|
||||||
return Err(ErrorKind::Auth.into());
|
return Err(Error::Auth);
|
||||||
}
|
}
|
||||||
self.ingress_mac.update(&payload[0..payload.len() - 16]);
|
self.ingress_mac.update(&payload[0..payload.len() - 16]);
|
||||||
EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &[0u8; 0]);
|
EncryptedConnection::update_mac(&mut self.ingress_mac, &mut self.mac_encoder, &[0u8; 0]);
|
||||||
@ -430,7 +430,7 @@ impl EncryptedConnection {
|
|||||||
let mut expected = H128::default();
|
let mut expected = H128::default();
|
||||||
self.ingress_mac.clone().finalize(expected.as_bytes_mut());
|
self.ingress_mac.clone().finalize(expected.as_bytes_mut());
|
||||||
if mac != &expected[..] {
|
if mac != &expected[..] {
|
||||||
return Err(ErrorKind::Auth.into());
|
return Err(Error::Auth);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut packet = vec![0u8; self.payload_len];
|
let mut packet = vec![0u8; self.payload_len];
|
||||||
|
@ -27,7 +27,7 @@ use parity_bytes::Bytes;
|
|||||||
use rlp::{Rlp, RlpStream};
|
use rlp::{Rlp, RlpStream};
|
||||||
|
|
||||||
use ethkey::{KeyPair, recover, Secret, sign};
|
use ethkey::{KeyPair, recover, Secret, sign};
|
||||||
use network::{Error, ErrorKind};
|
use network::Error;
|
||||||
use network::IpFilter;
|
use network::IpFilter;
|
||||||
use node_table::*;
|
use node_table::*;
|
||||||
use PROTOCOL_VERSION;
|
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> {
|
pub fn on_packet(&mut self, packet: &[u8], from: SocketAddr) -> Result<Option<TableUpdates>, Error> {
|
||||||
// validate packet
|
// validate packet
|
||||||
if packet.len() < 32 + 65 + 4 + 1 {
|
if packet.len() < 32 + 65 + 4 + 1 {
|
||||||
return Err(ErrorKind::BadProtocol.into());
|
return Err(Error::BadProtocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash_signed = keccak(&packet[32..]);
|
let hash_signed = keccak(&packet[32..]);
|
||||||
if hash_signed[..] != packet[0..32] {
|
if hash_signed[..] != packet[0..32] {
|
||||||
return Err(ErrorKind::BadProtocol.into());
|
return Err(Error::BadProtocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
let signed = &packet[(32 + 65)..];
|
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();
|
let secs_since_epoch = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_secs();
|
||||||
if self.check_timestamps && timestamp < secs_since_epoch {
|
if self.check_timestamps && timestamp < secs_since_epoch {
|
||||||
debug!(target: "discovery", "Expired packet");
|
debug!(target: "discovery", "Expired packet");
|
||||||
return Err(ErrorKind::Expired.into());
|
return Err(Error::Expired);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ use ethkey::{Generator, KeyPair, Public, Random, recover, Secret, sign};
|
|||||||
use ethkey::crypto::{ecdh, ecies};
|
use ethkey::crypto::{ecdh, ecies};
|
||||||
use host::HostInfo;
|
use host::HostInfo;
|
||||||
use io::{IoContext, StreamToken};
|
use io::{IoContext, StreamToken};
|
||||||
use network::{Error, ErrorKind};
|
use network::Error;
|
||||||
use node_table::NodeId;
|
use node_table::NodeId;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
@ -166,7 +166,7 @@ impl Handshake {
|
|||||||
trace!(target: "network", "Received handshake auth from {:?}", self.connection.remote_addr_str());
|
trace!(target: "network", "Received handshake auth from {:?}", self.connection.remote_addr_str());
|
||||||
if data.len() != V4_AUTH_PACKET_SIZE {
|
if data.len() != V4_AUTH_PACKET_SIZE {
|
||||||
debug!(target: "network", "Wrong 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();
|
self.auth_cipher = data.to_vec();
|
||||||
match ecies::decrypt(secret, &[], data) {
|
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;
|
let total = ((u16::from(data[0]) << 8 | (u16::from(data[1]))) as usize) + 2;
|
||||||
if total < V4_AUTH_PACKET_SIZE {
|
if total < V4_AUTH_PACKET_SIZE {
|
||||||
debug!(target: "network", "Wrong EIP8 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();
|
let rest = total - data.len();
|
||||||
self.state = HandshakeState::ReadingAuthEip8;
|
self.state = HandshakeState::ReadingAuthEip8;
|
||||||
@ -212,7 +212,7 @@ impl Handshake {
|
|||||||
trace!(target: "network", "Received handshake ack from {:?}", self.connection.remote_addr_str());
|
trace!(target: "network", "Received handshake ack from {:?}", self.connection.remote_addr_str());
|
||||||
if data.len() != V4_ACK_PACKET_SIZE {
|
if data.len() != V4_ACK_PACKET_SIZE {
|
||||||
debug!(target: "network", "Wrong 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();
|
self.ack_cipher = data.to_vec();
|
||||||
match ecies::decrypt(secret, &[], data) {
|
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;
|
let total = (((u16::from(data[0])) << 8 | (u16::from(data[1]))) as usize) + 2;
|
||||||
if total < V4_ACK_PACKET_SIZE {
|
if total < V4_ACK_PACKET_SIZE {
|
||||||
debug!(target: "network", "Wrong EIP8 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();
|
let rest = total - data.len();
|
||||||
self.state = HandshakeState::ReadingAckEip8;
|
self.state = HandshakeState::ReadingAckEip8;
|
||||||
|
@ -44,7 +44,7 @@ use io::*;
|
|||||||
use ip_utils::{map_external_address, select_public_address};
|
use ip_utils::{map_external_address, select_public_address};
|
||||||
use network::{NetworkConfiguration, NetworkIoMessage, PacketId, PeerId, ProtocolId};
|
use network::{NetworkConfiguration, NetworkIoMessage, PacketId, PeerId, ProtocolId};
|
||||||
use network::{NetworkContext as NetworkContextTrait, NonReservedPeerMode};
|
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::{ConnectionDirection, ConnectionFilter};
|
||||||
use network::client_version::ClientVersion;
|
use network::client_version::ClientVersion;
|
||||||
use node_table::*;
|
use node_table::*;
|
||||||
@ -157,7 +157,7 @@ impl<'s> NetworkContextTrait for NetworkContext<'s> {
|
|||||||
|
|
||||||
fn respond(&self, packet_id: PacketId, data: Vec<u8>) -> Result<(), Error> {
|
fn respond(&self, packet_id: PacketId, data: Vec<u8>) -> Result<(), Error> {
|
||||||
assert!(self.session.is_some(), "Respond called without network context");
|
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) {
|
fn disable_peer(&self, peer: PeerId) {
|
||||||
@ -719,8 +719,8 @@ impl Host {
|
|||||||
Err(e) => {
|
Err(e) => {
|
||||||
let s = session.lock();
|
let s = session.lock();
|
||||||
trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e);
|
trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e);
|
||||||
match *e.kind() {
|
match e {
|
||||||
ErrorKind::Disconnect(DisconnectReason::IncompatibleProtocol) | ErrorKind::Disconnect(DisconnectReason::UselessPeer) => {
|
Error::Disconnect(DisconnectReason::IncompatibleProtocol) | Error::Disconnect(DisconnectReason::UselessPeer) => {
|
||||||
if let Some(id) = s.id() {
|
if let Some(id) = s.id() {
|
||||||
if !self.reserved_nodes.read().contains(id) {
|
if !self.reserved_nodes.read().contains(id) {
|
||||||
let mut nodes = self.nodes.write();
|
let mut nodes = self.nodes.write();
|
||||||
|
@ -68,8 +68,6 @@ extern crate bytes;
|
|||||||
extern crate crypto as rcrypto;
|
extern crate crypto as rcrypto;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
#[macro_use]
|
|
||||||
extern crate error_chain;
|
|
||||||
extern crate ethcore_io as io;
|
extern crate ethcore_io as io;
|
||||||
extern crate ethcore_network as network;
|
extern crate ethcore_network as network;
|
||||||
extern crate ethereum_types;
|
extern crate ethereum_types;
|
||||||
|
@ -31,7 +31,7 @@ use serde_json;
|
|||||||
|
|
||||||
use discovery::{NodeEntry, TableUpdates};
|
use discovery::{NodeEntry, TableUpdates};
|
||||||
use ip_utils::*;
|
use ip_utils::*;
|
||||||
use network::{AllowIP, Error, ErrorKind, IpFilter};
|
use network::{AllowIP, Error, IpFilter};
|
||||||
|
|
||||||
/// Node public key
|
/// Node public key
|
||||||
pub type NodeId = H512;
|
pub type NodeId = H512;
|
||||||
@ -133,8 +133,8 @@ impl FromStr for NodeEndpoint {
|
|||||||
address: a,
|
address: a,
|
||||||
udp_port: a.port()
|
udp_port: a.port()
|
||||||
}),
|
}),
|
||||||
Ok(None) => bail!(ErrorKind::AddressResolve(None)),
|
Ok(None) => return Err(Error::AddressResolve(None.into())),
|
||||||
Err(_) => Err(ErrorKind::AddressParse.into()) // always an io::Error of InvalidInput kind
|
Err(_) => Err(Error::AddressParse) // always an io::Error of InvalidInput kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ impl FromStr for Node {
|
|||||||
type Err = Error;
|
type Err = Error;
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let (id, endpoint) = if s.len() > 136 && &s[0..8] == "enode://" && &s[136..137] == "@" {
|
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 {
|
else {
|
||||||
(NodeId::default(), NodeEndpoint::from_str(s)?)
|
(NodeId::default(), NodeEndpoint::from_str(s)?)
|
||||||
@ -629,21 +629,21 @@ mod tests {
|
|||||||
fn endpoint_parse_empty_ip_string_returns_error() {
|
fn endpoint_parse_empty_ip_string_returns_error() {
|
||||||
let endpoint = NodeEndpoint::from_str("");
|
let endpoint = NodeEndpoint::from_str("");
|
||||||
assert!(endpoint.is_err());
|
assert!(endpoint.is_err());
|
||||||
assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse);
|
assert_matches!(endpoint.unwrap_err(), Error::AddressParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn endpoint_parse_invalid_ip_string_returns_error() {
|
fn endpoint_parse_invalid_ip_string_returns_error() {
|
||||||
let endpoint = NodeEndpoint::from_str("beef");
|
let endpoint = NodeEndpoint::from_str("beef");
|
||||||
assert!(endpoint.is_err());
|
assert!(endpoint.is_err());
|
||||||
assert_matches!(endpoint.unwrap_err().kind(), &ErrorKind::AddressParse);
|
assert_matches!(endpoint.unwrap_err(), Error::AddressParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn endpoint_parse_valid_ip_without_port_returns_error() {
|
fn endpoint_parse_valid_ip_without_port_returns_error() {
|
||||||
let endpoint = NodeEndpoint::from_str("123.123.123.123");
|
let endpoint = NodeEndpoint::from_str("123.123.123.123");
|
||||||
assert!(endpoint.is_err());
|
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");
|
let endpoint = NodeEndpoint::from_str("123.123.123.123:123");
|
||||||
assert!(endpoint.is_ok())
|
assert!(endpoint.is_ok())
|
||||||
}
|
}
|
||||||
@ -668,11 +668,11 @@ mod tests {
|
|||||||
fn node_parse_fails_for_invalid_urls() {
|
fn node_parse_fails_for_invalid_urls() {
|
||||||
let node = Node::from_str("foo");
|
let node = Node::from_str("foo");
|
||||||
assert!(node.is_err());
|
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");
|
let node = Node::from_str("enode://foo@bar");
|
||||||
assert!(node.is_err());
|
assert!(node.is_err());
|
||||||
assert_matches!(node.unwrap_err().kind(), &ErrorKind::AddressParse);
|
assert_matches!(node.unwrap_err(), Error::AddressParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -30,7 +30,7 @@ use connection::{Connection, EncryptedConnection, MAX_PAYLOAD_SIZE, Packet};
|
|||||||
use handshake::Handshake;
|
use handshake::Handshake;
|
||||||
use host::*;
|
use host::*;
|
||||||
use io::{IoContext, StreamToken};
|
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::client_version::ClientVersion;
|
||||||
use network::SessionCapabilityInfo;
|
use network::SessionCapabilityInfo;
|
||||||
use node_table::NodeId;
|
use node_table::NodeId;
|
||||||
@ -256,10 +256,10 @@ impl Session {
|
|||||||
where Message: Send + Sync + Clone {
|
where Message: Send + Sync + Clone {
|
||||||
if protocol.is_some() && (self.info.capabilities.is_empty() || !self.had_hello) {
|
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);
|
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() {
|
if self.expired() {
|
||||||
return Err(ErrorKind::Expired.into());
|
return Err(Error::Expired);
|
||||||
}
|
}
|
||||||
let mut i = 0usize;
|
let mut i = 0usize;
|
||||||
let pid = match protocol {
|
let pid = match protocol {
|
||||||
@ -281,7 +281,7 @@ impl Session {
|
|||||||
let mut payload = data; // create a reference with local lifetime
|
let mut payload = data; // create a reference with local lifetime
|
||||||
if self.compression {
|
if self.compression {
|
||||||
if payload.len() > MAX_PAYLOAD_SIZE {
|
if payload.len() > MAX_PAYLOAD_SIZE {
|
||||||
bail!(ErrorKind::OversizedPacket);
|
return Err(Error::OversizedPacket);
|
||||||
}
|
}
|
||||||
let len = snappy::compress_into(&payload, &mut compressed);
|
let len = snappy::compress_into(&payload, &mut compressed);
|
||||||
trace!(target: "network", "compressed {} to {}", payload.len(), len);
|
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>
|
fn read_packet<Message>(&mut self, io: &IoContext<Message>, packet: &Packet, host: &HostInfo) -> Result<SessionData, Error>
|
||||||
where Message: Send + Sync + Clone {
|
where Message: Send + Sync + Clone {
|
||||||
if packet.data.len() < 2 {
|
if packet.data.len() < 2 {
|
||||||
return Err(ErrorKind::BadProtocol.into());
|
return Err(Error::BadProtocol);
|
||||||
}
|
}
|
||||||
let packet_id = packet.data[0];
|
let packet_id = packet.data[0];
|
||||||
if packet_id != PACKET_HELLO && packet_id != PACKET_DISCONNECT && !self.had_hello {
|
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 data = if self.compression {
|
||||||
let compressed = &packet.data[1..];
|
let compressed = &packet.data[1..];
|
||||||
if snappy::decompressed_len(&compressed)? > MAX_PAYLOAD_SIZE {
|
if snappy::decompressed_len(&compressed)? > MAX_PAYLOAD_SIZE {
|
||||||
bail!(ErrorKind::OversizedPacket);
|
return Err(Error::OversizedPacket);
|
||||||
}
|
}
|
||||||
snappy::decompress(&compressed)?
|
snappy::decompress(&compressed)?
|
||||||
} else {
|
} else {
|
||||||
@ -358,7 +358,7 @@ impl Session {
|
|||||||
if self.had_hello {
|
if self.had_hello {
|
||||||
debug!(target:"network", "Disconnected: {}: {:?}", self.token(), DisconnectReason::from_u8(reason));
|
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 => {
|
PACKET_PING => {
|
||||||
self.send_pong(io)?;
|
self.send_pong(io)?;
|
||||||
@ -500,7 +500,7 @@ impl Session {
|
|||||||
rlp.append(&(reason as u32));
|
rlp.append(&(reason as u32));
|
||||||
self.send_packet(io, None, PACKET_DISCONNECT, &rlp.drain()).ok();
|
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 {
|
fn send<Message>(&mut self, io: &IoContext<Message>, data: &[u8]) -> Result<(), Error> where Message: Send + Sync + Clone {
|
||||||
|
@ -7,7 +7,7 @@ version = "1.12.0"
|
|||||||
authors = ["Parity Technologies <admin@parity.io>"]
|
authors = ["Parity Technologies <admin@parity.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
error-chain = { version = "0.12", default-features = false }
|
derive_more = "0.14.0"
|
||||||
parity-crypto = "0.4.0"
|
parity-crypto = "0.4.0"
|
||||||
ethcore-io = { path = "../io" }
|
ethcore-io = { path = "../io" }
|
||||||
ethereum-types = "0.6.0"
|
ethereum-types = "0.6.0"
|
||||||
|
@ -14,11 +14,7 @@
|
|||||||
// 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 Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// 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`
|
use std::{error, io, net, fmt};
|
||||||
// https://github.com/paritytech/parity-ethereum/issues/10302
|
|
||||||
#![allow(deprecated)]
|
|
||||||
|
|
||||||
use std::{io, net, fmt};
|
|
||||||
use libc::{ENFILE, EMFILE};
|
use libc::{ENFILE, EMFILE};
|
||||||
use io::IoError;
|
use io::IoError;
|
||||||
use {rlp, ethkey, crypto, snappy};
|
use {rlp, ethkey, crypto, snappy};
|
||||||
@ -85,118 +81,127 @@ impl fmt::Display for DisconnectReason {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
error_chain! {
|
/// Queue error
|
||||||
foreign_links {
|
#[derive(Debug, derive_more::Display)]
|
||||||
SocketIo(IoError) #[doc = "Socket IO error."];
|
pub enum Error {
|
||||||
Decompression(snappy::InvalidInput) #[doc = "Decompression error."];
|
/// Socket IO error.
|
||||||
Rlp(rlp::DecoderError) #[doc = "Rlp decoder 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 {
|
impl From<Option<io::Error>> for AddressResolveError {
|
||||||
#[doc = "Error concerning the network address parsing subsystem."]
|
fn from(err: Option<io::Error>) -> Self {
|
||||||
AddressParse {
|
AddressResolveError(err)
|
||||||
description("Failed to parse network address"),
|
}
|
||||||
display("Failed to parse network address"),
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[doc = "Error concerning the network address resolution subsystem."]
|
impl error::Error for Error {
|
||||||
AddressResolve(err: Option<io::Error>) {
|
fn source(&self) -> Option<&(error::Error + 'static)> {
|
||||||
description("Failed to resolve network address"),
|
match self {
|
||||||
display("Failed to resolve network address {}", err.as_ref().map_or("".to_string(), |e| e.to_string())),
|
Error::Decompression(e) => Some(e),
|
||||||
|
Error::Rlp(e) => Some(e),
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[doc = "Authentication failure"]
|
impl From<IoError> for Error {
|
||||||
Auth {
|
fn from(err: IoError) -> Self {
|
||||||
description("Authentication failure"),
|
Error::SocketIo(err)
|
||||||
display("Authentication failure"),
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = "Unrecognised protocol"]
|
impl From<snappy::InvalidInput> for Error {
|
||||||
BadProtocol {
|
fn from(err: snappy::InvalidInput) -> Self {
|
||||||
description("Bad protocol"),
|
Error::Decompression(err)
|
||||||
display("Bad protocol"),
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = "Expired message"]
|
impl From<rlp::DecoderError> for Error {
|
||||||
Expired {
|
fn from(err: rlp::DecoderError) -> Self {
|
||||||
description("Expired message"),
|
Error::Rlp(err)
|
||||||
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<io::Error> for Error {
|
impl From<io::Error> for Error {
|
||||||
fn from(err: io::Error) -> Self {
|
fn from(err: io::Error) -> Self {
|
||||||
match err.raw_os_error() {
|
match err.raw_os_error() {
|
||||||
Some(ENFILE) => ErrorKind::ProcessTooManyFiles.into(),
|
Some(ENFILE) => Error::ProcessTooManyFiles,
|
||||||
Some(EMFILE) => ErrorKind::SystemTooManyFiles.into(),
|
Some(EMFILE) => Error::SystemTooManyFiles,
|
||||||
_ => Error::from_kind(ErrorKind::Io(err))
|
_ => Error::Io(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ethkey::Error> for Error {
|
impl From<ethkey::Error> for Error {
|
||||||
fn from(_err: ethkey::Error) -> Self {
|
fn from(_err: ethkey::Error) -> Self {
|
||||||
ErrorKind::Auth.into()
|
Error::Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ethkey::crypto::Error> for Error {
|
impl From<ethkey::crypto::Error> for Error {
|
||||||
fn from(_err: ethkey::crypto::Error) -> Self {
|
fn from(_err: ethkey::crypto::Error) -> Self {
|
||||||
ErrorKind::Auth.into()
|
Error::Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<crypto::error::SymmError> for Error {
|
impl From<crypto::error::SymmError> for Error {
|
||||||
fn from(_err: crypto::error::SymmError) -> Self {
|
fn from(_err: crypto::error::SymmError) -> Self {
|
||||||
ErrorKind::Auth.into()
|
Error::Auth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<net::AddrParseError> for Error {
|
impl From<net::AddrParseError> for Error {
|
||||||
fn from(_err: net::AddrParseError) -> Self { ErrorKind::AddressParse.into() }
|
fn from(_err: net::AddrParseError) -> Self { Error::AddressParse }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -208,13 +213,13 @@ fn test_errors() {
|
|||||||
}
|
}
|
||||||
assert_eq!(DisconnectReason::Unknown, r);
|
assert_eq!(DisconnectReason::Unknown, r);
|
||||||
|
|
||||||
match *<Error as From<rlp::DecoderError>>::from(rlp::DecoderError::RlpIsTooBig).kind() {
|
match <Error as From<rlp::DecoderError>>::from(rlp::DecoderError::RlpIsTooBig) {
|
||||||
ErrorKind::Rlp(_) => {},
|
Error::Rlp(_) => {},
|
||||||
_ => panic!("Unexpected error"),
|
_ => panic!("Unexpected error"),
|
||||||
}
|
}
|
||||||
|
|
||||||
match *<Error as From<ethkey::crypto::Error>>::from(ethkey::crypto::Error::InvalidMessage).kind() {
|
match <Error as From<ethkey::crypto::Error>>::from(ethkey::crypto::Error::InvalidMessage) {
|
||||||
ErrorKind::Auth => {},
|
Error::Auth => {},
|
||||||
_ => panic!("Unexpected error"),
|
_ => panic!("Unexpected error"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,18 +231,18 @@ fn test_io_errors() {
|
|||||||
assert_matches!(
|
assert_matches!(
|
||||||
<Error as From<io::Error>>::from(
|
<Error as From<io::Error>>::from(
|
||||||
io::Error::from_raw_os_error(ENFILE)
|
io::Error::from_raw_os_error(ENFILE)
|
||||||
).kind(),
|
),
|
||||||
ErrorKind::ProcessTooManyFiles);
|
Error::ProcessTooManyFiles);
|
||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
<Error as From<io::Error>>::from(
|
<Error as From<io::Error>>::from(
|
||||||
io::Error::from_raw_os_error(EMFILE)
|
io::Error::from_raw_os_error(EMFILE)
|
||||||
).kind(),
|
),
|
||||||
ErrorKind::SystemTooManyFiles);
|
Error::SystemTooManyFiles);
|
||||||
|
|
||||||
assert_matches!(
|
assert_matches!(
|
||||||
<Error as From<io::Error>>::from(
|
<Error as From<io::Error>>::from(
|
||||||
io::Error::from_raw_os_error(0)
|
io::Error::from_raw_os_error(0)
|
||||||
).kind(),
|
),
|
||||||
ErrorKind::Io(_));
|
Error::Io(_));
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,7 @@ extern crate serde_derive;
|
|||||||
|
|
||||||
#[cfg(test)] #[macro_use]
|
#[cfg(test)] #[macro_use]
|
||||||
extern crate assert_matches;
|
extern crate assert_matches;
|
||||||
|
extern crate derive_more;
|
||||||
#[macro_use]
|
|
||||||
extern crate error_chain;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
@ -46,7 +44,7 @@ mod error;
|
|||||||
|
|
||||||
pub use connection_filter::{ConnectionFilter, ConnectionDirection};
|
pub use connection_filter::{ConnectionFilter, ConnectionDirection};
|
||||||
pub use io::TimerToken;
|
pub use io::TimerToken;
|
||||||
pub use error::{Error, ErrorKind, DisconnectReason};
|
pub use error::{Error, DisconnectReason};
|
||||||
|
|
||||||
use client_version::ClientVersion;
|
use client_version::ClientVersion;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
Loading…
Reference in New Issue
Block a user