mina_node/rpc/
rpc_state.rs

1use std::collections::BTreeMap;
2
3use mina_core::block::AppliedBlock;
4use mina_p2p_messages::v2;
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, Default)]
35pub enum RpcRequestExtraData {
36    #[default]
37    None,
38    FullBlockOpt(Option<AppliedBlock>),
39}
40
41impl RpcRequestStatus {
42    pub fn is_init(&self) -> bool {
43        matches!(self, Self::Init { .. })
44    }
45
46    pub fn is_pending(&self) -> bool {
47        matches!(self, Self::Pending { .. })
48    }
49
50    pub fn is_finished(&self) -> bool {
51        matches!(self, Self::Error { .. } | Self::Success { .. })
52    }
53}
54
55#[derive(Serialize, Deserialize, Debug, Clone, Default)]
56pub struct RpcState {
57    pub requests: BTreeMap<RpcId, RpcRequestState>,
58}
59
60impl RpcState {
61    pub fn new() -> Self {
62        Self::default()
63    }
64
65    pub fn scan_state_summary_rpc_ids(
66        &self,
67    ) -> impl Iterator<
68        Item = (
69            RpcId,
70            &v2::MinaBaseStagedLedgerHashStableV1,
71            &RpcRequestStatus,
72        ),
73    > {
74        self.requests
75            .iter()
76            .filter(|(_, req)| matches!(req.req, RpcRequest::ScanStateSummaryGet(_)))
77            .filter_map(|(id, req)| {
78                let block = match &req.data {
79                    RpcRequestExtraData::FullBlockOpt(block) => block.as_ref()?,
80                    _ => return None,
81                };
82                Some((*id, block.staged_ledger_hashes(), &req.status))
83            })
84    }
85
86    pub fn accounts_request_rpc_ids(
87        &self,
88    ) -> impl Iterator<Item = (RpcId, AccountQuery, &RpcRequestStatus)> + '_ {
89        self.requests.iter().filter_map(|(id, req)| {
90            if let RpcRequest::LedgerAccountsGet(account) = &req.req {
91                Some((*id, account.clone(), &req.status))
92            } else {
93                None
94            }
95        })
96    }
97}