Skip to main content

hashgraph_like_consensus/
service_stats.rs

1//! Scope-level statistics for monitoring consensus activity.
2
3use crate::{
4    events::ConsensusEventBus, scope::ConsensusScope, service::ConsensusService,
5    session::ConsensusState, storage::ConsensusStorage,
6};
7
8/// Aggregate counters for all sessions within a single scope.
9#[derive(Debug, Clone)]
10pub struct ConsensusStats {
11    /// Total number of proposals in this scope.
12    pub total_sessions: usize,
13    /// How many proposals are still accepting votes.
14    pub active_sessions: usize,
15    /// How many proposals failed to reach consensus (timeout with insufficient votes).
16    pub failed_sessions: usize,
17    /// How many proposals successfully reached consensus.
18    pub consensus_reached: usize,
19}
20
21impl<Scope, S, E> ConsensusService<Scope, S, E>
22where
23    Scope: ConsensusScope,
24    S: ConsensusStorage<Scope>,
25    E: ConsensusEventBus<Scope>,
26{
27    /// Get statistics about proposals in a scope.
28    ///
29    /// Returns counts of total, active, failed, and finalized proposals.
30    /// Useful for monitoring and dashboards.
31    pub async fn get_scope_stats(&self, scope: &Scope) -> ConsensusStats {
32        self.list_scope_sessions(scope)
33            .await
34            .map(|scope_sessions| {
35                let total_sessions = scope_sessions.len();
36                let active_sessions = scope_sessions.iter().filter(|s| s.is_active()).count();
37                let consensus_reached = scope_sessions
38                    .iter()
39                    .filter(|s| matches!(s.state, ConsensusState::ConsensusReached(_)))
40                    .count();
41                let failed_sessions = scope_sessions
42                    .iter()
43                    .filter(|s| matches!(s.state, ConsensusState::Failed))
44                    .count();
45
46                ConsensusStats {
47                    total_sessions,
48                    active_sessions,
49                    consensus_reached,
50                    failed_sessions,
51                }
52            })
53            .unwrap_or(ConsensusStats {
54                total_sessions: 0,
55                active_sessions: 0,
56                consensus_reached: 0,
57                failed_sessions: 0,
58            })
59    }
60}