Skip to content

Commit 1268056

Browse files
committed
feat: record validation and end-to-end response time in signer metrics
1 parent bbde40f commit 1268056

File tree

4 files changed

+64
-0
lines changed

4 files changed

+64
-0
lines changed

stacks-signer/src/monitoring/mod.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#[cfg(feature = "monitoring_prom")]
1818
use ::prometheus::HistogramTimer;
19+
use blockstack_lib::chainstate::nakamoto::NakamotoBlock;
1920
#[cfg(feature = "monitoring_prom")]
2021
use slog::slog_error;
2122
#[cfg(not(feature = "monitoring_prom"))]
@@ -123,6 +124,33 @@ pub fn new_rpc_call_timer(_full_path: &str, _origin: &str) -> NoOpTimer {
123124
NoOpTimer
124125
}
125126

127+
/// Record the time taken to issue a block response for
128+
/// a given block. The block's timestamp is used to calculate the latency.
129+
///
130+
/// Call this right after broadcasting a BlockResponse
131+
#[allow(unused_variables)]
132+
pub fn record_block_response_latency(block: &NakamotoBlock) {
133+
#[cfg(feature = "monitoring_prom")]
134+
{
135+
use clarity::util::get_epoch_time_ms;
136+
137+
let diff =
138+
get_epoch_time_ms().saturating_sub(block.header.timestamp.saturating_mul(1000).into());
139+
prometheus::SIGNER_BLOCK_RESPONSE_LATENCIES_HISTOGRAM
140+
.with_label_values(&[])
141+
.observe(diff as f64 / 1000.0);
142+
}
143+
}
144+
145+
/// Record the time taken to validate a block, as reported by the Stacks node.
146+
#[allow(unused_variables)]
147+
pub fn record_block_validation_latency(latency_ms: u64) {
148+
#[cfg(feature = "monitoring_prom")]
149+
prometheus::SIGNER_BLOCK_VALIDATION_LATENCIES_HISTOGRAM
150+
.with_label_values(&[])
151+
.observe(latency_ms as f64 / 1000.0);
152+
}
153+
126154
/// Start serving monitoring metrics.
127155
/// This will only serve the metrics if the `monitoring_prom` feature is enabled.
128156
#[allow(unused_variables)]

stacks-signer/src/monitoring/prometheus.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ lazy_static! {
6262
"Time (seconds) measuring round-trip RPC call latency to the Stacks node"
6363
// Will use DEFAULT_BUCKETS = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0] by default
6464
), &["path"]).unwrap();
65+
66+
pub static ref SIGNER_BLOCK_VALIDATION_LATENCIES_HISTOGRAM: HistogramVec = register_histogram_vec!(histogram_opts!(
67+
"stacks_signer_block_validation_latencies_histogram",
68+
"Time (seconds) measuring block validation time reported by the Stacks node",
69+
vec![0.005, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0, 20.0]
70+
), &[]).unwrap();
71+
72+
pub static ref SIGNER_BLOCK_RESPONSE_LATENCIES_HISTOGRAM: HistogramVec = register_histogram_vec!(histogram_opts!(
73+
"stacks_signer_block_response_latencies_histogram",
74+
"Time (seconds) measuring end-to-end time to respond to a block",
75+
vec![0.005, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0, 20.0, 30.0, 60.0, 120.0]
76+
), &[]).unwrap();
6577
}
6678

6779
pub fn gather_metrics_string() -> String {

stacks-signer/src/v0/signer.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ impl Signer {
466466
{
467467
Ok(_) => {
468468
crate::monitoring::increment_block_responses_sent(accepted);
469+
crate::monitoring::record_block_response_latency(&block_proposal.block);
469470
}
470471
Err(e) => {
471472
warn!("{self}: Failed to send block response to stacker-db: {e:?}",);
@@ -688,6 +689,8 @@ impl Signer {
688689
.stackerdb
689690
.send_message_with_retry::<SignerMessage>(block_response.into());
690691

692+
crate::monitoring::record_block_response_latency(&block_info.block);
693+
691694
match res {
692695
Err(e) => warn!("{self}: Failed to send block rejection to stacker-db: {e:?}"),
693696
Ok(ack) if !ack.accepted => warn!(
@@ -792,6 +795,9 @@ impl Signer {
792795
info!("{self}: Received a block validate response: {block_validate_response:?}");
793796
let block_response = match block_validate_response {
794797
BlockValidateResponse::Ok(block_validate_ok) => {
798+
crate::monitoring::record_block_validation_latency(
799+
block_validate_ok.validation_time_ms,
800+
);
795801
self.handle_block_validate_ok(stacks_client, block_validate_ok)
796802
}
797803
BlockValidateResponse::Reject(block_validate_reject) => {
@@ -812,6 +818,12 @@ impl Signer {
812818
{
813819
Ok(_) => {
814820
crate::monitoring::increment_block_responses_sent(accepted);
821+
if let Ok(Some(block_info)) = self
822+
.signer_db
823+
.block_lookup(&block_validate_response.signer_signature_hash())
824+
{
825+
crate::monitoring::record_block_response_latency(&block_info.block);
826+
}
815827
}
816828
Err(e) => {
817829
warn!("{self}: Failed to send block rejection to stacker-db: {e:?}",);
@@ -876,6 +888,8 @@ impl Signer {
876888
.stackerdb
877889
.send_message_with_retry::<SignerMessage>(rejection.into());
878890

891+
crate::monitoring::record_block_response_latency(&block_info.block);
892+
879893
match res {
880894
Err(e) => warn!("{self}: Failed to send block rejection to stacker-db: {e:?}"),
881895
Ok(ack) if !ack.accepted => warn!(

stackslib/src/net/api/postblock_proposal.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,16 @@ pub enum BlockValidateResponse {
164164
Reject(BlockValidateReject),
165165
}
166166

167+
impl BlockValidateResponse {
168+
/// Get the signer signature hash from the block validate response
169+
pub fn signer_signature_hash(&self) -> Sha512Trunc256Sum {
170+
match self {
171+
BlockValidateResponse::Ok(ok) => ok.signer_signature_hash,
172+
BlockValidateResponse::Reject(reject) => reject.signer_signature_hash,
173+
}
174+
}
175+
}
176+
167177
impl From<Result<BlockValidateOk, BlockValidateReject>> for BlockValidateResponse {
168178
fn from(value: Result<BlockValidateOk, BlockValidateReject>) -> Self {
169179
match value {

0 commit comments

Comments
 (0)