1mod ledger_read_actions;
2use ledger::{Account, AccountId};
3pub use ledger_read_actions::*;
4
5mod ledger_read_state;
6pub use ledger_read_state::*;
7use openmina_core::{
8 block::AppliedBlock,
9 requests::{RequestId, RpcId, RpcIdType},
10};
11use p2p::{channels::rpc::P2pRpcId, PeerId};
12use redux::Callback;
13
14mod ledger_read_reducer;
15
16use std::{collections::BTreeMap, sync::Arc};
17
18use mina_p2p_messages::v2;
19use serde::{Deserialize, Serialize};
20
21use crate::{
22 account::AccountPublicKey,
23 block_producer::vrf_evaluator::DelegatorTable,
24 ledger::LedgerAddress,
25 p2p::channels::rpc::StagedLedgerAuxAndPendingCoinbases,
26 rpc::{AccountQuery, RpcScanStateSummaryScanStateJob},
27};
28
29#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone, Copy)]
30pub enum LedgerReadKind {
31 DelegatorTable,
32 GetNumAccounts,
33 GetAccounts,
34 GetChildHashesAtAddr,
35 GetChildAccountsAtAddr,
36 GetStagedLedgerAuxAndPendingCoinbases,
37 ScanStateSummary,
38 AccountsForRpc,
39 GetLedgerStatus,
40 GetAccountDelegators,
41}
42
43#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
44pub enum LedgerReadRequest {
45 DelegatorTable(v2::LedgerHash, AccountPublicKey),
47 GetNumAccounts(v2::LedgerHash),
49 GetAccounts(v2::LedgerHash, Vec<AccountId>, Option<RpcId>),
50 GetChildHashesAtAddr(v2::LedgerHash, LedgerAddress),
51 GetChildAccountsAtAddr(v2::LedgerHash, LedgerAddress),
52 GetStagedLedgerAuxAndPendingCoinbases(LedgerReadStagedLedgerAuxAndPendingCoinbases),
53 ScanStateSummary(v2::MinaBaseStagedLedgerHashStableV1),
55 AccountsForRpc(RpcId, v2::LedgerHash, AccountQuery),
56 GetLedgerStatus(RpcId, v2::LedgerHash),
57 GetAccountDelegators(RpcId, v2::LedgerHash, AccountId),
58}
59
60#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
61pub struct LedgerStatus {
62 pub num_accounts: u64,
63 pub best_tip_staged_ledger_hash: v2::LedgerHash,
64}
65
66#[derive(Serialize, Deserialize, Debug, Clone)]
67pub enum LedgerReadResponse {
68 DelegatorTable(Option<DelegatorTable>),
70 GetNumAccounts(Option<(u64, v2::LedgerHash)>),
72 GetAccounts(Vec<Account>, Option<RpcId>),
73 GetChildHashesAtAddr(Option<(v2::LedgerHash, v2::LedgerHash)>),
74 GetChildAccountsAtAddr(Option<Vec<v2::MinaBaseAccountBinableArgStableV2>>),
75 GetStagedLedgerAuxAndPendingCoinbases(Option<Arc<StagedLedgerAuxAndPendingCoinbases>>),
76 ScanStateSummary(Result<Vec<Vec<RpcScanStateSummaryScanStateJob>>, String>),
78 AccountsForRpc(RpcId, Vec<Account>, AccountQuery),
79 GetLedgerStatus(RpcId, Option<LedgerStatus>),
80 GetAccountDelegators(RpcId, Option<Vec<Account>>),
81}
82
83#[derive(Serialize, Deserialize, Debug, Clone)]
84pub struct LedgerReadStagedLedgerAuxAndPendingCoinbases {
85 pub ledger_hash: v2::MinaBaseStagedLedgerHashStableV1,
86 pub protocol_states: BTreeMap<v2::StateHash, v2::MinaStateProtocolStateValueStableV2>,
87}
88
89impl LedgerReadRequest {
90 pub fn kind(&self) -> LedgerReadKind {
91 match self {
92 Self::DelegatorTable(..) => LedgerReadKind::DelegatorTable,
93 Self::GetNumAccounts(..) => LedgerReadKind::GetNumAccounts,
94 Self::GetAccounts(..) => LedgerReadKind::GetAccounts,
95 Self::GetChildAccountsAtAddr(..) => LedgerReadKind::GetChildAccountsAtAddr,
96 Self::GetChildHashesAtAddr(..) => LedgerReadKind::GetChildHashesAtAddr,
97 Self::GetStagedLedgerAuxAndPendingCoinbases(..) => {
98 LedgerReadKind::GetStagedLedgerAuxAndPendingCoinbases
99 }
100 Self::ScanStateSummary(..) => LedgerReadKind::ScanStateSummary,
101 Self::AccountsForRpc(..) => LedgerReadKind::AccountsForRpc,
102 Self::GetLedgerStatus(..) => LedgerReadKind::GetLedgerStatus,
103 Self::GetAccountDelegators(..) => LedgerReadKind::GetAccountDelegators,
104 }
105 }
106
107 pub fn cost(&self) -> usize {
108 let cost = match self {
109 Self::DelegatorTable(..) => 100,
110 Self::GetNumAccounts(..) => 1,
111 Self::GetAccounts(..) => 10, Self::GetChildAccountsAtAddr(_, addr) => {
113 let height_diff = super::LEDGER_DEPTH.saturating_sub(addr.length());
114 let max_accounts_count = 2_u32.pow(height_diff as u32);
115 (max_accounts_count / 4) as usize
116 }
117 Self::GetChildHashesAtAddr(..) => 1,
118 Self::GetStagedLedgerAuxAndPendingCoinbases(..) => 100,
119 Self::ScanStateSummary(..) => 100,
120 Self::AccountsForRpc(..) => 10,
122 Self::GetLedgerStatus(..) => 1,
123 Self::GetAccountDelegators(..) => 10,
124 };
125 cost.max(1)
126 }
127}
128
129impl LedgerReadResponse {
130 pub fn kind(&self) -> LedgerReadKind {
131 match self {
132 Self::DelegatorTable(..) => LedgerReadKind::DelegatorTable,
133 Self::GetNumAccounts(..) => LedgerReadKind::GetNumAccounts,
134 Self::GetAccounts(..) => LedgerReadKind::GetAccounts,
135 Self::GetChildAccountsAtAddr(..) => LedgerReadKind::GetChildAccountsAtAddr,
136 Self::GetChildHashesAtAddr(..) => LedgerReadKind::GetChildHashesAtAddr,
137 Self::GetStagedLedgerAuxAndPendingCoinbases(..) => {
138 LedgerReadKind::GetStagedLedgerAuxAndPendingCoinbases
139 }
140 Self::ScanStateSummary(..) => LedgerReadKind::ScanStateSummary,
141 Self::AccountsForRpc(..) => LedgerReadKind::AccountsForRpc,
142 Self::GetLedgerStatus(..) => LedgerReadKind::GetLedgerStatus,
143 Self::GetAccountDelegators(..) => LedgerReadKind::GetAccountDelegators,
144 }
145 }
146}
147
148impl PartialEq for LedgerReadStagedLedgerAuxAndPendingCoinbases {
149 fn eq(&self, other: &Self) -> bool {
150 self.ledger_hash == other.ledger_hash
151 }
152}
153
154#[derive(Serialize, Deserialize, Debug, Clone)]
155pub enum LedgerReadInitCallback {
156 RpcLedgerAccountsGetPending {
157 callback: Callback<RequestId<RpcIdType>>,
158 args: RequestId<RpcIdType>,
159 },
160 RpcScanStateSummaryGetPending {
161 callback: Callback<(RequestId<RpcIdType>, AppliedBlock)>,
162 args: (RequestId<RpcIdType>, AppliedBlock),
163 },
164 P2pChannelsResponsePending {
165 callback: Callback<(bool, P2pRpcId, PeerId)>,
166 args: (bool, P2pRpcId, PeerId),
167 },
168 RpcLedgerStatusGetPending {
169 callback: Callback<RequestId<RpcIdType>>,
170 args: RequestId<RpcIdType>,
171 },
172 RpcLedgerAccountDelegatorsGetPending {
173 callback: Callback<RequestId<RpcIdType>>,
174 args: RequestId<RpcIdType>,
175 },
176 None,
177}