subspace_networking/
utils.rs

1//! Miscellaneous utilities for networking.
2
3pub(crate) mod key_with_distance;
4pub mod multihash;
5pub mod piece_provider;
6pub(crate) mod rate_limiter;
7
8use event_listener_primitives::Bag;
9use libp2p::multiaddr::Protocol;
10use libp2p::{Multiaddr, PeerId};
11use prometheus_client::metrics::gauge::Gauge;
12use prometheus_client::registry::Registry;
13use std::sync::Arc;
14use tracing::warn;
15
16const NETWORKING_REGISTRY_PREFIX: &str = "subspace";
17
18/// Metrics for Subspace networking
19pub struct SubspaceMetrics {
20    established_connections: Gauge,
21}
22
23impl SubspaceMetrics {
24    /// Constructor
25    pub fn new(registry: &mut Registry) -> Self {
26        let sub_registry = registry.sub_registry_with_prefix(NETWORKING_REGISTRY_PREFIX);
27
28        let gauge = Gauge::default();
29        sub_registry.register(
30            "established_connections",
31            "The current number of established connections",
32            gauge.clone(),
33        );
34
35        Self {
36            established_connections: gauge,
37        }
38    }
39
40    pub(crate) fn inc_established_connections(&self) {
41        self.established_connections.inc();
42    }
43
44    pub(crate) fn dec_established_connections(&self) {
45        self.established_connections.dec();
46    }
47}
48
49/// This test is successful only for global IP addresses and DNS names.
50pub(crate) fn is_global_address_or_dns(addr: &Multiaddr) -> bool {
51    match addr.iter().next() {
52        Some(Protocol::Ip4(ip)) => ip.is_global(),
53        Some(Protocol::Ip6(ip)) => ip.is_global(),
54        Some(Protocol::Dns(_)) | Some(Protocol::Dns4(_)) | Some(Protocol::Dns6(_)) => true,
55        _ => false,
56    }
57}
58
59/// Convenience alias for peer ID and its multiaddresses.
60pub type PeerAddress = (PeerId, Multiaddr);
61
62/// Helper function. Converts multiaddresses to a tuple with peer ID removing the peer Id suffix.
63/// It logs incorrect multiaddresses.
64pub fn strip_peer_id(addresses: Vec<Multiaddr>) -> Vec<PeerAddress> {
65    addresses
66        .into_iter()
67        .filter_map(|multiaddr| {
68            let mut modified_multiaddr = multiaddr.clone();
69
70            let peer_id: Option<PeerId> = modified_multiaddr.pop().and_then(|protocol| {
71                if let Protocol::P2p(peer_id) = protocol {
72                    Some(peer_id)
73                } else {
74                    None
75                }
76            });
77
78            if let Some(peer_id) = peer_id {
79                Some((peer_id, modified_multiaddr))
80            } else {
81                warn!(%multiaddr, "Incorrect multiaddr provided.");
82
83                None
84            }
85        })
86        .collect()
87}
88
89pub(crate) type HandlerFn<A> = Arc<dyn Fn(&A) + Send + Sync + 'static>;
90pub(crate) type Handler<A> = Bag<HandlerFn<A>, A>;