diff --git a/Cargo.lock b/Cargo.lock index 28f7a798d..ae8719813 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7586,6 +7586,7 @@ name = "reth-network-p2p" version = "1.0.5" dependencies = [ "auto_impl", + "derive_more", "futures", "parking_lot 0.12.3", "reth-consensus", @@ -7594,7 +7595,6 @@ dependencies = [ "reth-primitives", "reth-storage-errors", "serde", - "thiserror", "tokio", "tracing", ] diff --git a/crates/net/p2p/Cargo.toml b/crates/net/p2p/Cargo.toml index 261024427..e5b94b913 100644 --- a/crates/net/p2p/Cargo.toml +++ b/crates/net/p2p/Cargo.toml @@ -27,8 +27,8 @@ tokio = { workspace = true, features = ["sync"] } # misc auto_impl.workspace = true -thiserror.workspace = true tracing.workspace = true +derive_more.workspace = true parking_lot = { workspace = true, optional = true } diff --git a/crates/net/p2p/src/error.rs b/crates/net/p2p/src/error.rs index 91c3fa78f..597b2c3c5 100644 --- a/crates/net/p2p/src/error.rs +++ b/crates/net/p2p/src/error.rs @@ -1,12 +1,12 @@ use std::ops::RangeInclusive; +use derive_more::Display; use reth_consensus::ConsensusError; use reth_network_peers::WithPeerId; use reth_primitives::{ BlockHashOrNumber, BlockNumber, GotExpected, GotExpectedBoxed, Header, B256, }; use reth_storage_errors::{db::DatabaseError, provider::ProviderError}; -use thiserror::Error; use tokio::sync::{mpsc, oneshot}; use super::headers::client::HeadersRequest; @@ -78,26 +78,26 @@ impl EthResponseValidator for RequestResult> { /// Error variants that can happen when sending requests to a session. /// /// Represents errors encountered when sending requests. -#[derive(Clone, Debug, Error, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Display)] pub enum RequestError { /// Closed channel to the peer. - #[error("closed channel to the peer")] + #[display(fmt = "closed channel to the peer")] /// Indicates the channel to the peer is closed. ChannelClosed, /// Connection to a peer dropped while handling the request. - #[error("connection to a peer dropped while handling the request")] + #[display(fmt = "connection to a peer dropped while handling the request")] /// Represents a dropped connection while handling the request. ConnectionDropped, /// Capability message is not supported by the remote peer. - #[error("capability message is not supported by remote peer")] + #[display(fmt = "capability message is not supported by remote peer")] /// Indicates an unsupported capability message from the remote peer. UnsupportedCapability, /// Request timed out while awaiting response. - #[error("request timed out while awaiting response")] + #[display(fmt = "request timed out while awaiting response")] /// Represents a timeout while waiting for a response. Timeout, /// Received bad response. - #[error("received bad response")] + #[display(fmt = "received bad response")] /// Indicates a bad response was received. BadResponse, } @@ -128,77 +128,76 @@ impl From for RequestError { } } +#[cfg(feature = "std")] +impl std::error::Error for RequestError {} + /// The download result type pub type DownloadResult = Result; /// The downloader error type -#[derive(Error, Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Display)] pub enum DownloadError { /* ==================== HEADER ERRORS ==================== */ /// Header validation failed. - #[error("failed to validate header {hash}, block number {number}: {error}")] + #[display(fmt = "failed to validate header {hash}, block number {number}: {error}")] HeaderValidation { /// Hash of header failing validation hash: B256, /// Number of header failing validation number: u64, /// The details of validation failure - #[source] error: Box, }, /// Received an invalid tip. - #[error("received invalid tip: {0}")] + #[display(fmt = "received invalid tip: {_0}")] InvalidTip(GotExpectedBoxed), /// Received a tip with an invalid tip number. - #[error("received invalid tip number: {0}")] + #[display(fmt = "received invalid tip number: {_0}")] InvalidTipNumber(GotExpected), /// Received a response to a request with unexpected start block - #[error("headers response starts at unexpected block: {0}")] + #[display(fmt = "headers response starts at unexpected block: {_0}")] HeadersResponseStartBlockMismatch(GotExpected), /// Received headers with less than expected items. - #[error("received less headers than expected: {0}")] + #[display(fmt = "received less headers than expected: {_0}")] HeadersResponseTooShort(GotExpected), /* ==================== BODIES ERRORS ==================== */ /// Block validation failed - #[error("failed to validate body for header {hash}, block number {number}: {error}")] + #[display(fmt = "failed to validate body for header {hash}, block number {number}: {error}")] BodyValidation { /// Hash of the block failing validation hash: B256, /// Number of the block failing validation number: u64, /// The details of validation failure - #[source] error: Box, }, /// Received more bodies than requested. - #[error("received more bodies than requested: {0}")] + #[display(fmt = "received more bodies than requested: {_0}")] TooManyBodies(GotExpected), /// Headers missing from the database. - #[error("header missing from the database: {block_number}")] + #[display(fmt = "header missing from the database: {block_number}")] MissingHeader { /// Missing header block number. block_number: BlockNumber, }, /// Body range invalid - #[error("requested body range is invalid: {range:?}")] + #[display(fmt = "requested body range is invalid: {range:?}")] InvalidBodyRange { /// Invalid block number range. range: RangeInclusive, }, /* ==================== COMMON ERRORS ==================== */ /// Timed out while waiting for request id response. - #[error("timed out while waiting for response")] + #[display(fmt = "timed out while waiting for response")] Timeout, /// Received empty response while expecting non empty - #[error("received empty response")] + #[display(fmt = "received empty response")] EmptyResponse, /// Error while executing the request. - #[error(transparent)] - RequestError(#[from] RequestError), + RequestError(RequestError), /// Provider error. - #[error(transparent)] - Provider(#[from] ProviderError), + Provider(ProviderError), } impl From for DownloadError { @@ -207,6 +206,32 @@ impl From for DownloadError { } } +impl From for DownloadError { + fn from(error: RequestError) -> Self { + Self::RequestError(error) + } +} + +impl From for DownloadError { + fn from(error: ProviderError) -> Self { + Self::Provider(error) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for DownloadError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::HeaderValidation { error, .. } | Self::BodyValidation { error, .. } => { + std::error::Error::source(error) + } + Self::RequestError(error) => std::error::Error::source(error), + Self::Provider(error) => std::error::Error::source(error), + _ => None, + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/net/p2p/src/headers/error.rs b/crates/net/p2p/src/headers/error.rs index f586aaf74..3bda79c29 100644 --- a/crates/net/p2p/src/headers/error.rs +++ b/crates/net/p2p/src/headers/error.rs @@ -1,23 +1,31 @@ +use derive_more::Display; use reth_consensus::ConsensusError; use reth_primitives::SealedHeader; -use thiserror::Error; /// Header downloader result pub type HeadersDownloaderResult = Result; /// Error variants that can happen when sending requests to a session. -#[derive(Debug, Error, Clone, Eq, PartialEq)] +#[derive(Debug, Clone, Eq, PartialEq, Display)] pub enum HeadersDownloaderError { /// The downloaded header cannot be attached to the local head, /// but is valid otherwise. - #[error("valid downloaded header cannot be attached to the local head: {error}")] + #[display(fmt = "valid downloaded header cannot be attached to the local head: {error}")] DetachedHead { /// The local head we attempted to attach to. local_head: Box, /// The header we attempted to attach. header: Box, /// The error that occurred when attempting to attach the header. - #[source] error: Box, }, } + +#[cfg(feature = "std")] +impl std::error::Error for HeadersDownloaderError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::DetachedHead { error, .. } => Some(error), + } + } +}