1#![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;
17pub mod error;
19pub mod events;
20pub 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
43pub type PeerId = alloy_primitives::B512;
45
46pub 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#[auto_impl::auto_impl(&, Arc)]
75pub trait NetworkInfo: Send + Sync {
76 fn local_addr(&self) -> SocketAddr;
78
79 fn network_status(&self) -> impl Future<Output = Result<NetworkStatus, NetworkError>> + Send;
81
82 fn chain_id(&self) -> u64;
84
85 fn is_syncing(&self) -> bool;
87
88 fn is_initially_syncing(&self) -> bool;
90}
91
92#[auto_impl::auto_impl(&, Arc)]
94pub trait PeersInfo: Send + Sync {
95 fn num_connected_peers(&self) -> usize;
99
100 fn local_node_record(&self) -> NodeRecord;
102
103 fn local_enr(&self) -> enr::Enr<enr::secp256k1::SecretKey>;
105}
106
107#[auto_impl::auto_impl(&, Arc)]
109pub trait Peers: PeersInfo {
110 fn add_peer(&self, peer: PeerId, tcp_addr: SocketAddr) {
112 self.add_peer_kind(peer, PeerKind::Static, tcp_addr, None);
113 }
114
115 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 fn add_trusted_peer_id(&self, peer: PeerId);
124
125 fn add_trusted_peer(&self, peer: PeerId, tcp_addr: SocketAddr) {
127 self.add_peer_kind(peer, PeerKind::Trusted, tcp_addr, None);
128 }
129
130 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 fn add_peer_kind(
137 &self,
138 peer: PeerId,
139 kind: PeerKind,
140 tcp_addr: SocketAddr,
141 udp_addr: Option<SocketAddr>,
142 );
143
144 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 fn get_basic_peers(&self) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send {
153 self.get_peers_by_kind(PeerKind::Basic)
154 }
155
156 fn get_peers_by_kind(
158 &self,
159 kind: PeerKind,
160 ) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send;
161
162 fn get_all_peers(&self) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send;
164
165 fn get_peer_by_id(
169 &self,
170 peer_id: PeerId,
171 ) -> impl Future<Output = Result<Option<PeerInfo>, NetworkError>> + Send;
172
173 fn get_peers_by_id(
178 &self,
179 peer_ids: Vec<PeerId>,
180 ) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send;
181
182 fn remove_peer(&self, peer: PeerId, kind: PeerKind);
184
185 fn disconnect_peer(&self, peer: PeerId);
187
188 fn disconnect_peer_with_reason(&self, peer: PeerId, reason: DisconnectReason);
190
191 fn connect_peer(&self, peer: PeerId, tcp_addr: SocketAddr) {
194 self.connect_peer_kind(peer, PeerKind::Static, tcp_addr, None)
195 }
196
197 fn connect_peer_kind(
199 &self,
200 peer: PeerId,
201 kind: PeerKind,
202 tcp_addr: SocketAddr,
203 udp_addr: Option<SocketAddr>,
204 );
205
206 fn reputation_change(&self, peer_id: PeerId, kind: ReputationChangeKind);
208
209 fn reputation_by_id(
211 &self,
212 peer_id: PeerId,
213 ) -> impl Future<Output = Result<Option<Reputation>, NetworkError>> + Send;
214}
215
216#[derive(Debug, Clone)]
218pub struct PeerInfo {
219 pub capabilities: Arc<Capabilities>,
221 pub remote_id: PeerId,
223 pub client_version: Arc<str>,
225 pub enode: String,
227 pub enr: Option<String>,
229 pub remote_addr: SocketAddr,
231 pub local_addr: Option<SocketAddr>,
233 pub direction: Direction,
235 pub eth_version: EthVersion,
237 pub status: Arc<Status>,
239 pub session_established: Instant,
241 pub kind: PeerKind,
243}
244
245#[derive(Debug, Copy, Clone, PartialEq, Eq)]
247pub enum Direction {
248 Incoming,
250 Outgoing(PeerId),
252}
253
254impl Direction {
255 pub const fn is_incoming(&self) -> bool {
257 matches!(self, Self::Incoming)
258 }
259
260 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#[derive(Clone, Debug)]
277#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
278pub struct NetworkStatus {
279 pub client_version: String,
281 pub protocol_version: u64,
283 pub eth_protocol_info: EthProtocolInfo,
285}