node/rpc/
rpc_state.rs

1use std::collections::BTreeMap;
2
3use mina_p2p_messages::v2;
4use openmina_core::block::AppliedBlock;
5use serde::{Deserialize, Serialize};
6
7use super::{AccountQuery, RpcId, RpcRequest};
8
9#[derive(Serialize, Deserialize, Debug, Clone)]
10pub struct RpcRequestState {
11    pub req: RpcRequest,
12    pub status: RpcRequestStatus,
13    /// Extra data for the request.
14    pub data: RpcRequestExtraData,
15}
16
17#[derive(Serialize, Deserialize, Debug, Clone)]
18pub enum RpcRequestStatus {
19    Init {
20        time: redux::Timestamp,
21    },
22    Pending {
23        time: redux::Timestamp,
24    },
25    Error {
26        time: redux::Timestamp,
27        error: String,
28    },
29    Success {
30        time: redux::Timestamp,
31    },
32}
33
34#[derive(Serialize, Deserialize, Debug, Clone)]
35pub enum RpcRequestExtraData {
36    None,
37    FullBlockOpt(Option<AppliedBlock>),
38}
39
40impl RpcRequestStatus {
41    pub fn is_init(&self) -> bool {
42        matches!(self, Self::Init { .. })
43    }
44
45    pub fn is_pending(&self) -> bool {
46        matches!(self, Self::Pending { .. })
47    }
48
49    pub fn is_finished(&self) -> bool {
50        matches!(self, Self::Error { .. } | Self::Success { .. })
51    }
52}
53
54#[derive(Serialize, Deserialize, Debug, Clone, Default)]
55pub struct RpcState {
56    pub requests: BTreeMap<RpcId, RpcRequestState>,
57}
58
59impl RpcState {
60    pub fn new() -> Self {
61        Self::default()
62    }
63
64    pub fn scan_state_summary_rpc_ids(
65        &self,
66    ) -> impl Iterator<
67        Item = (
68            RpcId,
69            &v2::MinaBaseStagedLedgerHashStableV1,
70            &RpcRequestStatus,
71        ),
72    > {
73        self.requests
74            .iter()
75            .filter(|(_, req)| matches!(req.req, RpcRequest::ScanStateSummaryGet(_)))
76            .filter_map(|(id, req)| {
77                let block = match &req.data {
78                    RpcRequestExtraData::FullBlockOpt(block) => block.as_ref()?,
79                    _ => return None,
80                };
81                Some((*id, block.staged_ledger_hashes(), &req.status))
82            })
83    }
84
85    pub fn accounts_request_rpc_ids(
86        &self,
87    ) -> impl Iterator<Item = (RpcId, AccountQuery, &RpcRequestStatus)> + '_ {
88        self.requests.iter().filter_map(|(id, req)| {
89            if let RpcRequest::LedgerAccountsGet(account) = &req.req {
90                Some((*id, account.clone(), &req.status))
91            } else {
92                None
93            }
94        })
95    }
96}
97
98impl Default for RpcRequestExtraData {
99    fn default() -> Self {
100        Self::None
101    }
102}