reth_discv5/
metrics.rs

1//! Tracks peer discovery for [`Discv5`](crate::Discv5).
2use metrics::{Counter, Gauge};
3use reth_metrics::Metrics;
4
5use crate::NetworkStackId;
6
7/// Information tracked by [`Discv5`](crate::Discv5).
8#[derive(Debug, Default, Clone)]
9pub struct Discv5Metrics {
10    /// Frequency of networks advertised in discovered peers' node records.
11    pub discovered_peers_advertised_networks: AdvertisedChainMetrics,
12    /// Tracks discovered peers.
13    pub discovered_peers: DiscoveredPeersMetrics,
14}
15
16/// Tracks discovered peers.
17#[derive(Metrics, Clone)]
18#[metrics(scope = "discv5")]
19pub struct DiscoveredPeersMetrics {
20    ////////////////////////////////////////////////////////////////////////////////////////////////
21    // Kbuckets
22    ////////////////////////////////////////////////////////////////////////////////////////////////
23    /// Total peers currently in [`discv5::Discv5`]'s kbuckets.
24    kbucket_peers_raw_total: Gauge,
25    /// Total discovered peers that are inserted into [`discv5::Discv5`]'s kbuckets.
26    ///
27    /// This is a subset of the total established sessions, in which all peers advertise a udp
28    /// socket in their node record which is reachable from the local node. Only these peers make
29    /// it into [`discv5::Discv5`]'s kbuckets and will hence be included in queries.
30    ///
31    /// Note: the definition of 'discovered' is not exactly synonymous in `reth_discv4::Discv4`.
32    inserted_kbucket_peers_raw_total: Counter,
33
34    ////////////////////////////////////////////////////////////////////////////////////////////////
35    // Sessions
36    ////////////////////////////////////////////////////////////////////////////////////////////////
37    /// Total peers currently connected to [`discv5::Discv5`].
38    sessions_raw_total: Gauge,
39    /// Total number of sessions established by [`discv5::Discv5`].
40    established_sessions_raw_total: Counter,
41    /// Total number of sessions established by [`discv5::Discv5`], with peers that don't advertise
42    /// a socket which is reachable from the local node in their node record.
43    ///
44    /// These peers can't make it into [`discv5::Discv5`]'s kbuckets, and hence won't be part of
45    /// queries (neither shared with peers in NODES responses, nor queried for peers with FINDNODE
46    /// requests).
47    established_sessions_unreachable_enr_total: Counter,
48    /// Total number of sessions established by [`discv5::Discv5`], that pass configured
49    /// [`filter`](crate::filter) rules.
50    established_sessions_custom_filtered_total: Counter,
51    /// Total number of unverifiable ENRs discovered by [`discv5::Discv5`].
52    ///
53    /// These are peers that fail [`discv5::Discv5`] session establishment, because the UDP socket
54    /// they're making a connection from doesn't match the UDP socket advertised in their ENR.
55    /// These peers will be denied a session (and hence can't make it into kbuckets) until they
56    /// have update their ENR, to reflect their actual UDP socket.
57    unverifiable_enrs_raw_total: Counter,
58}
59
60impl DiscoveredPeersMetrics {
61    /// Sets current total number of peers in [`discv5::Discv5`]'s kbuckets.
62    pub fn set_total_kbucket_peers(&self, num: usize) {
63        self.kbucket_peers_raw_total.set(num as f64)
64    }
65
66    /// Increments the number of kbucket insertions in [`discv5::Discv5`].
67    pub fn increment_kbucket_insertions(&self, num: u64) {
68        self.inserted_kbucket_peers_raw_total.increment(num)
69    }
70
71    /// Sets current total number of peers connected to [`discv5::Discv5`].
72    pub fn set_total_sessions(&self, num: usize) {
73        self.sessions_raw_total.set(num as f64)
74    }
75
76    /// Increments number of sessions established by [`discv5::Discv5`].
77    pub fn increment_established_sessions_raw(&self, num: u64) {
78        self.established_sessions_raw_total.increment(num)
79    }
80
81    /// Increments number of sessions established by [`discv5::Discv5`], with peers that don't have
82    /// a reachable node record.
83    pub fn increment_established_sessions_unreachable_enr(&self, num: u64) {
84        self.established_sessions_unreachable_enr_total.increment(num)
85    }
86
87    /// Increments number of sessions established by [`discv5::Discv5`], that pass configured
88    /// [`filter`](crate::filter) rules.
89    pub fn increment_established_sessions_filtered(&self, num: u64) {
90        self.established_sessions_custom_filtered_total.increment(num)
91    }
92
93    /// Increments number of unverifiable ENRs discovered by [`discv5::Discv5`]. These are peers
94    /// that fail session establishment because their advertised UDP socket doesn't match the
95    /// socket they are making the connection from.
96    pub fn increment_unverifiable_enrs_raw_total(&self, num: u64) {
97        self.unverifiable_enrs_raw_total.increment(num)
98    }
99}
100
101/// Tracks frequency of networks that are advertised by discovered peers.
102///
103/// Peers advertise the chain they belong to as a kv-pair in their node record, using the network
104/// as key.
105#[derive(Metrics, Clone)]
106#[metrics(scope = "discv5")]
107pub struct AdvertisedChainMetrics {
108    /// Frequency of node records with a kv-pair with [`OPEL`](NetworkStackId::OPEL) as
109    /// key.
110    opel: Counter,
111
112    /// Frequency of node records with a kv-pair with [`OPSTACK`](NetworkStackId::OPSTACK) as
113    /// key.
114    opstack: Counter,
115
116    /// Frequency of node records with a kv-pair with [`ETH`](NetworkStackId::ETH) as key.
117    eth: Counter,
118
119    /// Frequency of node records with a kv-pair with [`ETH2`](NetworkStackId::ETH2) as key.
120    eth2: Counter,
121}
122
123impl AdvertisedChainMetrics {
124    /// Counts each recognised network stack type that is advertised on node record, once.
125    pub fn increment_once_by_network_type(&self, enr: &discv5::Enr) {
126        if enr.get_raw_rlp(NetworkStackId::OPEL).is_some() {
127            self.opel.increment(1u64)
128        }
129        if enr.get_raw_rlp(NetworkStackId::OPSTACK).is_some() {
130            self.opstack.increment(1u64)
131        }
132        if enr.get_raw_rlp(NetworkStackId::ETH).is_some() {
133            self.eth.increment(1u64)
134        }
135        if enr.get_raw_rlp(NetworkStackId::ETH2).is_some() {
136            self.eth2.increment(1u64)
137        }
138    }
139}