Skip to content

Commit 224e9cb

Browse files
committed
feat(slasher): add slasher metrics
1 parent 1db6dfa commit 224e9cb

4 files changed

Lines changed: 194 additions & 10 deletions

File tree

scripts/gen-dashboard.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2763,6 +2763,70 @@ def validator() -> RowPanel:
27632763
return create_row("Validator", metrics)
27642764

27652765

2766+
def slasher() -> RowPanel:
2767+
metrics = [
2768+
timeseries_panel(
2769+
targets=[
2770+
target(
2771+
'tycho_slasher_blocks_batch_size{instance=~"$instance"} and \
2772+
on(instance, job) tycho_slasher_enabled{instance=~"$instance"} == 1',
2773+
legend_format="{{instance}}",
2774+
)
2775+
],
2776+
title="Slasher blocks batch size",
2777+
unit=UNITS.NUMBER_FORMAT,
2778+
),
2779+
create_gauge_panel("tycho_slasher_active_sessions", "Slasher active sessions"),
2780+
create_gauge_panel(
2781+
"tycho_slasher_session_init_queue_len", "Slasher session init queue"
2782+
),
2783+
create_gauge_panel(
2784+
"tycho_slasher_batch_delivery_tasks", "Slasher batch delivery tasks"
2785+
),
2786+
create_gauge_panel(
2787+
"tycho_slasher_pending_messages", "Slasher pending messages"
2788+
),
2789+
create_counter_panel(
2790+
"tycho_slasher_blocks_batch_send_attempts_total",
2791+
"Slasher batch send attempts",
2792+
),
2793+
create_counter_panel(
2794+
"tycho_slasher_blocks_batch_send_results_total",
2795+
"Slasher batch send results",
2796+
by_labels=["instance", "result"],
2797+
legend_format="{{instance}} {{result}}",
2798+
),
2799+
create_counter_panel(
2800+
"tycho_slasher_blocks_batches_submitted_total",
2801+
"Slasher submitted batches",
2802+
by_labels=["instance", "origin"],
2803+
legend_format="{{instance}} {{origin}}",
2804+
),
2805+
create_counter_panel(
2806+
"tycho_slasher_contract_event_decode_errors_total",
2807+
"Slasher contract event decode errors",
2808+
),
2809+
create_counter_panel(
2810+
"tycho_slasher_vset_reports_total", "Slasher vset reports"
2811+
),
2812+
create_counter_panel(
2813+
"tycho_slasher_accusations_total",
2814+
"Slasher accusations",
2815+
by_labels=["instance", "pubkey"],
2816+
legend_format="{{instance}} {{pubkey}}",
2817+
legend_placement="bottom",
2818+
),
2819+
create_heatmap_panel(
2820+
"tycho_slasher_handle_state_time", "Slasher handle state time"
2821+
),
2822+
create_heatmap_panel(
2823+
"tycho_slasher_blocks_batch_delivery_time",
2824+
"Slasher blocks batch delivery time",
2825+
),
2826+
]
2827+
return create_row("Slasher", metrics)
2828+
2829+
27662830
def mempool_rounds() -> RowPanel:
27672831
metrics = [
27682832
create_gauge_panel(
@@ -3682,6 +3746,7 @@ def templates() -> Templating:
36823746
collator_misc_operations_metrics(),
36833747
collator_commit_block_metrics(),
36843748
validator(),
3749+
slasher(),
36853750
mempool_rounds(),
36863751
mempool_payload_rates(),
36873752
mempool_engine_rates(),

slasher/src/bc/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use crate::util::BitSet;
1616

1717
mod contract;
1818

19+
const METRIC_PENDING_MESSAGES: &str = "tycho_slasher_pending_messages";
20+
1921
#[derive(Clone, Copy)]
2022
pub struct EncodeBlocksBatchMessage<'a> {
2123
pub address: &'a StdAddr,
@@ -82,6 +84,7 @@ impl ContractSubscription {
8284
match self.pending_messages.entry(*msg_hash) {
8385
Entry::Vacant(entry) => {
8486
entry.insert(PendingMessage { expire_at, tx });
87+
self.report_pending_messages();
8588
Ok(rx)
8689
}
8790
Entry::Occupied(_) => anyhow::bail!("duplicate external message: {msg_hash}"),
@@ -100,6 +103,7 @@ impl ContractSubscription {
100103

101104
if let Some((_, pending)) = self.pending_messages.remove(msg_hash) {
102105
pending.tx.send(MessageDelivered { tx_hash: *tx_hash }).ok();
106+
self.report_pending_messages();
103107
return Ok(true);
104108
}
105109
Ok(false)
@@ -115,6 +119,15 @@ impl ContractSubscription {
115119
if dropped > 0 {
116120
tracing::warn!(dropped, "dropped pending messages");
117121
}
122+
self.report_pending_messages();
123+
}
124+
125+
pub fn reset_pending_messages_metrics() {
126+
metrics::gauge!(METRIC_PENDING_MESSAGES).set(0);
127+
}
128+
129+
pub fn report_pending_messages(&self) {
130+
metrics::gauge!(METRIC_PENDING_MESSAGES).set(self.pending_messages.len() as f64);
118131
}
119132
}
120133

slasher/src/collector/validator_events.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use tycho_util::{DashMapEntry, FastDashMap};
1515
use crate::bc::BlocksBatch;
1616

1717
const INIT_QUEUE_CAPACITY: usize = 3;
18+
const METRIC_ACTIVE_SESSIONS: &str = "tycho_slasher_active_sessions";
19+
const METRIC_SESSION_INIT_QUEUE_LEN: &str = "tycho_slasher_session_init_queue_len";
1820

1921
pub trait BlockBatchesStore {
2022
fn known_batch_size(&self) -> AtomicU32;
@@ -55,6 +57,8 @@ impl ValidatorEventsCollector {
5557
pub fn new(default_batch_size: NonZeroU32) -> Self {
5658
let init_queue_capacity = INIT_QUEUE_CAPACITY;
5759
let init_queue = Mutex::new(VecDeque::with_capacity(init_queue_capacity));
60+
metrics::gauge!(METRIC_ACTIVE_SESSIONS).set(0);
61+
metrics::gauge!(METRIC_SESSION_INIT_QUEUE_LEN).set(0);
5862

5963
Self {
6064
default_batch_size: AtomicU32::new(default_batch_size.get()),
@@ -71,7 +75,9 @@ impl ValidatorEventsCollector {
7175
{
7276
return None;
7377
}
74-
queue.pop_front()
78+
let result = queue.pop_front();
79+
metrics::gauge!(METRIC_SESSION_INIT_QUEUE_LEN).set(queue.len() as f64);
80+
result
7581
}
7682

7783
fn push_session_to_init(&self, info: ValidatorSessionInfo) {
@@ -85,6 +91,7 @@ impl ValidatorEventsCollector {
8591
);
8692
}
8793
items.push_back(info);
94+
metrics::gauge!(METRIC_SESSION_INIT_QUEUE_LEN).set(items.len() as f64);
8895
}
8996

9097
pub fn set_default_batch_size(&self, batch_size: NonZeroU32) {
@@ -119,7 +126,11 @@ impl ValidatorEventsCollector {
119126
}
120127

121128
pub fn skip_session(&self, session_id: ValidationSessionId) -> bool {
122-
self.sessions.remove(&session_id).is_some()
129+
let removed = self.sessions.remove(&session_id).is_some();
130+
if removed {
131+
metrics::gauge!(METRIC_ACTIVE_SESSIONS).set(self.sessions.len() as f64);
132+
}
133+
removed
123134
}
124135
}
125136

@@ -163,6 +174,7 @@ impl ValidatorEventsListener for ValidatorEventsCollector {
163174
own_validator_idx,
164175
validators,
165176
});
177+
metrics::gauge!(METRIC_ACTIVE_SESSIONS).set(self.sessions.len() as f64);
166178
} else {
167179
tracing::warn!("duplicate session");
168180
}
@@ -176,6 +188,7 @@ impl ValidatorEventsListener for ValidatorEventsCollector {
176188
{
177189
tracing::warn!("failed to commit blocks batch on finish: {e:?}");
178190
}
191+
metrics::gauge!(METRIC_ACTIVE_SESSIONS).set(self.sessions.len() as f64);
179192
}
180193

181194
#[instrument(skip_all, fields(session_id = ?session_id))]

0 commit comments

Comments
 (0)