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}