mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-19 03:04:27 -05:00
feat(engine): add gas-bucketed sub-phase metrics for new_payload (#22210)
Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: YK <chiayongkang@hotmail.com>
This commit is contained in:
committed by
GitHub
parent
11acd97982
commit
317f858bd4
@@ -34,6 +34,10 @@ pub struct EngineApiMetrics {
|
||||
/// Metrics for EIP-7928 Block-Level Access Lists (BAL).
|
||||
#[allow(dead_code)]
|
||||
pub(crate) bal: BalMetrics,
|
||||
/// Gas-bucketed execution sub-phase metrics.
|
||||
pub(crate) execution_gas_buckets: ExecutionGasBucketMetrics,
|
||||
/// Gas-bucketed block validation sub-phase metrics.
|
||||
pub(crate) block_validation_gas_buckets: BlockValidationGasBucketMetrics,
|
||||
}
|
||||
|
||||
impl EngineApiMetrics {
|
||||
@@ -82,6 +86,22 @@ impl EngineApiMetrics {
|
||||
self.executor.post_execution_histogram.record(elapsed);
|
||||
}
|
||||
|
||||
/// Records execution duration into the gas-bucketed execution histogram.
|
||||
pub fn record_block_execution_gas_bucket(&self, gas_used: u64, elapsed: Duration) {
|
||||
let idx = GasBucketMetrics::bucket_index(gas_used);
|
||||
self.execution_gas_buckets.buckets[idx]
|
||||
.execution_gas_bucket_histogram
|
||||
.record(elapsed.as_secs_f64());
|
||||
}
|
||||
|
||||
/// Records state root duration into the gas-bucketed block validation histogram.
|
||||
pub fn record_state_root_gas_bucket(&self, gas_used: u64, elapsed_secs: f64) {
|
||||
let idx = GasBucketMetrics::bucket_index(gas_used);
|
||||
self.block_validation_gas_buckets.buckets[idx]
|
||||
.state_root_gas_bucket_histogram
|
||||
.record(elapsed_secs);
|
||||
}
|
||||
|
||||
/// Records the time spent waiting for the next transaction from the iterator.
|
||||
pub fn record_transaction_wait(&self, elapsed: Duration) {
|
||||
self.executor.transaction_wait_histogram.record(elapsed);
|
||||
@@ -280,7 +300,8 @@ impl GasBucketMetrics {
|
||||
.record(gas_used as f64 / elapsed.as_secs_f64());
|
||||
}
|
||||
|
||||
fn bucket_index(gas_used: u64) -> usize {
|
||||
/// Returns the bucket index for a given gas value.
|
||||
pub(crate) fn bucket_index(gas_used: u64) -> usize {
|
||||
GAS_BUCKET_THRESHOLDS
|
||||
.iter()
|
||||
.position(|&threshold| gas_used < threshold)
|
||||
@@ -288,7 +309,7 @@ impl GasBucketMetrics {
|
||||
}
|
||||
|
||||
/// Returns a human-readable label like `<5M`, `5-10M`, … `>40M`.
|
||||
fn bucket_label(index: usize) -> String {
|
||||
pub(crate) fn bucket_label(index: usize) -> String {
|
||||
if index == 0 {
|
||||
let hi = GAS_BUCKET_THRESHOLDS[0] / MEGAGAS;
|
||||
format!("<{hi}M")
|
||||
@@ -303,6 +324,56 @@ impl GasBucketMetrics {
|
||||
}
|
||||
}
|
||||
|
||||
/// Per-gas-bucket execution duration metric.
|
||||
#[derive(Clone, Metrics)]
|
||||
#[metrics(scope = "sync.execution")]
|
||||
pub(crate) struct ExecutionGasBucketSeries {
|
||||
/// Gas-bucketed EVM execution duration.
|
||||
pub(crate) execution_gas_bucket_histogram: Histogram,
|
||||
}
|
||||
|
||||
/// Holds pre-initialized [`ExecutionGasBucketSeries`] instances, one per gas bucket.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct ExecutionGasBucketMetrics {
|
||||
buckets: [ExecutionGasBucketSeries; NUM_GAS_BUCKETS],
|
||||
}
|
||||
|
||||
impl Default for ExecutionGasBucketMetrics {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
buckets: std::array::from_fn(|i| {
|
||||
let label = GasBucketMetrics::bucket_label(i);
|
||||
ExecutionGasBucketSeries::new_with_labels(&[("gas_bucket", label)])
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Per-gas-bucket block validation metrics (state root).
|
||||
#[derive(Clone, Metrics)]
|
||||
#[metrics(scope = "sync.block_validation")]
|
||||
pub(crate) struct BlockValidationGasBucketSeries {
|
||||
/// Gas-bucketed state root computation duration.
|
||||
pub(crate) state_root_gas_bucket_histogram: Histogram,
|
||||
}
|
||||
|
||||
/// Holds pre-initialized [`BlockValidationGasBucketSeries`] instances, one per gas bucket.
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct BlockValidationGasBucketMetrics {
|
||||
buckets: [BlockValidationGasBucketSeries; NUM_GAS_BUCKETS],
|
||||
}
|
||||
|
||||
impl Default for BlockValidationGasBucketMetrics {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
buckets: std::array::from_fn(|i| {
|
||||
let label = GasBucketMetrics::bucket_label(i);
|
||||
BlockValidationGasBucketSeries::new_with_labels(&[("gas_bucket", label)])
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics for engine newPayload responses.
|
||||
#[derive(Metrics)]
|
||||
#[metrics(scope = "consensus.engine.beacon")]
|
||||
|
||||
@@ -597,6 +597,8 @@ where
|
||||
};
|
||||
|
||||
self.metrics.block_validation.record_state_root(&trie_output, root_elapsed.as_secs_f64());
|
||||
self.metrics
|
||||
.record_state_root_gas_bucket(block.header().gas_used(), root_elapsed.as_secs_f64());
|
||||
debug!(target: "engine::tree::payload_validator", ?root_elapsed, "Calculated state root");
|
||||
|
||||
// ensure state root matches
|
||||
@@ -765,6 +767,7 @@ where
|
||||
|
||||
let execution_duration = execution_start.elapsed();
|
||||
self.metrics.record_block_execution(&output, execution_duration);
|
||||
self.metrics.record_block_execution_gas_bucket(output.result.gas_used, execution_duration);
|
||||
|
||||
debug!(target: "engine::tree::payload_validator", elapsed = ?execution_duration, "Executed block");
|
||||
Ok((output, senders, result_rx))
|
||||
|
||||
Reference in New Issue
Block a user