p2p/network/kad/
p2p_network_kad_actions.rs1use multiaddr::Multiaddr;
2use openmina_core::ActionEvent;
3use redux::EnablingCondition;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 kad::stream::P2pNetworkKademliaStreamAction, request::P2pNetworkKadRequestAction,
8 ConnectionAddr, P2pAction, P2pNetworkAction, P2pNetworkKadEntry, P2pState, PeerId, StreamId,
9};
10
11use super::{bootstrap::P2pNetworkKadBootstrapAction, CID};
12
13#[derive(Debug, Clone, Serialize, Deserialize, derive_more::From, ActionEvent)]
15pub enum P2pNetworkKadAction {
16 System(P2pNetworkKademliaAction),
17 Bootstrap(P2pNetworkKadBootstrapAction),
18 Request(P2pNetworkKadRequestAction),
19 Stream(P2pNetworkKademliaStreamAction),
20}
21
22impl EnablingCondition<P2pState> for P2pNetworkKadAction {
23 fn is_enabled(&self, state: &P2pState, time: redux::Timestamp) -> bool {
24 match self {
25 P2pNetworkKadAction::System(action) => action.is_enabled(state, time),
26 P2pNetworkKadAction::Bootstrap(action) => action.is_enabled(state, time),
27 P2pNetworkKadAction::Request(action) => action.is_enabled(state, time),
28 P2pNetworkKadAction::Stream(action) => action.is_enabled(state, time),
29 }
30 }
31}
32
33impl From<P2pNetworkKadAction> for P2pAction {
34 fn from(value: P2pNetworkKadAction) -> Self {
35 P2pNetworkAction::Kad(value).into()
36 }
37}
38
39#[derive(Debug, Clone, Serialize, Deserialize, ActionEvent)]
41#[action_event(fields(
42 display(addr),
43 display(peer_id),
44 stream_id,
45 debug(key),
46 debug(closest_peers),
47 debug(addrs)
48))]
49pub enum P2pNetworkKademliaAction {
50 AnswerFindNodeRequest {
54 addr: ConnectionAddr,
55 peer_id: PeerId,
56 stream_id: StreamId,
57 key: CID,
58 },
59 UpdateFindNodeRequest {
63 addr: ConnectionAddr,
64 peer_id: PeerId,
65 stream_id: StreamId,
66 closest_peers: Vec<P2pNetworkKadEntry>,
67 },
68 #[action_event(level = info)]
70 StartBootstrap { key: PeerId },
71 BootstrapFinished,
73
74 #[action_event(level = info)]
76 UpdateRoutingTable {
77 peer_id: PeerId,
78 addrs: Vec<Multiaddr>,
79 },
80}
81
82impl EnablingCondition<P2pState> for P2pNetworkKademliaAction {
83 fn is_enabled(&self, state: &P2pState, time: redux::Timestamp) -> bool {
84 let Some(discovery_state) = &state.network.scheduler.discovery_state else {
85 return false;
86 };
87 match self {
88 P2pNetworkKademliaAction::AnswerFindNodeRequest {
89 peer_id, stream_id, ..
90 } => discovery_state
91 .find_kad_stream_state(peer_id, stream_id)
92 .is_some(),
93 P2pNetworkKademliaAction::UpdateFindNodeRequest {
94 addr: _,
95 peer_id,
96 stream_id,
97 ..
98 } => {
99 discovery_state
100 .find_kad_stream_state(peer_id, stream_id)
101 .is_some()
102 && discovery_state.request(peer_id).is_some()
103 }
104 P2pNetworkKademliaAction::StartBootstrap { .. } => discovery_state
105 .status
106 .can_bootstrap(time, &state.config.timeouts),
107 P2pNetworkKademliaAction::BootstrapFinished { .. } => {
108 matches!(
110 discovery_state.status,
111 super::P2pNetworkKadStatus::Bootstrapping(_)
112 )
113 }
114 P2pNetworkKademliaAction::UpdateRoutingTable { .. } => true,
115 }
116 }
117}
118
119impl From<P2pNetworkKademliaAction> for P2pAction {
120 fn from(value: P2pNetworkKademliaAction) -> Self {
121 P2pAction::Network(P2pNetworkKadAction::System(value).into())
122 }
123}