reth_network_api/
lib.rs

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