reth_rpc_engine_api/
metrics.rs1use std::time::Duration;
2
3use crate::EngineApiError;
4use alloy_rpc_types_engine::{ForkchoiceUpdated, PayloadStatus, PayloadStatusEnum};
5use metrics::{Counter, Gauge, Histogram};
6use reth_metrics::Metrics;
7
8#[derive(Default)]
10pub(crate) struct EngineApiMetrics {
11    pub(crate) latency: EngineApiLatencyMetrics,
13    pub(crate) fcu_response: ForkchoiceUpdatedResponseMetrics,
15    pub(crate) new_payload_response: NewPayloadStatusResponseMetrics,
17    pub(crate) blob_metrics: BlobMetrics,
19}
20
21#[derive(Metrics)]
23#[metrics(scope = "engine.rpc")]
24pub(crate) struct EngineApiLatencyMetrics {
25    pub(crate) new_payload_v1: Histogram,
27    pub(crate) new_payload_v2: Histogram,
29    pub(crate) new_payload_v3: Histogram,
31    pub(crate) new_payload_v4: Histogram,
33    pub(crate) fork_choice_updated_v1: Histogram,
35    pub(crate) fork_choice_updated_v2: Histogram,
37    pub(crate) fork_choice_updated_v3: Histogram,
39    pub(crate) new_payload_forkchoice_updated_time_diff: Histogram,
41    pub(crate) get_payload_v1: Histogram,
43    pub(crate) get_payload_v2: Histogram,
45    pub(crate) get_payload_v3: Histogram,
47    pub(crate) get_payload_v4: Histogram,
49    pub(crate) get_payload_v5: Histogram,
51    pub(crate) get_payload_bodies_by_range_v1: Histogram,
53    pub(crate) get_payload_bodies_by_hash_v1: Histogram,
55    pub(crate) get_blobs_v1: Histogram,
57    pub(crate) get_blobs_v2: Histogram,
59}
60
61#[derive(Metrics)]
63#[metrics(scope = "engine.rpc")]
64pub(crate) struct ForkchoiceUpdatedResponseMetrics {
65    pub(crate) forkchoice_updated_messages: Counter,
67    pub(crate) forkchoice_updated_invalid: Counter,
70    pub(crate) forkchoice_updated_valid: Counter,
73    pub(crate) forkchoice_updated_syncing: Counter,
76    pub(crate) forkchoice_updated_accepted: Counter,
79    pub(crate) forkchoice_updated_error: Counter,
82}
83
84#[derive(Metrics)]
86#[metrics(scope = "engine.rpc")]
87pub(crate) struct NewPayloadStatusResponseMetrics {
88    pub(crate) new_payload_messages: Counter,
90    pub(crate) new_payload_invalid: Counter,
93    pub(crate) new_payload_valid: Counter,
96    pub(crate) new_payload_syncing: Counter,
99    pub(crate) new_payload_accepted: Counter,
102    pub(crate) new_payload_error: Counter,
105    pub(crate) new_payload_total_gas: Histogram,
107    pub(crate) new_payload_gas_per_second: Histogram,
109    pub(crate) new_payload_last: Gauge,
111}
112
113#[derive(Metrics)]
114#[metrics(scope = "engine.rpc.blobs")]
115pub(crate) struct BlobMetrics {
116    pub(crate) blob_count: Counter,
118    pub(crate) blob_misses: Counter,
120    pub(crate) get_blobs_requests_blobs_total: Counter,
122    pub(crate) get_blobs_requests_blobs_in_blobpool_total: Counter,
124    pub(crate) get_blobs_requests_success_total: Counter,
126    pub(crate) get_blobs_requests_failure_total: Counter,
128}
129
130impl NewPayloadStatusResponseMetrics {
131    pub(crate) fn update_response_metrics(
133        &self,
134        result: &Result<PayloadStatus, EngineApiError>,
135        gas_used: u64,
136        time: Duration,
137    ) {
138        self.new_payload_last.set(time);
139        match result {
140            Ok(status) => match status.status {
141                PayloadStatusEnum::Valid => {
142                    self.new_payload_valid.increment(1);
143                    self.new_payload_total_gas.record(gas_used as f64);
144                    self.new_payload_gas_per_second.record(gas_used as f64 / time.as_secs_f64());
145                }
146                PayloadStatusEnum::Syncing => self.new_payload_syncing.increment(1),
147                PayloadStatusEnum::Accepted => self.new_payload_accepted.increment(1),
148                PayloadStatusEnum::Invalid { .. } => self.new_payload_invalid.increment(1),
149            },
150            Err(_) => self.new_payload_error.increment(1),
151        }
152        self.new_payload_messages.increment(1);
153    }
154}
155
156impl ForkchoiceUpdatedResponseMetrics {
157    pub(crate) fn update_response_metrics(
159        &self,
160        result: &Result<ForkchoiceUpdated, EngineApiError>,
161    ) {
162        match result {
163            Ok(status) => match status.payload_status.status {
164                PayloadStatusEnum::Valid => self.forkchoice_updated_valid.increment(1),
165                PayloadStatusEnum::Syncing => self.forkchoice_updated_syncing.increment(1),
166                PayloadStatusEnum::Accepted => self.forkchoice_updated_accepted.increment(1),
167                PayloadStatusEnum::Invalid { .. } => self.forkchoice_updated_invalid.increment(1),
168            },
169            Err(_) => self.forkchoice_updated_error.increment(1),
170        }
171        self.forkchoice_updated_messages.increment(1);
172    }
173}