reth_network_api/
noop.rs

1//! A network implementation that does nothing.
2//!
3//! This is useful for wiring components together that don't require network but still need to be
4//! generic over it.
5
6use std::net::{IpAddr, SocketAddr};
7
8use alloy_rpc_types_admin::EthProtocolInfo;
9use enr::{secp256k1::SecretKey, Enr};
10use reth_eth_wire_types::{DisconnectReason, ProtocolVersion};
11use reth_network_peers::NodeRecord;
12use reth_network_types::{PeerKind, Reputation, ReputationChangeKind};
13
14use crate::{NetworkError, NetworkInfo, NetworkStatus, PeerId, PeerInfo, Peers, PeersInfo};
15
16/// A type that implements all network trait that does nothing.
17///
18/// Intended for testing purposes where network is not used.
19#[derive(Debug, Clone, Default)]
20#[non_exhaustive]
21pub struct NoopNetwork;
22
23impl NetworkInfo for NoopNetwork {
24    fn local_addr(&self) -> SocketAddr {
25        (IpAddr::from(std::net::Ipv4Addr::UNSPECIFIED), 30303).into()
26    }
27
28    async fn network_status(&self) -> Result<NetworkStatus, NetworkError> {
29        #[expect(deprecated)]
30        Ok(NetworkStatus {
31            client_version: "reth-test".to_string(),
32            protocol_version: ProtocolVersion::V5 as u64,
33            eth_protocol_info: EthProtocolInfo {
34                network: 1,
35                difficulty: None,
36                genesis: Default::default(),
37                config: Default::default(),
38                head: Default::default(),
39            },
40        })
41    }
42
43    fn chain_id(&self) -> u64 {
44        // mainnet
45        1
46    }
47
48    fn is_syncing(&self) -> bool {
49        false
50    }
51
52    fn is_initially_syncing(&self) -> bool {
53        false
54    }
55}
56
57impl PeersInfo for NoopNetwork {
58    fn num_connected_peers(&self) -> usize {
59        0
60    }
61
62    fn local_node_record(&self) -> NodeRecord {
63        NodeRecord::new(self.local_addr(), PeerId::random())
64    }
65
66    fn local_enr(&self) -> Enr<SecretKey> {
67        let sk = SecretKey::from_slice(&[0xcd; 32]).unwrap();
68        Enr::builder().build(&sk).unwrap()
69    }
70}
71
72impl Peers for NoopNetwork {
73    fn add_trusted_peer_id(&self, _peer: PeerId) {}
74
75    fn add_peer_kind(
76        &self,
77        _peer: PeerId,
78        _kind: PeerKind,
79        _tcp_addr: SocketAddr,
80        _udp_addr: Option<SocketAddr>,
81    ) {
82    }
83
84    async fn get_peers_by_kind(&self, _kind: PeerKind) -> Result<Vec<PeerInfo>, NetworkError> {
85        Ok(vec![])
86    }
87
88    async fn get_all_peers(&self) -> Result<Vec<PeerInfo>, NetworkError> {
89        Ok(vec![])
90    }
91
92    async fn get_peer_by_id(&self, _peer_id: PeerId) -> Result<Option<PeerInfo>, NetworkError> {
93        Ok(None)
94    }
95
96    async fn get_peers_by_id(&self, _peer_id: Vec<PeerId>) -> Result<Vec<PeerInfo>, NetworkError> {
97        Ok(vec![])
98    }
99
100    fn remove_peer(&self, _peer: PeerId, _kind: PeerKind) {}
101
102    fn disconnect_peer(&self, _peer: PeerId) {}
103
104    fn disconnect_peer_with_reason(&self, _peer: PeerId, _reason: DisconnectReason) {}
105
106    fn connect_peer_kind(
107        &self,
108        _peer: PeerId,
109        _kind: PeerKind,
110        _tcp_addr: SocketAddr,
111        _udp_addr: Option<SocketAddr>,
112    ) {
113    }
114
115    fn reputation_change(&self, _peer_id: PeerId, _kind: ReputationChangeKind) {}
116
117    async fn reputation_by_id(&self, _peer_id: PeerId) -> Result<Option<Reputation>, NetworkError> {
118        Ok(None)
119    }
120}