1mod stats_actions;
43pub mod actions {
44 pub use super::stats_actions::*;
45}
46use actions::{ActionStats, ActionStatsForBlock, ActionStatsSnapshot};
47
48mod stats_sync;
49pub mod sync {
50 pub use super::stats_sync::*;
51}
52use sync::{SyncStats, SyncStatsSnapshot, SyncingLedger};
53
54mod stats_block_producer;
55pub mod block_producer {
56 pub use super::stats_block_producer::*;
57}
58use block_producer::BlockProducerStats;
59
60use mina_core::block::{AppliedBlock, ArcBlockWithHash};
61use redux::{ActionMeta, ActionWithMeta, Timestamp};
62
63use crate::{
64 transition_frontier::sync::{
65 ledger::{staged::PeerStagedLedgerPartsFetchError, SyncLedgerTargetKind},
66 TransitionFrontierSyncBlockState,
67 },
68 ActionKind,
69};
70
71pub type ActionKindWithMeta = ActionWithMeta<ActionKind>;
72
73pub struct Stats {
74 last_action: ActionKindWithMeta,
75 action_stats: ActionStats,
76 sync_stats: SyncStats,
77 block_producer_stats: BlockProducerStats,
78}
79
80impl Stats {
81 pub fn new() -> Self {
82 Self {
83 last_action: ActionMeta::ZERO.with_action(ActionKind::None),
84 action_stats: Default::default(),
85 sync_stats: Default::default(),
86 block_producer_stats: Default::default(),
87 }
88 }
89
90 pub fn block_producer(&mut self) -> &mut BlockProducerStats {
91 &mut self.block_producer_stats
92 }
93
94 pub fn new_sync_target(
95 &mut self,
96 time: Timestamp,
97 best_tip: &ArcBlockWithHash,
98 root_block: &ArcBlockWithHash,
99 ) -> &mut Self {
100 self.sync_stats.new_target(time, best_tip, root_block);
101 self
102 }
103
104 pub fn syncing_ledger(
105 &mut self,
106 kind: SyncLedgerTargetKind,
107 update: SyncingLedger,
108 ) -> &mut Self {
109 self.sync_stats.ledger(kind, update);
110 self
111 }
112
113 pub fn syncing_blocks_init(
114 &mut self,
115 states: &[TransitionFrontierSyncBlockState],
116 ) -> &mut Self {
117 self.sync_stats.blocks_init(states);
118 self
119 }
120
121 pub fn syncing_block_update(&mut self, state: &TransitionFrontierSyncBlockState) -> &mut Self {
122 self.sync_stats.block_update(state);
123 self
124 }
125
126 pub fn new_best_chain(&mut self, time: Timestamp, chain: &[AppliedBlock]) -> &mut Self {
127 let best_tip = chain.last().unwrap().block_with_hash();
128 self.action_stats
129 .new_best_tip(time, best_tip.height(), best_tip.hash().clone());
130 self.sync_stats.synced(time);
131 self.block_producer_stats.new_best_chain(time, chain);
132 self
133 }
134
135 pub fn new_action(&mut self, kind: ActionKind, meta: ActionMeta) -> &mut Self {
136 let action = meta.with_action(kind);
137 self.action_stats.add(&action, &self.last_action);
138 self.last_action = action;
139 self
140 }
141
142 pub fn collect_action_stats_since_start(&self) -> ActionStatsSnapshot {
143 self.action_stats.since_start.clone()
144 }
145
146 pub fn collect_action_stats_for_block_with_id(
147 &self,
148 id: Option<u64>,
149 ) -> Option<ActionStatsForBlock> {
150 self.action_stats.collect_stats_for_block_with_id(id)
151 }
152
153 pub fn collect_sync_stats(&self, limit: Option<usize>) -> Vec<SyncStatsSnapshot> {
154 self.sync_stats.collect_stats(limit)
155 }
156
157 pub fn get_sync_time(&self) -> Option<Timestamp> {
158 self.sync_stats
159 .collect_stats(Some(1))
160 .first()
161 .and_then(|stats| stats.synced)
162 }
163
164 pub fn staging_ledger_fetch_failure(
165 &mut self,
166 error: &PeerStagedLedgerPartsFetchError,
167 time: Timestamp,
168 ) {
169 self.sync_stats
170 .staging_ledger_fetch_failure(format!("{error:?}"), time)
171 }
172}
173
174impl Default for Stats {
175 fn default() -> Self {
176 Self::new()
177 }
178}