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;
27pub use reth_network_p2p::{BlockClient, HeadersClient};
28pub use reth_network_types::{PeerKind, Reputation, ReputationChangeKind};
29
30pub use downloaders::BlockDownloaderProvider;
31pub use error::NetworkError;
32pub use events::{
33 DiscoveredEvent, DiscoveryEvent, NetworkEvent, NetworkEventListenerProvider, PeerRequest,
34 PeerRequestSender,
35};
36
37use reth_eth_wire_types::{
38 capability::Capabilities, Capability, DisconnectReason, EthVersion, NetworkPrimitives,
39 UnifiedStatus,
40};
41use reth_network_p2p::sync::NetworkSyncUpdater;
42use reth_network_peers::NodeRecord;
43use std::{future::Future, net::SocketAddr, sync::Arc, time::Instant};
44
45pub type PeerId = alloy_primitives::B512;
47
48pub trait FullNetwork:
50 BlockDownloaderProvider<
51 Client: BlockClient<Block = <Self::Primitives as NetworkPrimitives>::Block>,
52 > + NetworkSyncUpdater
53 + NetworkInfo
54 + NetworkEventListenerProvider
55 + Peers
56 + PeersHandleProvider
57 + Clone
58 + Unpin
59 + 'static
60{
61}
62
63impl<T> FullNetwork for T where
64 T: BlockDownloaderProvider<
65 Client: BlockClient<Block = <Self::Primitives as NetworkPrimitives>::Block>,
66 > + NetworkSyncUpdater
67 + NetworkInfo
68 + NetworkEventListenerProvider
69 + Peers
70 + PeersHandleProvider
71 + Clone
72 + Unpin
73 + 'static
74{
75}
76
77#[auto_impl::auto_impl(&, Arc)]
79pub trait NetworkInfo: Send + Sync {
80 fn local_addr(&self) -> SocketAddr;
82
83 fn network_status(&self) -> impl Future<Output = Result<NetworkStatus, NetworkError>> + Send;
85
86 fn chain_id(&self) -> u64;
88
89 fn is_syncing(&self) -> bool;
91
92 fn is_initially_syncing(&self) -> bool;
94}
95
96#[auto_impl::auto_impl(&, Arc)]
98pub trait PeersInfo: Send + Sync {
99 fn num_connected_peers(&self) -> usize;
103
104 fn local_node_record(&self) -> NodeRecord;
106
107 fn local_enr(&self) -> enr::Enr<enr::secp256k1::SecretKey>;
109}
110
111#[auto_impl::auto_impl(&, Arc)]
113pub trait Peers: PeersInfo {
114 fn add_peer(&self, peer: PeerId, tcp_addr: SocketAddr) {
116 self.add_peer_kind(peer, PeerKind::Static, tcp_addr, None);
117 }
118
119 fn add_peer_with_udp(&self, peer: PeerId, tcp_addr: SocketAddr, udp_addr: SocketAddr) {
121 self.add_peer_kind(peer, PeerKind::Static, tcp_addr, Some(udp_addr));
122 }
123
124 fn add_trusted_peer_id(&self, peer: PeerId);
128
129 fn add_trusted_peer(&self, peer: PeerId, tcp_addr: SocketAddr) {
131 self.add_peer_kind(peer, PeerKind::Trusted, tcp_addr, None);
132 }
133
134 fn add_trusted_peer_with_udp(&self, peer: PeerId, tcp_addr: SocketAddr, udp_addr: SocketAddr) {
136 self.add_peer_kind(peer, PeerKind::Trusted, tcp_addr, Some(udp_addr));
137 }
138
139 fn add_peer_kind(
141 &self,
142 peer: PeerId,
143 kind: PeerKind,
144 tcp_addr: SocketAddr,
145 udp_addr: Option<SocketAddr>,
146 );
147
148 fn get_trusted_peers(
150 &self,
151 ) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send {
152 self.get_peers_by_kind(PeerKind::Trusted)
153 }
154
155 fn get_basic_peers(&self) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send {
157 self.get_peers_by_kind(PeerKind::Basic)
158 }
159
160 fn get_peers_by_kind(
162 &self,
163 kind: PeerKind,
164 ) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send;
165
166 fn get_all_peers(&self) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send;
168
169 fn get_peer_by_id(
173 &self,
174 peer_id: PeerId,
175 ) -> impl Future<Output = Result<Option<PeerInfo>, NetworkError>> + Send;
176
177 fn get_peers_by_id(
182 &self,
183 peer_ids: Vec<PeerId>,
184 ) -> impl Future<Output = Result<Vec<PeerInfo>, NetworkError>> + Send;
185
186 fn remove_peer(&self, peer: PeerId, kind: PeerKind);
188
189 fn disconnect_peer(&self, peer: PeerId);
191
192 fn disconnect_peer_with_reason(&self, peer: PeerId, reason: DisconnectReason);
194
195 fn connect_peer(&self, peer: PeerId, tcp_addr: SocketAddr) {
198 self.connect_peer_kind(peer, PeerKind::Static, tcp_addr, None)
199 }
200
201 fn connect_peer_kind(
203 &self,
204 peer: PeerId,
205 kind: PeerKind,
206 tcp_addr: SocketAddr,
207 udp_addr: Option<SocketAddr>,
208 );
209
210 fn reputation_change(&self, peer_id: PeerId, kind: ReputationChangeKind);
212
213 fn reputation_by_id(
215 &self,
216 peer_id: PeerId,
217 ) -> impl Future<Output = Result<Option<Reputation>, NetworkError>> + Send;
218}
219
220#[derive(Debug, Clone)]
222pub struct PeerInfo {
223 pub capabilities: Arc<Capabilities>,
225 pub remote_id: PeerId,
227 pub client_version: Arc<str>,
229 pub enode: String,
231 pub enr: Option<String>,
233 pub remote_addr: SocketAddr,
235 pub local_addr: Option<SocketAddr>,
237 pub direction: Direction,
239 pub eth_version: EthVersion,
241 pub status: Arc<UnifiedStatus>,
243 pub session_established: Instant,
245 pub kind: PeerKind,
247}
248
249#[derive(Debug, Copy, Clone, PartialEq, Eq)]
251pub enum Direction {
252 Incoming,
254 Outgoing(PeerId),
256}
257
258impl Direction {
259 pub const fn is_incoming(&self) -> bool {
261 matches!(self, Self::Incoming)
262 }
263
264 pub const fn is_outgoing(&self) -> bool {
266 matches!(self, Self::Outgoing(_))
267 }
268}
269
270impl std::fmt::Display for Direction {
271 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
272 match self {
273 Self::Incoming => write!(f, "incoming"),
274 Self::Outgoing(_) => write!(f, "outgoing"),
275 }
276 }
277}
278
279#[derive(Clone, Debug)]
281#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
282pub struct NetworkStatus {
283 pub client_version: String,
285 pub protocol_version: u64,
287 pub eth_protocol_info: EthProtocolInfo,
289 pub capabilities: Vec<Capability>,
291}