p2p/network/kad/bootstrap/
p2p_network_kad_bootstrap_actions.rs

1use openmina_core::ActionEvent;
2use redux::EnablingCondition;
3use serde::{Deserialize, Serialize};
4
5use crate::{P2pAction, P2pNetworkKadAction, P2pNetworkKadLatestRequestPeers, P2pState, PeerId};
6
7use super::P2pNetworkKadBoostrapRequestState;
8
9#[derive(Clone, Debug, Serialize, Deserialize, ActionEvent)]
10#[action_event(fields(display(peer_id), debug(closest_peers), error))]
11pub enum P2pNetworkKadBootstrapAction {
12    /// Create `FIND_NODE` request.
13    CreateRequests,
14    AppendRequest {
15        request: Option<P2pNetworkKadBoostrapRequestState>,
16        peer_id: PeerId,
17    },
18    FinalizeRequests,
19    /// `FIND_NODE` request successful.
20    RequestDone {
21        peer_id: PeerId,
22        closest_peers: P2pNetworkKadLatestRequestPeers,
23    },
24    /// `FIND_NODE` request failed.
25    #[action_event(level = debug)]
26    RequestError {
27        peer_id: PeerId,
28        error: String,
29    },
30}
31
32impl EnablingCondition<P2pState> for P2pNetworkKadBootstrapAction {
33    fn is_enabled(&self, state: &P2pState, _time: redux::Timestamp) -> bool {
34        let state = state
35            .network
36            .scheduler
37            .discovery_state
38            .as_ref()
39            .and_then(|discovery_state| discovery_state.bootstrap_state());
40        match self {
41            P2pNetworkKadBootstrapAction::CreateRequests => {
42                state.is_some_and(|bootstrap_state| bootstrap_state.requests.len() < 3)
43            }
44            P2pNetworkKadBootstrapAction::AppendRequest { .. } => {
45                state.is_some_and(|bootstrap_state| bootstrap_state.peer_id_req_vec.len() < 3)
46            }
47            P2pNetworkKadBootstrapAction::FinalizeRequests => {
48                state.is_some_and(|bootstrap_state| bootstrap_state.peer_id_req_vec.len() <= 3)
49            }
50            P2pNetworkKadBootstrapAction::RequestDone { peer_id, .. }
51            | P2pNetworkKadBootstrapAction::RequestError { peer_id, .. } => {
52                state.is_some_and(|bootstrap_state| bootstrap_state.request(peer_id).is_some())
53            }
54        }
55    }
56}
57
58impl From<P2pNetworkKadBootstrapAction> for P2pAction {
59    fn from(value: P2pNetworkKadBootstrapAction) -> Self {
60        P2pNetworkKadAction::Bootstrap(value).into()
61    }
62}