diff --git a/crates/optimism/rpc/src/eth/proofs.rs b/crates/optimism/rpc/src/eth/proofs.rs index 0a2a574440c..907543e12c2 100644 --- a/crates/optimism/rpc/src/eth/proofs.rs +++ b/crates/optimism/rpc/src/eth/proofs.rs @@ -1,11 +1,11 @@ //! Historical proofs RPC server implementation. +use crate::metrics::EthApiExtMetrics; use alloy_eips::BlockId; use alloy_primitives::Address; use alloy_rpc_types_eth::EIP1186AccountProofResponse; use alloy_serde::JsonStorageKey; use async_trait::async_trait; -use derive_more::Constructor; use jsonrpsee::proc_macros::rpc; use jsonrpsee_core::RpcResult; use jsonrpsee_types::error::ErrorObject; @@ -13,6 +13,7 @@ use reth_optimism_trie::{provider::OpProofsStateProviderRef, OpProofsStorage, Op use reth_provider::{BlockIdReader, ProviderError, ProviderResult, StateProofProvider}; use reth_rpc_api::eth::helpers::FullEthApi; use reth_rpc_eth_types::EthApiError; +use std::time::Instant; #[cfg_attr(not(test), rpc(server, namespace = "eth"))] #[cfg_attr(test, rpc(server, client, namespace = "eth"))] @@ -28,11 +29,12 @@ pub trait EthApiOverride { ) -> RpcResult; } -#[derive(Debug, Constructor)] +#[derive(Debug)] /// Overrides applied to the `eth_` namespace of the RPC API for historical proofs ExEx. pub struct EthApiExt { eth_api: Eth, preimage_store: OpProofsStorage

, + metrics: EthApiExtMetrics, } impl EthApiExt @@ -41,6 +43,12 @@ where ErrorObject<'static>: From, P: OpProofsStore + Clone + 'static, { + /// Creates a new instance with the provided ETH API and proof store. + pub fn new(eth_api: Eth, preimage_store: OpProofsStorage

) -> Self { + let metrics = EthApiExtMetrics::default(); + Self { eth_api, preimage_store, metrics } + } + async fn state_provider( &self, block_id: Option, @@ -95,11 +103,28 @@ where keys: Vec, block_number: Option, ) -> RpcResult { - let state = self.state_provider(block_number).await.map_err(Into::into)?; - let storage_keys = keys.iter().map(|key| key.as_b256()).collect::>(); + self.metrics.get_proof_requests.increment(1); + let start = Instant::now(); + + let result = async { + let state = self.state_provider(block_number).await.map_err(Into::into)?; + let storage_keys: Vec<_> = keys.iter().map(|key| key.as_b256()).collect(); + + let proof = + state.proof(Default::default(), address, &storage_keys).map_err(Into::into)?; - let proof = state.proof(Default::default(), address, &storage_keys).map_err(Into::into)?; + Ok(proof.into_eip1186_response(keys)) + } + .await; + + match &result { + Ok(_) => { + self.metrics.get_proof_latency.record(start.elapsed().as_secs_f64()); + self.metrics.get_proof_successful_responses.increment(1); + } + Err(_) => self.metrics.get_proof_failures.increment(1), + } - return Ok(proof.into_eip1186_response(keys)); + result } } diff --git a/crates/optimism/rpc/src/lib.rs b/crates/optimism/rpc/src/lib.rs index 10f8ad5dccd..5adb410bad0 100644 --- a/crates/optimism/rpc/src/lib.rs +++ b/crates/optimism/rpc/src/lib.rs @@ -22,5 +22,5 @@ pub use engine::OpEngineApiClient; pub use engine::{OpEngineApi, OpEngineApiServer, OP_ENGINE_CAPABILITIES}; pub use error::{OpEthApiError, OpInvalidTransactionError, SequencerClientError}; pub use eth::{OpEthApi, OpEthApiBuilder, OpReceiptBuilder}; -pub use metrics::SequencerMetrics; +pub use metrics::{EthApiExtMetrics, SequencerMetrics}; pub use sequencer::SequencerClient; diff --git a/crates/optimism/rpc/src/metrics.rs b/crates/optimism/rpc/src/metrics.rs index 5aa5e3eff3d..7979fe0164c 100644 --- a/crates/optimism/rpc/src/metrics.rs +++ b/crates/optimism/rpc/src/metrics.rs @@ -1,7 +1,7 @@ //! RPC metrics unique for OP-stack. use core::time::Duration; -use metrics::Histogram; +use metrics::{Counter, Histogram}; use reth_metrics::Metrics; /// Optimism sequencer metrics @@ -19,3 +19,20 @@ impl SequencerMetrics { self.sequencer_forward_latency.record(duration.as_secs_f64()); } } + +/// Optimism ETH API extension metrics +#[derive(Metrics, Clone)] +#[metrics(scope = "optimism_rpc.eth_api_ext")] +pub struct EthApiExtMetrics { + /// How long it takes to handle a `eth_getProof` request successfully + pub(crate) get_proof_latency: Histogram, + + /// Total number of `eth_getProof` requests + pub(crate) get_proof_requests: Counter, + + /// Total number of successful `eth_getProof` responses + pub(crate) get_proof_successful_responses: Counter, + + /// Total number of failures handling `eth_getProof` requests + pub(crate) get_proof_failures: Counter, +}