node/
action.rs

1use p2p::P2pEffectfulAction;
2use serde::{Deserialize, Serialize};
3
4pub type ActionWithMeta = redux::ActionWithMeta<Action>;
5pub type ActionWithMetaRef<'a> = redux::ActionWithMeta<&'a Action>;
6
7pub use crate::{
8    block_producer::BlockProducerAction,
9    block_producer_effectful::BlockProducerEffectfulAction,
10    event_source::EventSourceAction,
11    external_snark_worker::ExternalSnarkWorkerAction,
12    ledger::LedgerAction,
13    p2p::P2pAction,
14    rpc::RpcAction,
15    snark::SnarkAction,
16    snark_pool::{SnarkPoolAction, SnarkPoolEffectfulAction},
17    transaction_pool::TransactionPoolAction,
18    transition_frontier::TransitionFrontierAction,
19    watched_accounts::WatchedAccountsAction,
20};
21use crate::{
22    external_snark_worker_effectful::ExternalSnarkWorkerEffectfulAction,
23    ledger_effectful::LedgerEffectfulAction, p2p::callbacks::P2pCallbacksAction,
24    rpc_effectful::RpcEffectfulAction, transaction_pool::TransactionPoolEffectfulAction,
25};
26
27pub trait ActionKindGet {
28    fn kind(&self) -> crate::ActionKind;
29}
30
31// Static limit for size of [`Action`] set to 512 bytes, if [`Action`] size is bigger code won't compile
32// compile error: "attempt to compute `0_usize - 1_usize`, which would overflow"
33static_assertions::const_assert!(std::mem::size_of::<Action>() <= 512);
34
35#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)]
36pub enum Action {
37    CheckTimeouts(CheckTimeoutsAction),
38    EventSource(EventSourceAction),
39
40    P2p(P2pAction),
41    P2pEffectful(P2pEffectfulAction),
42    P2pCallbacks(P2pCallbacksAction),
43
44    Ledger(LedgerAction),
45    LedgerEffects(LedgerEffectfulAction),
46    Snark(SnarkAction),
47    TransitionFrontier(TransitionFrontierAction),
48    SnarkPool(SnarkPoolAction),
49    SnarkPoolEffect(SnarkPoolEffectfulAction),
50    TransactionPool(TransactionPoolAction),
51    TransactionPoolEffect(TransactionPoolEffectfulAction),
52    ExternalSnarkWorker(ExternalSnarkWorkerAction),
53    ExternalSnarkWorkerEffects(ExternalSnarkWorkerEffectfulAction),
54    BlockProducer(BlockProducerAction),
55    BlockProducerEffectful(BlockProducerEffectfulAction),
56    Rpc(RpcAction),
57    RpcEffectful(RpcEffectfulAction),
58
59    WatchedAccounts(WatchedAccountsAction),
60}
61
62impl Action {
63    pub fn kind(&self) -> crate::ActionKind {
64        ActionKindGet::kind(self)
65    }
66}
67
68/// Checks for timeouts and dispatches other time dependant actions.
69///
70/// Gets called repeatedly, so it's effects should be as light as possible.
71#[derive(Serialize, Deserialize, Debug, Clone)]
72pub struct CheckTimeoutsAction {}
73
74impl redux::EnablingCondition<crate::State> for CheckTimeoutsAction {}
75
76impl redux::EnablingCondition<crate::State> for Action {
77    fn is_enabled(&self, state: &crate::State, time: redux::Timestamp) -> bool {
78        match self {
79            Action::CheckTimeouts(a) => a.is_enabled(state, time),
80            Action::EventSource(a) => a.is_enabled(state, time),
81            Action::P2p(a) => match a {
82                P2pAction::Initialization(a) => a.is_enabled(state, time),
83                other => state
84                    .p2p
85                    .ready()
86                    .is_some_and(|p2p| other.is_enabled(p2p, time)),
87            },
88            Action::P2pEffectful(a) => state
89                .p2p
90                .ready()
91                .is_some_and(|state| a.is_enabled(state, time)),
92            Action::Ledger(a) => a.is_enabled(state, time),
93            Action::LedgerEffects(a) => a.is_enabled(state, time),
94            Action::Snark(a) => a.is_enabled(&state.snark, time),
95            Action::TransitionFrontier(a) => a.is_enabled(state, time),
96            Action::SnarkPool(a) => a.is_enabled(state, time),
97            Action::SnarkPoolEffect(a) => a.is_enabled(state, time),
98            Action::ExternalSnarkWorker(a) => a.is_enabled(state, time),
99            Action::ExternalSnarkWorkerEffects(a) => a.is_enabled(state, time),
100            Action::BlockProducer(a) => a.is_enabled(state, time),
101            Action::BlockProducerEffectful(a) => a.is_enabled(state, time),
102            Action::Rpc(a) => a.is_enabled(state, time),
103            Action::WatchedAccounts(a) => a.is_enabled(state, time),
104            Action::TransactionPool(a) => a.is_enabled(state, time),
105            Action::TransactionPoolEffect(a) => a.is_enabled(state, time),
106            Action::P2pCallbacks(a) => a.is_enabled(state, time),
107            Action::RpcEffectful(a) => a.is_enabled(state, time),
108        }
109    }
110}
111
112impl From<redux::AnyAction> for Action {
113    fn from(action: redux::AnyAction) -> Self {
114        match action.0.downcast() {
115            Ok(action) => *action,
116            Err(action) => Self::P2p(*action.downcast().expect("Downcast failed")),
117        }
118    }
119}