node/stats/
mod.rs

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}