reth_rpc_engine_api/metrics.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
use std::time::Duration;
use crate::EngineApiError;
use alloy_rpc_types_engine::{ForkchoiceUpdated, PayloadStatus, PayloadStatusEnum};
use metrics::{Counter, Histogram};
use reth_metrics::Metrics;
/// All beacon consensus engine metrics
#[derive(Default)]
pub(crate) struct EngineApiMetrics {
/// Engine API latency metrics
pub(crate) latency: EngineApiLatencyMetrics,
/// Engine API forkchoiceUpdated response type metrics
pub(crate) fcu_response: ForkchoiceUpdatedResponseMetrics,
/// Engine API newPayload response type metrics
pub(crate) new_payload_response: NewPayloadStatusResponseMetrics,
}
/// Beacon consensus engine latency metrics.
#[derive(Metrics)]
#[metrics(scope = "engine.rpc")]
pub(crate) struct EngineApiLatencyMetrics {
/// Latency for `engine_newPayloadV1`
pub(crate) new_payload_v1: Histogram,
/// Latency for `engine_newPayloadV2`
pub(crate) new_payload_v2: Histogram,
/// Latency for `engine_newPayloadV3`
pub(crate) new_payload_v3: Histogram,
/// Latency for `engine_newPayloadV4`
pub(crate) new_payload_v4: Histogram,
/// Latency for `engine_forkchoiceUpdatedV1`
pub(crate) fork_choice_updated_v1: Histogram,
/// Latency for `engine_forkchoiceUpdatedV2`
pub(crate) fork_choice_updated_v2: Histogram,
/// Latency for `engine_forkchoiceUpdatedV3`
pub(crate) fork_choice_updated_v3: Histogram,
/// Time diff between `engine_newPayloadV*` and the next FCU
pub(crate) new_payload_forkchoice_updated_time_diff: Histogram,
/// Latency for `engine_getPayloadV1`
pub(crate) get_payload_v1: Histogram,
/// Latency for `engine_getPayloadV2`
pub(crate) get_payload_v2: Histogram,
/// Latency for `engine_getPayloadV3`
pub(crate) get_payload_v3: Histogram,
/// Latency for `engine_getPayloadV4`
pub(crate) get_payload_v4: Histogram,
/// Latency for `engine_getPayloadBodiesByRangeV1`
pub(crate) get_payload_bodies_by_range_v1: Histogram,
/// Latency for `engine_getPayloadBodiesByHashV1`
pub(crate) get_payload_bodies_by_hash_v1: Histogram,
/// Latency for `engine_exchangeTransitionConfigurationV1`
pub(crate) exchange_transition_configuration: Histogram,
}
/// Metrics for engine API forkchoiceUpdated responses.
#[derive(Metrics)]
#[metrics(scope = "engine.rpc")]
pub(crate) struct ForkchoiceUpdatedResponseMetrics {
/// The total count of forkchoice updated messages received.
pub(crate) forkchoice_updated_messages: Counter,
/// The total count of forkchoice updated messages that we responded to with
/// [`Invalid`](alloy_rpc_types_engine::PayloadStatusEnum#Invalid).
pub(crate) forkchoice_updated_invalid: Counter,
/// The total count of forkchoice updated messages that we responded to with
/// [`Valid`](alloy_rpc_types_engine::PayloadStatusEnum#Valid).
pub(crate) forkchoice_updated_valid: Counter,
/// The total count of forkchoice updated messages that we responded to with
/// [`Syncing`](alloy_rpc_types_engine::PayloadStatusEnum#Syncing).
pub(crate) forkchoice_updated_syncing: Counter,
/// The total count of forkchoice updated messages that we responded to with
/// [`Accepted`](alloy_rpc_types_engine::PayloadStatusEnum#Accepted).
pub(crate) forkchoice_updated_accepted: Counter,
/// The total count of forkchoice updated messages that were unsuccessful, i.e. we responded
/// with an error type that is not a [`PayloadStatusEnum`].
pub(crate) forkchoice_updated_error: Counter,
}
/// Metrics for engine API newPayload responses.
#[derive(Metrics)]
#[metrics(scope = "engine.rpc")]
pub(crate) struct NewPayloadStatusResponseMetrics {
/// The total count of new payload messages received.
pub(crate) new_payload_messages: Counter,
/// The total count of new payload messages that we responded to with
/// [Invalid](alloy_rpc_types_engine::PayloadStatusEnum#Invalid).
pub(crate) new_payload_invalid: Counter,
/// The total count of new payload messages that we responded to with
/// [Valid](alloy_rpc_types_engine::PayloadStatusEnum#Valid).
pub(crate) new_payload_valid: Counter,
/// The total count of new payload messages that we responded to with
/// [Syncing](alloy_rpc_types_engine::PayloadStatusEnum#Syncing).
pub(crate) new_payload_syncing: Counter,
/// The total count of new payload messages that we responded to with
/// [Accepted](alloy_rpc_types_engine::PayloadStatusEnum#Accepted).
pub(crate) new_payload_accepted: Counter,
/// The total count of new payload messages that were unsuccessful, i.e. we responded with an
/// error type that is not a [`PayloadStatusEnum`].
pub(crate) new_payload_error: Counter,
/// The total gas of valid new payload messages received.
pub(crate) new_payload_total_gas: Histogram,
/// The gas per second of valid new payload messages received.
pub(crate) new_payload_gas_per_second: Histogram,
}
impl NewPayloadStatusResponseMetrics {
/// Increment the newPayload counter based on the given rpc result
pub(crate) fn update_response_metrics(
&self,
result: &Result<PayloadStatus, EngineApiError>,
gas_used: u64,
time: Duration,
) {
match result {
Ok(status) => match status.status {
PayloadStatusEnum::Valid => {
self.new_payload_valid.increment(1);
self.new_payload_total_gas.record(gas_used as f64);
self.new_payload_gas_per_second.record(gas_used as f64 / time.as_secs_f64());
}
PayloadStatusEnum::Syncing => self.new_payload_syncing.increment(1),
PayloadStatusEnum::Accepted => self.new_payload_accepted.increment(1),
PayloadStatusEnum::Invalid { .. } => self.new_payload_invalid.increment(1),
},
Err(_) => self.new_payload_error.increment(1),
}
self.new_payload_messages.increment(1);
}
}
impl ForkchoiceUpdatedResponseMetrics {
/// Increment the forkchoiceUpdated counter based on the given rpc result
pub(crate) fn update_response_metrics(
&self,
result: &Result<ForkchoiceUpdated, EngineApiError>,
) {
match result {
Ok(status) => match status.payload_status.status {
PayloadStatusEnum::Valid => self.forkchoice_updated_valid.increment(1),
PayloadStatusEnum::Syncing => self.forkchoice_updated_syncing.increment(1),
PayloadStatusEnum::Accepted => self.forkchoice_updated_accepted.increment(1),
PayloadStatusEnum::Invalid { .. } => self.forkchoice_updated_invalid.increment(1),
},
Err(_) => self.forkchoice_updated_error.increment(1),
}
self.forkchoice_updated_messages.increment(1);
}
}