1mod stats_actions;
2pub mod actions {
3 pub use super::stats_actions::*;
4}
5use actions::{ActionStats, ActionStatsForBlock, ActionStatsSnapshot};
6
7mod stats_sync;
8pub mod sync {
9 pub use super::stats_sync::*;
10}
11use sync::{SyncStats, SyncStatsSnapshot, SyncingLedger};
12
13mod stats_block_producer;
14pub mod block_producer {
15 pub use super::stats_block_producer::*;
16}
17use block_producer::BlockProducerStats;
18
19use openmina_core::block::{AppliedBlock, ArcBlockWithHash};
20use redux::{ActionMeta, ActionWithMeta, Timestamp};
21
22use crate::{
23 transition_frontier::sync::{
24 ledger::{staged::PeerStagedLedgerPartsFetchError, SyncLedgerTargetKind},
25 TransitionFrontierSyncBlockState,
26 },
27 ActionKind,
28};
29
30pub type ActionKindWithMeta = ActionWithMeta<ActionKind>;
31
32pub struct Stats {
33 last_action: ActionKindWithMeta,
34 action_stats: ActionStats,
35 sync_stats: SyncStats,
36 block_producer_stats: BlockProducerStats,
37}
38
39impl Stats {
40 pub fn new() -> Self {
41 Self {
42 last_action: ActionMeta::ZERO.with_action(ActionKind::None),
43 action_stats: Default::default(),
44 sync_stats: Default::default(),
45 block_producer_stats: Default::default(),
46 }
47 }
48
49 pub fn block_producer(&mut self) -> &mut BlockProducerStats {
50 &mut self.block_producer_stats
51 }
52
53 pub fn new_sync_target(
54 &mut self,
55 time: Timestamp,
56 best_tip: &ArcBlockWithHash,
57 root_block: &ArcBlockWithHash,
58 ) -> &mut Self {
59 self.sync_stats.new_target(time, best_tip, root_block);
60 self
61 }
62
63 pub fn syncing_ledger(
64 &mut self,
65 kind: SyncLedgerTargetKind,
66 update: SyncingLedger,
67 ) -> &mut Self {
68 self.sync_stats.ledger(kind, update);
69 self
70 }
71
72 pub fn syncing_blocks_init(
73 &mut self,
74 states: &[TransitionFrontierSyncBlockState],
75 ) -> &mut Self {
76 self.sync_stats.blocks_init(states);
77 self
78 }
79
80 pub fn syncing_block_update(&mut self, state: &TransitionFrontierSyncBlockState) -> &mut Self {
81 self.sync_stats.block_update(state);
82 self
83 }
84
85 pub fn new_best_chain(&mut self, time: Timestamp, chain: &[AppliedBlock]) -> &mut Self {
86 let best_tip = chain.last().unwrap().block_with_hash();
87 self.action_stats
88 .new_best_tip(time, best_tip.height(), best_tip.hash().clone());
89 self.sync_stats.synced(time);
90 self.block_producer_stats.new_best_chain(time, chain);
91 self
92 }
93
94 pub fn new_action(&mut self, kind: ActionKind, meta: ActionMeta) -> &mut Self {
95 let action = meta.with_action(kind);
96 self.action_stats.add(&action, &self.last_action);
97 self.last_action = action;
98 self
99 }
100
101 pub fn collect_action_stats_since_start(&self) -> ActionStatsSnapshot {
102 self.action_stats.since_start.clone()
103 }
104
105 pub fn collect_action_stats_for_block_with_id(
106 &self,
107 id: Option<u64>,
108 ) -> Option<ActionStatsForBlock> {
109 self.action_stats.collect_stats_for_block_with_id(id)
110 }
111
112 pub fn collect_sync_stats(&self, limit: Option<usize>) -> Vec<SyncStatsSnapshot> {
113 self.sync_stats.collect_stats(limit)
114 }
115
116 pub fn get_sync_time(&self) -> Option<Timestamp> {
117 self.sync_stats
118 .collect_stats(Some(1))
119 .first()
120 .and_then(|stats| stats.synced)
121 }
122
123 pub fn staging_ledger_fetch_failure(
124 &mut self,
125 error: &PeerStagedLedgerPartsFetchError,
126 time: Timestamp,
127 ) {
128 self.sync_stats
129 .staging_ledger_fetch_failure(format!("{error:?}"), time)
130 }
131}
132
133impl Default for Stats {
134 fn default() -> Self {
135 Self::new()
136 }
137}