reth_network_api/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
//! Reth interface definitions and commonly used types for the reth-network crate.
//!
//! Provides abstractions for the reth-network crate.
//!
//! ## Feature Flags
//!
//! - `serde` (default): Enable serde support
#![doc(
html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
pub mod downloaders;
/// Network Error
pub mod error;
pub mod events;
/// Implementation of network traits for that does nothing.
pub mod noop;
pub mod test_utils;
pub use alloy_rpc_types_admin::EthProtocolInfo;
use reth_network_p2p::sync::NetworkSyncUpdater;
pub use reth_network_p2p::BlockClient;
pub use reth_network_types::{PeerKind, Reputation, ReputationChangeKind};
pub use downloaders::BlockDownloaderProvider;
pub use error::NetworkError;
pub use events::{
DiscoveredEvent, DiscoveryEvent, NetworkEvent, NetworkEventListenerProvider, PeerRequest,
PeerRequestSender,
};
use std::{future::Future, net::SocketAddr, sync::Arc, time::Instant};
use reth_eth_wire_types::{capability::Capabilities, DisconnectReason, EthVersion, Status};
use reth_network_peers::NodeRecord;
/// The `PeerId` type.
pub type PeerId = alloy_primitives::B512;
/// Helper trait that unifies network API needed to launch node.
pub trait FullNetwork:
BlockDownloaderProvider
+ NetworkSyncUpdater
+ NetworkInfo
+ NetworkEventListenerProvider
+ PeersInfo
+ Peers
+ Clone
+ 'static
{
}
impl<T> FullNetwork for T where
T: BlockDownloaderProvider
+ NetworkSyncUpdater
+ NetworkInfo
+ NetworkEventListenerProvider
+ PeersInfo
+ Peers
+ Clone
+ 'static
{
}
/// Provides general purpose information about the network.
#[auto_impl::auto_impl(&, Arc)]
pub trait NetworkInfo: Send + Sync {
/// Returns the [`SocketAddr`] that listens for incoming connections.
fn local_addr(&self) -> SocketAddr;
/// Returns the current status of the network being ran by the local node.
fn network_status(&self) -> impl Future<Output = Result<NetworkStatus, NetworkError>> + Send;
/// Returns the chain id
fn chain_id(&self) -> u64;
/// Returns `true` if the network is undergoing sync.
fn is_syncing(&self) -> bool;
/// Returns `true` when the node is undergoing the very first Pipeline sync.
fn is_initially_syncing(&self) -> bool;
}
/// Provides general purpose information about Peers in the network.
#[auto_impl::auto_impl(&, Arc)]
pub trait PeersInfo: Send + Sync {
/// Returns how many peers the network is currently connected to.
///
/// Note: this should only include established connections and _not_ ongoing attempts.
fn num_connected_peers(&self) -> usize;
/// Returns the Ethereum Node Record of the node.
fn local_node_record(&self) -> NodeRecord;
/// Returns the local ENR of the node.
fn local_enr(&self) -> enr::Enr<enr::secp256k1::SecretKey>;
}
/// Provides an API for managing the peers of the network.
#[auto_impl::auto_impl(&, Arc)]
pub trait Peers: PeersInfo {
/// Adds a peer to the peer set with TCP `SocketAddr`.
fn add_peer(&self, peer: PeerId, tcp_addr: SocketAddr) {
self.add_peer_kind(peer, PeerKind::Static, tcp_addr, None);
}
/// Adds a peer to the peer set with TCP and UDP `SocketAddr`.
fn add_peer_with_udp(&self, peer: PeerId, tcp_addr: SocketAddr, udp_addr: SocketAddr) {
self.add_peer_kind(peer, PeerKind::Static, tcp_addr, Some(udp_addr));
}
/// Adds a trusted [`PeerId`] to the peer set.
///
/// This allows marking a peer as trusted without having to know the peer's address.
fn add_trusted_peer_id(&self, peer: PeerId);
/// Adds a trusted peer to the peer set with TCP `SocketAddr`.
fn add_trusted_peer(&self, peer: PeerId, tcp_addr: SocketAddr) {
self.add_peer_kind(peer, PeerKind::Trusted, tcp_addr, None);
}
/// Adds a trusted peer with TCP and UDP `SocketAddr` to the peer set.
fn add_trusted_peer_with_udp(&self, peer: PeerId, tcp_addr: SocketAddr, udp_addr: SocketAddr) {
self.add_peer_kind(peer, PeerKind::Trusted, tcp_addr, Some(udp_addr));
}
/// Adds a peer to the known peer set, with the given kind.
fn add_peer_kind(
&self,
peer: PeerId,
kind: PeerKind,
tcp_addr: SocketAddr,
udp_addr: Option<SocketAddr>,
);
/// Returns the rpc [`PeerInfo`] for all connected [`PeerKind::Trusted`] peers.
fn get_trusted_peers(
&self,
) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send {
self.get_peers_by_kind(PeerKind::Trusted)
}
/// Returns the rpc [`PeerInfo`] for all connected [`PeerKind::Basic`] peers.
fn get_basic_peers(&self) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send {
self.get_peers_by_kind(PeerKind::Basic)
}
/// Returns the rpc [`PeerInfo`] for all connected peers with the given kind.
fn get_peers_by_kind(
&self,
kind: PeerKind,
) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send;
/// Returns the rpc [`PeerInfo`] for all connected peers.
fn get_all_peers(&self) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send;
/// Returns the rpc [`PeerInfo`] for the given peer id.
///
/// Returns `None` if the peer is not connected.
fn get_peer_by_id(
&self,
peer_id: PeerId,
) -> impl Future<Output = Result<Option<PeerInfo>, NetworkError>> + Send;
/// Returns the rpc [`PeerInfo`] for the given peers if they are connected.
///
/// Note: This only returns peers that are connected, unconnected peers are ignored but keeping
/// the order in which they were requested.
fn get_peers_by_id(
&self,
peer_ids: Vec<PeerId>,
) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send;
/// Removes a peer from the peer set that corresponds to given kind.
fn remove_peer(&self, peer: PeerId, kind: PeerKind);
/// Disconnect an existing connection to the given peer.
fn disconnect_peer(&self, peer: PeerId);
/// Disconnect an existing connection to the given peer using the provided reason
fn disconnect_peer_with_reason(&self, peer: PeerId, reason: DisconnectReason);
/// Connect to the given peer. NOTE: if the maximum number out outbound sessions is reached,
/// this won't do anything. See `reth_network::SessionManager::dial_outbound`.
fn connect_peer(&self, peer: PeerId, tcp_addr: SocketAddr) {
self.connect_peer_kind(peer, PeerKind::Static, tcp_addr, None)
}
/// Connects a peer to the known peer set, with the given kind.
fn connect_peer_kind(
&self,
peer: PeerId,
kind: PeerKind,
tcp_addr: SocketAddr,
udp_addr: Option<SocketAddr>,
);
/// Send a reputation change for the given peer.
fn reputation_change(&self, peer_id: PeerId, kind: ReputationChangeKind);
/// Get the reputation of a peer.
fn reputation_by_id(
&self,
peer_id: PeerId,
) -> impl Future<Output = Result<Option<Reputation>, NetworkError>> + Send;
}
/// Info about an active peer session.
#[derive(Debug, Clone)]
pub struct PeerInfo {
/// Announced capabilities of the peer
pub capabilities: Arc<Capabilities>,
/// The identifier of the remote peer
pub remote_id: PeerId,
/// The client's name and version
pub client_version: Arc<str>,
/// The peer's enode
pub enode: String,
/// The peer's enr
pub enr: Option<String>,
/// The peer's address we're connected to
pub remote_addr: SocketAddr,
/// The local address of the connection
pub local_addr: Option<SocketAddr>,
/// The direction of the session
pub direction: Direction,
/// The negotiated eth version.
pub eth_version: EthVersion,
/// The Status message the peer sent for the `eth` handshake
pub status: Arc<Status>,
/// The timestamp when the session to that peer has been established.
pub session_established: Instant,
/// The peer's connection kind
pub kind: PeerKind,
}
/// The direction of the connection.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Direction {
/// Incoming connection.
Incoming,
/// Outgoing connection to a specific node.
Outgoing(PeerId),
}
impl Direction {
/// Returns `true` if this an incoming connection.
pub const fn is_incoming(&self) -> bool {
matches!(self, Self::Incoming)
}
/// Returns `true` if this an outgoing connection.
pub const fn is_outgoing(&self) -> bool {
matches!(self, Self::Outgoing(_))
}
}
impl std::fmt::Display for Direction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Incoming => write!(f, "incoming"),
Self::Outgoing(_) => write!(f, "outgoing"),
}
}
}
/// The status of the network being ran by the local node.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct NetworkStatus {
/// The local node client version.
pub client_version: String,
/// The current ethereum protocol version
pub protocol_version: u64,
/// Information about the Ethereum Wire Protocol.
pub eth_protocol_info: EthProtocolInfo,
}