Skip to content

Commit 97e4c1b

Browse files
feat: add lean_tick_interval_duration_seconds metric (lambdaclass#352)
closes lambdaclass#350 ## πŸ—’οΈ Description / Motivation Adds the `lean_tick_interval_duration_seconds` metric as defined in leanMetrics PR [lambdaclass#34](leanEthereum/leanMetrics#34). This tracks the scheduling interval of the blockchain server loop. ## What Changed * `crates/blockchain/src/lib.rs`: Added `last_tick_instant: Option<Instant>` to `BlockChainServer` to measure elapsed time at the top of `on_tick`. * `crates/blockchain/src/metrics.rs`: Registered the histogram with buckets from the spec. * `docs/metrics.md`: Added the new metric to the documentation. ## Correctness / Behavior Guarantees * Uses `std::time::Instant` (monotonic clock) rather than `SystemTime` to avoid wall-clock/NTP drift bugs. * Skips observation on the first tick. ## Tests Added / Run * Ran `cargo test -p ethlambda-blockchain --lib` (19 passed). ## βœ… Verification Checklist * [x] Ran `make fmt` β€” clean * [x] Ran `make lint` (clippy with `-D warnings`) β€” clean --------- Co-authored-by: TomΓ‘s GrΓΌner <47506558+MegaRedHand@users.noreply.github.com>
1 parent da95706 commit 97e4c1b

3 files changed

Lines changed: 32 additions & 1 deletion

File tree

β€Žcrates/blockchain/src/lib.rsβ€Ž

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use std::collections::{HashMap, HashSet, VecDeque};
2-
use std::time::{Duration, SystemTime};
2+
use std::time::{Duration, Instant, SystemTime};
33

44
use ethlambda_network_api::{BlockChainToP2PRef, InitP2P};
55
use ethlambda_state_transition::is_proposer;
@@ -73,6 +73,7 @@ impl BlockChain {
7373
aggregator,
7474
pending_block_parents: HashMap::new(),
7575
current_aggregation: None,
76+
last_tick_instant: None,
7677
}
7778
.start();
7879
let time_until_genesis = (SystemTime::UNIX_EPOCH + Duration::from_secs(genesis_time))
@@ -123,10 +124,19 @@ pub struct BlockChainServer {
123124
/// worker started at the most recent interval 2 is still running or until
124125
/// the next interval 2 takes over.
125126
current_aggregation: Option<AggregationSession>,
127+
128+
/// Last tick instant for measuring interval duration.
129+
last_tick_instant: Option<Instant>,
126130
}
127131

128132
impl BlockChainServer {
129133
async fn on_tick(&mut self, timestamp_ms: u64, ctx: &Context<Self>) {
134+
// Observe tick interval duration before any processing
135+
if let Some(prev_instant) = self.last_tick_instant {
136+
metrics::observe_tick_interval_duration(prev_instant.elapsed());
137+
}
138+
self.last_tick_instant = Some(Instant::now());
139+
130140
let genesis_time_ms = self.store.config().genesis_time * 1000;
131141

132142
// Calculate current slot and interval from milliseconds

β€Žcrates/blockchain/src/metrics.rsβ€Ž

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Prometheus metrics for the blockchain module.
22
3+
use std::time::Duration;
4+
35
use ethlambda_metrics::*;
46

57
// --- Gauges ---
@@ -305,6 +307,18 @@ static LEAN_FORK_CHOICE_REORG_DEPTH: std::sync::LazyLock<Histogram> =
305307
.unwrap()
306308
});
307309

310+
static LEAN_TICK_INTERVAL_DURATION_SECONDS: std::sync::LazyLock<Histogram> =
311+
std::sync::LazyLock::new(|| {
312+
register_histogram!(
313+
"lean_tick_interval_duration_seconds",
314+
"Elapsed time between clock ticks in seconds",
315+
vec![
316+
0.4, 0.6, 0.75, 0.8, 0.805, 0.81, 0.815, 0.82, 0.825, 0.85, 0.9, 1.0, 1.2, 1.6
317+
]
318+
)
319+
.unwrap()
320+
});
321+
308322
// --- Block Production ---
309323

310324
static LEAN_BLOCK_AGGREGATED_PAYLOADS: std::sync::LazyLock<Histogram> =
@@ -417,6 +431,7 @@ pub fn init() {
417431
std::sync::LazyLock::force(&LEAN_COMMITTEE_SIGNATURES_AGGREGATION_TIME_SECONDS);
418432
std::sync::LazyLock::force(&LEAN_AGGREGATED_PROOF_SIZE_BYTES);
419433
std::sync::LazyLock::force(&LEAN_FORK_CHOICE_REORG_DEPTH);
434+
std::sync::LazyLock::force(&LEAN_TICK_INTERVAL_DURATION_SECONDS);
420435
// Block production
421436
std::sync::LazyLock::force(&LEAN_BLOCK_AGGREGATED_PAYLOADS);
422437
std::sync::LazyLock::force(&LEAN_BLOCK_BUILDING_PAYLOAD_AGGREGATION_TIME_SECONDS);
@@ -599,6 +614,11 @@ pub fn observe_fork_choice_reorg_depth(depth: u64) {
599614
LEAN_FORK_CHOICE_REORG_DEPTH.observe(depth as f64);
600615
}
601616

617+
/// Observe the duration between consecutive tick intervals in seconds.
618+
pub fn observe_tick_interval_duration(duration: Duration) {
619+
LEAN_TICK_INTERVAL_DURATION_SECONDS.observe(duration.as_secs_f64());
620+
}
621+
602622
/// Observe the number of aggregated payloads in a built block.
603623
pub fn observe_block_aggregated_payloads(count: usize) {
604624
LEAN_BLOCK_AGGREGATED_PAYLOADS.observe(count as f64);

β€Ždocs/metrics.mdβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ The exposed metrics follow [the leanMetrics specification](https://github.com/le
4343
|`lean_attestation_validation_time_seconds`| Histogram | Time taken to validate attestation | On validate attestation | | 0.005, 0.01, 0.025, 0.05, 0.1, 1 | βœ… |
4444
| `lean_fork_choice_reorgs_total` | Counter | Total number of fork choice reorgs | On fork choice reorg | | | βœ… |
4545
| `lean_fork_choice_reorg_depth` | Histogram | Depth of fork choice reorgs (in blocks) | On fork choice reorg | | 1, 2, 3, 5, 7, 10, 20, 30, 50, 100 | βœ… |
46+
| `lean_tick_interval_duration_seconds` | Histogram | Elapsed time between clock ticks in seconds | At the start of each tick interval | | 0.4, 0.6, 0.75, 0.8, 0.805, 0.81, 0.815, 0.82, 0.825, 0.85, 0.9, 1.0, 1.2, 1.6 | βœ… |
4647
| `lean_gossip_signatures` | Gauge | Number of gossip signatures in fork-choice store | On gossip signatures update | | | βœ… |
4748
| `lean_latest_new_aggregated_payloads` | Gauge | Number of new aggregated payload items | On `latest_new_aggregated_payloads` update | | | βœ… |
4849
| `lean_latest_known_aggregated_payloads` | Gauge | Number of known aggregated payload items | On `latest_known_aggregated_payloads` update | | | βœ… |

0 commit comments

Comments
Β (0)