Skip to content

Commit 03d748f

Browse files
committed
Add Devnet-4 metrics: block production, gossip sizes, sync status, and bucket update (leanMetrics PR #29)
- Block production: building time, payload aggregation time, aggregated payload count, success/failure counters - Gossip message sizes: block, attestation, and aggregation compressed bytes - Sync status gauge with idle/syncing/synced labels (wiring deferred to PR #246) - Update committee_signatures_aggregation buckets from [0.005..1s] to [0.05..4s]
1 parent 0ee9ac1 commit 03d748f

5 files changed

Lines changed: 155 additions & 4 deletions

File tree

crates/blockchain/src/lib.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,16 @@ impl BlockChainServer {
222222
/// Build and publish a block for the given slot and validator.
223223
fn propose_block(&mut self, slot: u64, validator_id: u64) {
224224
info!(%slot, %validator_id, "We are the proposer for this slot");
225+
let _block_timing = metrics::time_block_building();
225226

226227
// Build the block with attestation signatures
227228
let Ok((block, attestation_signatures, post_checkpoints)) =
228-
store::produce_block_with_signatures(&mut self.store, slot, validator_id)
229-
.inspect_err(|err| error!(%slot, %validator_id, %err, "Failed to build block"))
229+
store::produce_block_with_signatures(&mut self.store, slot, validator_id).inspect_err(
230+
|err| {
231+
metrics::inc_block_building_failures();
232+
error!(%slot, %validator_id, %err, "Failed to build block");
233+
},
234+
)
230235
else {
231236
return;
232237
};
@@ -278,10 +283,13 @@ impl BlockChainServer {
278283

279284
// Process the block locally before publishing
280285
if let Err(err) = self.process_block(signed_block.clone()) {
286+
metrics::inc_block_building_failures();
281287
error!(%slot, %validator_id, %err, "Failed to process built block");
282288
return;
283289
};
284290

291+
metrics::inc_block_building_success();
292+
285293
// Publish to gossip network
286294
if let Some(ref p2p) = self.p2p {
287295
let _ = p2p

crates/blockchain/src/metrics.rs

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,59 @@ static LEAN_COMMITTEE_SIGNATURES_AGGREGATION_TIME_SECONDS: std::sync::LazyLock<H
261261
register_histogram!(
262262
"lean_committee_signatures_aggregation_time_seconds",
263263
"Time taken to aggregate committee signatures",
264-
vec![0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 0.75, 1.0]
264+
vec![0.05, 0.1, 0.25, 0.5, 0.75, 1.0, 2.0, 3.0, 4.0]
265265
)
266266
.unwrap()
267267
});
268268

269+
static LEAN_BLOCK_AGGREGATED_PAYLOADS: std::sync::LazyLock<Histogram> =
270+
std::sync::LazyLock::new(|| {
271+
register_histogram!(
272+
"lean_block_aggregated_payloads",
273+
"Number of aggregated_payloads in a block",
274+
vec![1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0]
275+
)
276+
.unwrap()
277+
});
278+
279+
static LEAN_BLOCK_BUILDING_PAYLOAD_AGGREGATION_TIME_SECONDS: std::sync::LazyLock<Histogram> =
280+
std::sync::LazyLock::new(|| {
281+
register_histogram!(
282+
"lean_block_building_payload_aggregation_time_seconds",
283+
"Time taken to build aggregated_payloads during block building",
284+
vec![0.1, 0.25, 0.5, 0.75, 1.0, 2.0, 3.0, 4.0]
285+
)
286+
.unwrap()
287+
});
288+
289+
static LEAN_BLOCK_BUILDING_TIME_SECONDS: std::sync::LazyLock<Histogram> =
290+
std::sync::LazyLock::new(|| {
291+
register_histogram!(
292+
"lean_block_building_time_seconds",
293+
"Time taken to build a block",
294+
vec![0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 0.75, 1.0]
295+
)
296+
.unwrap()
297+
});
298+
299+
static LEAN_BLOCK_BUILDING_SUCCESS_TOTAL: std::sync::LazyLock<IntCounter> =
300+
std::sync::LazyLock::new(|| {
301+
register_int_counter!(
302+
"lean_block_building_success_total",
303+
"Successful block builds"
304+
)
305+
.unwrap()
306+
});
307+
308+
static LEAN_BLOCK_BUILDING_FAILURES_TOTAL: std::sync::LazyLock<IntCounter> =
309+
std::sync::LazyLock::new(|| {
310+
register_int_counter!("lean_block_building_failures_total", "Failed block builds").unwrap()
311+
});
312+
313+
static LEAN_NODE_SYNC_STATUS: std::sync::LazyLock<IntGaugeVec> = std::sync::LazyLock::new(|| {
314+
register_int_gauge_vec!("lean_node_sync_status", "Node sync status", &["status"]).unwrap()
315+
});
316+
269317
static LEAN_FORK_CHOICE_REORG_DEPTH: std::sync::LazyLock<Histogram> =
270318
std::sync::LazyLock::new(|| {
271319
register_histogram!(
@@ -314,6 +362,12 @@ pub fn init() {
314362
std::sync::LazyLock::force(&LEAN_PQ_SIG_AGGREGATED_SIGNATURES_BUILDING_TIME_SECONDS);
315363
std::sync::LazyLock::force(&LEAN_PQ_SIG_AGGREGATED_SIGNATURES_VERIFICATION_TIME_SECONDS);
316364
std::sync::LazyLock::force(&LEAN_COMMITTEE_SIGNATURES_AGGREGATION_TIME_SECONDS);
365+
std::sync::LazyLock::force(&LEAN_BLOCK_AGGREGATED_PAYLOADS);
366+
std::sync::LazyLock::force(&LEAN_BLOCK_BUILDING_PAYLOAD_AGGREGATION_TIME_SECONDS);
367+
std::sync::LazyLock::force(&LEAN_BLOCK_BUILDING_TIME_SECONDS);
368+
std::sync::LazyLock::force(&LEAN_BLOCK_BUILDING_SUCCESS_TOTAL);
369+
std::sync::LazyLock::force(&LEAN_BLOCK_BUILDING_FAILURES_TOTAL);
370+
std::sync::LazyLock::force(&LEAN_NODE_SYNC_STATUS);
317371
std::sync::LazyLock::force(&LEAN_FORK_CHOICE_REORG_DEPTH);
318372
}
319373

@@ -476,3 +530,37 @@ pub fn set_attestation_committee_count(count: u64) {
476530
pub fn observe_fork_choice_reorg_depth(depth: u64) {
477531
LEAN_FORK_CHOICE_REORG_DEPTH.observe(depth as f64);
478532
}
533+
534+
/// Observe the number of aggregated payloads in a produced block.
535+
pub fn observe_block_aggregated_payloads(count: usize) {
536+
LEAN_BLOCK_AGGREGATED_PAYLOADS.observe(count as f64);
537+
}
538+
539+
/// Start timing payload aggregation during block building. Records duration when the guard is dropped.
540+
pub fn time_block_building_payload_aggregation() -> TimingGuard {
541+
TimingGuard::new(&LEAN_BLOCK_BUILDING_PAYLOAD_AGGREGATION_TIME_SECONDS)
542+
}
543+
544+
/// Start timing block building. Records duration when the guard is dropped.
545+
pub fn time_block_building() -> TimingGuard {
546+
TimingGuard::new(&LEAN_BLOCK_BUILDING_TIME_SECONDS)
547+
}
548+
549+
/// Increment the successful block builds counter.
550+
pub fn inc_block_building_success() {
551+
LEAN_BLOCK_BUILDING_SUCCESS_TOTAL.inc();
552+
}
553+
554+
/// Increment the failed block builds counter.
555+
pub fn inc_block_building_failures() {
556+
LEAN_BLOCK_BUILDING_FAILURES_TOTAL.inc();
557+
}
558+
559+
/// Set the node sync status. Sets the given status label to 1 and all others to 0.
560+
pub fn set_sync_status(status: &str) {
561+
for label in &["idle", "syncing", "synced"] {
562+
LEAN_NODE_SYNC_STATUS
563+
.with_label_values(&[label])
564+
.set(i64::from(*label == status));
565+
}
566+
}

crates/blockchain/src/store.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ pub fn produce_block_with_signatures(
814814

815815
let known_block_roots = store.get_block_roots();
816816

817+
let _payload_timing = metrics::time_block_building_payload_aggregation();
817818
let (block, signatures, post_checkpoints) = build_block(
818819
&head_state,
819820
slot,
@@ -822,6 +823,9 @@ pub fn produce_block_with_signatures(
822823
&known_block_roots,
823824
&aggregated_payloads,
824825
)?;
826+
drop(_payload_timing);
827+
828+
metrics::observe_block_aggregated_payloads(signatures.len());
825829

826830
Ok((block, signatures, post_checkpoints))
827831
}

crates/net/p2p/src/gossipsub/handler.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use super::{
1515
attestation_subnet_topic,
1616
},
1717
};
18-
use crate::P2PServer;
18+
use crate::{P2PServer, metrics};
1919

2020
pub async fn handle_gossipsub_message(server: &mut P2PServer, event: Event) {
2121
let Event::Message {
@@ -29,6 +29,7 @@ pub async fn handle_gossipsub_message(server: &mut P2PServer, event: Event) {
2929
let topic_kind = message.topic.as_str().split("/").nth(3);
3030
match topic_kind {
3131
Some(BLOCK_TOPIC_KIND) => {
32+
metrics::observe_gossip_block_size(message.data.len());
3233
let Ok(uncompressed_data) = decompress_message(&message.data)
3334
.inspect_err(|err| error!(%err, "Failed to decompress gossipped block"))
3435
else {
@@ -60,6 +61,7 @@ pub async fn handle_gossipsub_message(server: &mut P2PServer, event: Event) {
6061
}
6162
}
6263
Some(AGGREGATION_TOPIC_KIND) => {
64+
metrics::observe_gossip_aggregation_size(message.data.len());
6365
let Ok(uncompressed_data) = decompress_message(&message.data)
6466
.inspect_err(|err| error!(%err, "Failed to decompress gossipped aggregation"))
6567
else {
@@ -89,6 +91,7 @@ pub async fn handle_gossipsub_message(server: &mut P2PServer, event: Event) {
8991
}
9092
}
9193
Some(kind) if kind.starts_with(ATTESTATION_SUBNET_TOPIC_PREFIX) => {
94+
metrics::observe_gossip_attestation_size(message.data.len());
9295
let Ok(uncompressed_data) = decompress_message(&message.data)
9396
.inspect_err(|err| error!(%err, "Failed to decompress gossipped attestation"))
9497
else {

crates/net/p2p/src/metrics.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,54 @@ pub fn notify_peer_connected(peer_id: &Option<PeerId>, direction: &str, result:
9595
}
9696
}
9797

98+
static LEAN_GOSSIP_BLOCK_SIZE_BYTES: LazyLock<ethlambda_metrics::Histogram> = LazyLock::new(|| {
99+
ethlambda_metrics::register_histogram!(
100+
"lean_gossip_block_size_bytes",
101+
"Bytes size of a gossip block message",
102+
vec![
103+
10000.0, 50000.0, 100000.0, 250000.0, 500000.0, 1000000.0, 2000000.0, 5000000.0
104+
]
105+
)
106+
.unwrap()
107+
});
108+
109+
static LEAN_GOSSIP_ATTESTATION_SIZE_BYTES: LazyLock<ethlambda_metrics::Histogram> =
110+
LazyLock::new(|| {
111+
ethlambda_metrics::register_histogram!(
112+
"lean_gossip_attestation_size_bytes",
113+
"Bytes size of a gossip attestation message",
114+
vec![512.0, 1024.0, 2048.0, 4096.0, 8192.0, 16384.0]
115+
)
116+
.unwrap()
117+
});
118+
119+
static LEAN_GOSSIP_AGGREGATION_SIZE_BYTES: LazyLock<ethlambda_metrics::Histogram> =
120+
LazyLock::new(|| {
121+
ethlambda_metrics::register_histogram!(
122+
"lean_gossip_aggregation_size_bytes",
123+
"Bytes size of a gossip aggregated attestation message",
124+
vec![
125+
1024.0, 4096.0, 16384.0, 65536.0, 131072.0, 262144.0, 524288.0, 1048576.0
126+
]
127+
)
128+
.unwrap()
129+
});
130+
131+
/// Observe the compressed size of a gossip block message.
132+
pub fn observe_gossip_block_size(bytes: usize) {
133+
LEAN_GOSSIP_BLOCK_SIZE_BYTES.observe(bytes as f64);
134+
}
135+
136+
/// Observe the compressed size of a gossip attestation message.
137+
pub fn observe_gossip_attestation_size(bytes: usize) {
138+
LEAN_GOSSIP_ATTESTATION_SIZE_BYTES.observe(bytes as f64);
139+
}
140+
141+
/// Observe the compressed size of a gossip aggregated attestation message.
142+
pub fn observe_gossip_aggregation_size(bytes: usize) {
143+
LEAN_GOSSIP_AGGREGATION_SIZE_BYTES.observe(bytes as f64);
144+
}
145+
98146
/// Notify that a peer disconnected.
99147
///
100148
/// Decrements the connected peer count and increments the disconnection event counter.

0 commit comments

Comments
 (0)