Create Network variant in reth_interfaces::Error (#950)

This commit is contained in:
Ikechukwu Ahiara Marvellous
2023-01-22 20:59:50 +01:00
committed by GitHub
parent 009d2056f9
commit a331b54bb0
8 changed files with 98 additions and 14 deletions

3
Cargo.lock generated
View File

@ -4241,6 +4241,7 @@ dependencies = [
"reth-codecs", "reth-codecs",
"reth-db", "reth-db",
"reth-eth-wire", "reth-eth-wire",
"reth-network-api",
"reth-primitives", "reth-primitives",
"reth-rpc-types", "reth-rpc-types",
"secp256k1 0.24.2", "secp256k1 0.24.2",
@ -4399,6 +4400,8 @@ dependencies = [
"async-trait", "async-trait",
"reth-primitives", "reth-primitives",
"serde", "serde",
"thiserror",
"tokio",
] ]
[[package]] [[package]]

View File

@ -10,6 +10,7 @@ readme = "README.md"
reth-codecs = { path = "../storage/codecs" } reth-codecs = { path = "../storage/codecs" }
reth-primitives = { path = "../primitives" } reth-primitives = { path = "../primitives" }
reth-rpc-types = { path = "../net/rpc-types" } reth-rpc-types = { path = "../net/rpc-types" }
reth-network-api = { path = "../net/network-api"}
async-trait = "0.1.57" async-trait = "0.1.57"
thiserror = "1.0.37" thiserror = "1.0.37"
auto_impl = "1.0" auto_impl = "1.0"

View File

@ -11,8 +11,11 @@ description = "Network interfaces"
# reth # reth
reth-primitives = { path = "../../primitives" } reth-primitives = { path = "../../primitives" }
# io # io
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
# misc # misc
async-trait = "0.1" async-trait = "0.1"
thiserror = "1.0.37"
tokio = { version = "1.21.2", features = ["sync"] }

View File

@ -0,0 +1,22 @@
use thiserror::Error;
use tokio::sync::{mpsc, oneshot};
/// Network Errors
#[allow(missing_docs)]
#[derive(Error, Debug, Clone, PartialEq, Eq)]
pub enum NetworkError {
#[error("Sender has been dropped")]
ChannelClosed,
}
impl<T> From<mpsc::error::SendError<T>> for NetworkError {
fn from(_: mpsc::error::SendError<T>) -> Self {
NetworkError::ChannelClosed
}
}
impl From<oneshot::error::RecvError> for NetworkError {
fn from(_: oneshot::error::RecvError) -> Self {
NetworkError::ChannelClosed
}
}

View File

@ -12,19 +12,20 @@
use async_trait::async_trait; use async_trait::async_trait;
use reth_primitives::{NodeRecord, H256, U256}; use reth_primitives::{NodeRecord, H256, U256};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{error::Error, net::SocketAddr}; use std::net::SocketAddr;
/// Network Error
pub mod error;
pub use error::NetworkError;
/// Provides general purpose information about the network. /// Provides general purpose information about the network.
#[async_trait] #[async_trait]
pub trait NetworkInfo: Send + Sync { pub trait NetworkInfo: Send + Sync {
/// Associated error type for the network implementation.
type Error: Send + Sync + Error;
/// Returns the [`SocketAddr`] that listens for incoming connections. /// Returns the [`SocketAddr`] that listens for incoming connections.
fn local_addr(&self) -> SocketAddr; fn local_addr(&self) -> SocketAddr;
/// Returns the current status of the network being ran by the local node. /// Returns the current status of the network being ran by the local node.
async fn network_status(&self) -> Result<NetworkStatus, Self::Error>; async fn network_status(&self) -> Result<NetworkStatus, NetworkError>;
} }
/// Provides general purpose information about Peers in the network. /// Provides general purpose information about Peers in the network.

View File

@ -16,7 +16,7 @@ use reth_interfaces::{
sync::{SyncState, SyncStateProvider, SyncStateUpdater}, sync::{SyncState, SyncStateProvider, SyncStateUpdater},
}; };
use reth_net_common::bandwidth_meter::BandwidthMeter; use reth_net_common::bandwidth_meter::BandwidthMeter;
use reth_network_api::{EthProtocolInfo, NetworkInfo, NetworkStatus, PeersInfo}; use reth_network_api::{EthProtocolInfo, NetworkError, NetworkInfo, NetworkStatus, PeersInfo};
use reth_primitives::{NodeRecord, PeerId, TransactionSigned, TxHash, H256, U256}; use reth_primitives::{NodeRecord, PeerId, TransactionSigned, TxHash, H256, U256};
use std::{ use std::{
net::SocketAddr, net::SocketAddr,
@ -227,13 +227,11 @@ impl PeersInfo for NetworkHandle {
#[async_trait] #[async_trait]
impl NetworkInfo for NetworkHandle { impl NetworkInfo for NetworkHandle {
type Error = oneshot::error::RecvError;
fn local_addr(&self) -> SocketAddr { fn local_addr(&self) -> SocketAddr {
*self.inner.listener_address.lock() *self.inner.listener_address.lock()
} }
async fn network_status(&self) -> Result<NetworkStatus, Self::Error> { async fn network_status(&self) -> Result<NetworkStatus, NetworkError> {
let status = self.get_status().await?; let status = self.get_status().await?;
Ok(NetworkStatus { Ok(NetworkStatus {

View File

@ -1,11 +1,14 @@
use async_trait::async_trait; use async_trait::async_trait;
use jsonrpsee::core::RpcResult; use jsonrpsee::core::RpcResult;
use reth_network::{peers::PeerKind, NetworkHandle}; use reth_network::{peers::PeerKind, NetworkHandle};
use reth_network_api::{NetworkInfo, PeersInfo}; use reth_network_api::{NetworkInfo, PeersInfo};
use reth_primitives::NodeRecord; use reth_primitives::NodeRecord;
use reth_rpc_api::AdminApiServer; use reth_rpc_api::AdminApiServer;
use reth_rpc_types::NodeInfo; use reth_rpc_types::NodeInfo;
use crate::result::ToRpcResult;
/// `admin` API implementation. /// `admin` API implementation.
/// ///
/// This type provides the functionality for handling `admin` related requests. /// This type provides the functionality for handling `admin` related requests.
@ -52,10 +55,7 @@ impl AdminApiServer for AdminApi {
async fn node_info(&self) -> RpcResult<NodeInfo> { async fn node_info(&self) -> RpcResult<NodeInfo> {
let enr = self.network.local_node_record(); let enr = self.network.local_node_record();
let status = match self.network.network_status().await { let status = self.network.network_status().await.map_internal_err(|e| e.to_string())?;
Ok(status) => status,
Err(e) => return RpcResult::Err(jsonrpsee::core::Error::Custom(e.to_string())),
};
Ok(NodeInfo::new(enr, status)) Ok(NodeInfo::new(enr, status))
} }

View File

@ -1,6 +1,7 @@
//! Additional helpers for converting errors. //! Additional helpers for converting errors.
use jsonrpsee::core::{Error as RpcError, RpcResult}; use jsonrpsee::core::{Error as RpcError, RpcResult};
use reth_network_api::NetworkError;
/// Helper trait to easily convert various `Result` types into [`RpcResult`] /// Helper trait to easily convert various `Result` types into [`RpcResult`]
pub(crate) trait ToRpcResult<Ok, Err> { pub(crate) trait ToRpcResult<Ok, Err> {
@ -85,6 +86,61 @@ impl<Ok> ToRpcResult<Ok, reth_interfaces::Error> for reth_interfaces::Result<Ok>
} }
} }
impl<Ok> ToRpcResult<Ok, NetworkError> for Result<Ok, NetworkError> {
#[inline]
fn map_rpc_err<'a, F, M>(self, op: F) -> RpcResult<Ok>
where
F: FnOnce(NetworkError) -> (i32, M, Option<&'a [u8]>),
M: Into<String>,
{
match self {
Ok(t) => Ok(t),
Err(err) => {
let (code, msg, data) = op(err);
Err(rpc_err(code, msg, data))
}
}
}
#[inline]
fn map_internal_err<'a, F, M>(self, op: F) -> RpcResult<Ok>
where
F: FnOnce(NetworkError) -> M,
M: Into<String>,
{
match self {
Ok(t) => Ok(t),
Err(err) => Err(internal_rpc_err(op(err))),
}
}
#[inline]
fn map_internal_err_with_data<'a, F, M>(self, op: F) -> RpcResult<Ok>
where
F: FnOnce(NetworkError) -> (M, &'a [u8]),
M: Into<String>,
{
match self {
Ok(t) => Ok(t),
Err(err) => {
let (msg, data) = op(err);
Err(internal_rpc_err_with_data(msg, data))
}
}
}
#[inline]
fn with_message(self, msg: &str) -> RpcResult<Ok> {
match self {
Ok(t) => Ok(t),
Err(err) => {
let msg = format!("{msg}: {err:?}");
Err(internal_rpc_err(msg))
}
}
}
}
/// Constructs an internal JSON-RPC error. /// Constructs an internal JSON-RPC error.
pub(crate) fn internal_rpc_err(msg: impl Into<String>) -> jsonrpsee::core::Error { pub(crate) fn internal_rpc_err(msg: impl Into<String>) -> jsonrpsee::core::Error {
rpc_err(jsonrpsee::types::error::INTERNAL_ERROR_CODE, msg, None) rpc_err(jsonrpsee::types::error::INTERNAL_ERROR_CODE, msg, None)