diff --git a/crates/hotshot/src/tasks/task_state.rs b/crates/hotshot/src/tasks/task_state.rs index 1df18f9b5e..ba24fc4bd3 100644 --- a/crates/hotshot/src/tasks/task_state.rs +++ b/crates/hotshot/src/tasks/task_state.rs @@ -222,6 +222,9 @@ impl, V: Versions> CreateTaskState async fn create_from(handle: &SystemContextHandle) -> Self { let consensus = handle.hotshot.consensus(); + // Clone the consensus metrics + let consensus_metrics = Arc::clone(&consensus.read().await.metrics); + Self { public_key: handle.public_key().clone(), private_key: handle.private_key().clone(), @@ -237,6 +240,7 @@ impl, V: Versions> CreateTaskState storage: Arc::clone(&handle.storage), upgrade_lock: handle.hotshot.upgrade_lock.clone(), epoch_height: handle.hotshot.config.epoch_height, + consensus_metrics, } } } diff --git a/crates/task-impls/src/quorum_vote/mod.rs b/crates/task-impls/src/quorum_vote/mod.rs index 0567329788..a89e27a84c 100644 --- a/crates/task-impls/src/quorum_vote/mod.rs +++ b/crates/task-impls/src/quorum_vote/mod.rs @@ -16,7 +16,7 @@ use hotshot_task::{ task::TaskState, }; use hotshot_types::{ - consensus::OuterConsensus, + consensus::{ConsensusMetricsValue, OuterConsensus}, data::{Leaf2, QuorumProposal2}, drb::DrbResult, event::Event, @@ -80,6 +80,8 @@ pub struct VoteDependencyHandle, V pub receiver: InactiveReceiver>>, /// Lock for a decided upgrade pub upgrade_lock: UpgradeLock, + /// The consensus metrics + pub consensus_metrics: Arc, /// The node's id pub id: u64, /// Number of blocks in an epoch, zero means there are no epochs @@ -282,6 +284,9 @@ pub struct QuorumVoteTaskState, V: /// The node's id pub id: u64, + /// The consensus metrics + pub consensus_metrics: Arc, + /// Reference to the storage. pub storage: Arc>, @@ -386,6 +391,7 @@ impl, V: Versions> QuorumVoteTaskS upgrade_lock: self.upgrade_lock.clone(), id: self.id, epoch_height: self.epoch_height, + consensus_metrics: Arc::clone(&self.consensus_metrics), }, ); self.vote_dependencies @@ -410,6 +416,15 @@ impl, V: Versions> QuorumVoteTaskS } } + // Update the metric for the last voted view + if let Ok(last_voted_view_usize) = usize::try_from(*new_view) { + self.consensus_metrics + .last_voted_view + .set(last_voted_view_usize); + } else { + tracing::warn!("Failed to convert last voted view to a usize: {}", new_view); + } + self.latest_voted_view = new_view; return true; diff --git a/crates/testing/tests/tests_1/vote_dependency_handle.rs b/crates/testing/tests/tests_1/vote_dependency_handle.rs index 9de2531361..1b12e0b0f0 100644 --- a/crates/testing/tests/tests_1/vote_dependency_handle.rs +++ b/crates/testing/tests/tests_1/vote_dependency_handle.rs @@ -88,6 +88,7 @@ async fn test_vote_dependency_handle() { public_key: handle.public_key(), private_key: handle.private_key().clone(), consensus: OuterConsensus::new(consensus.clone()), + consensus_metrics: Arc::clone(&consensus.read().await.metrics), instance_state: handle.hotshot.instance_state(), quorum_membership: (*handle.hotshot.memberships).clone().into(), storage: Arc::clone(&handle.storage()), diff --git a/crates/types/src/consensus.rs b/crates/types/src/consensus.rs index 81250b7b5b..2d2e814e9f 100644 --- a/crates/types/src/consensus.rs +++ b/crates/types/src/consensus.rs @@ -331,6 +331,8 @@ pub struct ConsensusMetricsValue { pub last_synced_block_height: Box, /// The number of last decided view pub last_decided_view: Box, + /// The number of the last voted view + pub last_voted_view: Box, /// Number of timestamp for the last decided time pub last_decided_time: Box, /// The current view @@ -365,6 +367,7 @@ impl ConsensusMetricsValue { last_synced_block_height: metrics .create_gauge(String::from("last_synced_block_height"), None), last_decided_view: metrics.create_gauge(String::from("last_decided_view"), None), + last_voted_view: metrics.create_gauge(String::from("last_voted_view"), None), last_decided_time: metrics.create_gauge(String::from("last_decided_time"), None), current_view: metrics.create_gauge(String::from("current_view"), None), number_of_views_since_last_decide: metrics