p2p/network/kad/bootstrap/
p2p_network_kad_bootstrap_state.rs

1use std::{
2    collections::{BTreeMap, BTreeSet},
3    net::SocketAddr,
4};
5
6use malloc_size_of_derive::MallocSizeOf;
7use redux::Timestamp;
8use serde::{Deserialize, Serialize};
9
10use crate::{
11    connection::outgoing::P2pConnectionOutgoingInitOpts, P2pNetworkKadKey, P2pNetworkKadKeyError,
12    P2pNetworkKadLatestRequestPeers, PeerId,
13};
14
15#[derive(Clone, Debug, Serialize, Deserialize, MallocSizeOf)]
16pub struct P2pNetworkKadBootstrapState {
17    /// Key that is used to request closest peers. Usually self peer_id.
18    pub key: PeerId,
19    /// Kademlia key, `sha265(self.key)`.
20    pub kademlia_key: P2pNetworkKadKey,
21    /// Peers that already been contacted (successfully or not) for FIND_NODE.
22    #[with_malloc_size_of_func = "measurement::peer_id_map"]
23    pub processed_peers: BTreeSet<PeerId>,
24    /// Ongoing FIND_NODE requests.
25    ///
26    /// TODO: replace with something more lightweight.
27    #[with_malloc_size_of_func = "measurement::requests_map"]
28    pub requests: BTreeMap<PeerId, P2pNetworkKadBoostrapRequestState>,
29    /// Number of successful requests
30    pub successful_requests: usize,
31    /// Bootstrap requests statistics.
32    pub stats: P2pNetworkKadBootstrapStats,
33    /// Constructing request
34    pub peer_id_req_vec: Vec<(PeerId, P2pNetworkKadBoostrapRequestState)>,
35    /// Number of requests to construct
36    pub requests_number: usize,
37}
38
39impl P2pNetworkKadBootstrapState {
40    pub fn new(key: PeerId) -> Result<Self, P2pNetworkKadKeyError> {
41        Ok(P2pNetworkKadBootstrapState {
42            key,
43            kademlia_key: key.try_into()?,
44            processed_peers: BTreeSet::new(),
45            requests: BTreeMap::new(),
46            successful_requests: 0,
47            stats: Default::default(),
48            peer_id_req_vec: vec![],
49            requests_number: 0,
50        })
51    }
52
53    pub fn request(&self, peer_id: &PeerId) -> Option<&P2pNetworkKadBoostrapRequestState> {
54        self.requests.get(peer_id)
55    }
56}
57
58#[derive(Clone, Debug, Serialize, Deserialize, MallocSizeOf)]
59pub struct P2pNetworkKadBoostrapRequestState {
60    /// Address that is used for the current connection.
61    // TODO: generalize to DNS addrs
62    #[ignore_malloc_size_of = "doesn't allocate"]
63    pub addr: SocketAddr,
64    /// When connection to the peer was initiated.
65    #[ignore_malloc_size_of = "doesn't allocate"]
66    pub time: Timestamp,
67    /// Addresses yet to be used, if current connection will fail.
68    // TODO: use Multiaddr
69    #[with_malloc_size_of_func = "measurement::socket_addr_vec"]
70    pub addrs_to_use: Vec<SocketAddr>,
71}
72
73#[derive(Clone, Debug, Serialize, Deserialize, Default, MallocSizeOf)]
74pub struct P2pNetworkKadBootstrapStats {
75    pub requests: Vec<P2pNetworkKadBootstrapRequestStat>,
76}
77
78#[derive(Clone, Debug, Serialize, Deserialize, MallocSizeOf)]
79#[serde(tag = "type")]
80pub enum P2pNetworkKadBootstrapRequestStat {
81    Ongoing(P2pNetworkKadBootstrapOngoingRequest),
82    Successful(P2pNetworkKadBootstrapSuccessfulRequest),
83    Failed(P2pNetworkKadBootstrapFailedRequest),
84}
85
86#[derive(Clone, Debug, Serialize, Deserialize, MallocSizeOf)]
87pub struct P2pNetworkKadBootstrapOngoingRequest {
88    pub peer_id: PeerId,
89    pub address: P2pConnectionOutgoingInitOpts,
90    #[ignore_malloc_size_of = "doesn't allocate"]
91    pub start: Timestamp,
92}
93
94#[derive(Clone, Debug, Serialize, Deserialize, MallocSizeOf)]
95pub struct P2pNetworkKadBootstrapSuccessfulRequest {
96    pub peer_id: PeerId,
97    pub address: P2pConnectionOutgoingInitOpts,
98    #[ignore_malloc_size_of = "doesn't allocate"]
99    pub start: Timestamp,
100    #[ignore_malloc_size_of = "doesn't allocate"]
101    pub finish: Timestamp,
102    pub closest_peers: P2pNetworkKadLatestRequestPeers,
103}
104
105#[derive(Clone, Debug, Serialize, Deserialize, MallocSizeOf)]
106pub struct P2pNetworkKadBootstrapFailedRequest {
107    pub peer_id: PeerId,
108    pub address: P2pConnectionOutgoingInitOpts,
109    #[ignore_malloc_size_of = "doesn't allocate"]
110    pub start: Timestamp,
111    #[ignore_malloc_size_of = "doesn't allocate"]
112    pub finish: Timestamp,
113    pub error: String,
114}
115
116mod measurement {
117    use std::{
118        collections::{BTreeMap, BTreeSet},
119        mem,
120        net::SocketAddr,
121    };
122
123    use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
124
125    use super::P2pNetworkKadBoostrapRequestState;
126    use crate::PeerId;
127
128    pub fn socket_addr_vec(val: &Vec<SocketAddr>, _ops: &mut MallocSizeOfOps) -> usize {
129        val.capacity() * mem::size_of::<SocketAddr>()
130    }
131
132    pub fn peer_id_map(val: &BTreeSet<PeerId>, _ops: &mut MallocSizeOfOps) -> usize {
133        val.len() * mem::size_of::<PeerId>()
134    }
135
136    pub fn requests_map(
137        val: &BTreeMap<PeerId, P2pNetworkKadBoostrapRequestState>,
138        ops: &mut MallocSizeOfOps,
139    ) -> usize {
140        val.iter()
141            .map(|(k, v)| mem::size_of_val(k) + mem::size_of_val(v) + v.size_of(ops))
142            .sum()
143    }
144}