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 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}