p2p/disconnection/
p2p_disconnection_actions.rs1use std::time::Duration;
2
3use openmina_core::ActionEvent;
4use serde::{Deserialize, Serialize};
5
6use super::P2pDisconnectionReason;
7use crate::{P2pPeerStatus, P2pState, PeerId};
8
9pub type P2pDisconnectionActionWithMetaRef<'a> = redux::ActionWithMeta<&'a P2pDisconnectionAction>;
10
11const RANDOM_DISCONNECTION_TRY_FREQUENCY: Duration = Duration::from_secs(10);
12
13#[derive(Serialize, Deserialize, Debug, Clone, ActionEvent)]
14#[action_event(level = debug)]
15pub enum P2pDisconnectionAction {
16 RandomTry,
17 #[action_event(fields(display(peer_id), display(reason)), level = info)]
19 Init {
20 peer_id: PeerId,
21 reason: P2pDisconnectionReason,
22 },
23 #[action_event(fields(display(peer_id)), level = info)]
25 PeerClosed {
26 peer_id: PeerId,
27 },
28 #[action_event(fields(display(peer_id)), level = info)]
29 FailedCleanup {
30 peer_id: PeerId,
31 },
32 #[action_event(fields(display(peer_id)), level = debug)]
34 Finish {
35 peer_id: PeerId,
36 },
37}
38
39impl redux::EnablingCondition<P2pState> for P2pDisconnectionAction {
40 fn is_enabled(&self, state: &P2pState, time: redux::Timestamp) -> bool {
41 match self {
42 P2pDisconnectionAction::RandomTry => time
43 .checked_sub(state.last_random_disconnection_try)
44 .is_some_and(|dur| dur >= RANDOM_DISCONNECTION_TRY_FREQUENCY),
45 P2pDisconnectionAction::Init { peer_id, .. } => {
46 state.peers.get(peer_id).is_some_and(|peer| {
47 !peer.status.is_disconnected_or_disconnecting() && !peer.status.is_error()
48 })
49 }
50 P2pDisconnectionAction::Finish { peer_id } => {
51 state.peers.get(peer_id).is_some_and(|peer| {
52 !matches!(peer.status, P2pPeerStatus::Disconnected { .. })
53 && !peer.status.is_error()
54 })
55 }
56 P2pDisconnectionAction::PeerClosed { peer_id, .. } => {
57 state.peers.get(peer_id).is_some_and(|peer| {
58 !peer.status.is_disconnected_or_disconnecting() && !peer.status.is_error()
59 })
60 }
61 P2pDisconnectionAction::FailedCleanup { peer_id } => state
62 .peers
63 .get(peer_id)
64 .is_some_and(|peer| !peer.is_libp2p() && peer.status.is_error()),
65 }
66 }
67}