Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions crates/optimism/rpc/src/eth/proofs.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
//! 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;
use reth_optimism_trie::{provider::OpProofsStateProviderRef, OpProofsStorage, OpProofsStore};
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"))]
Expand All @@ -28,11 +29,12 @@ pub trait EthApiOverride {
) -> RpcResult<EIP1186AccountProofResponse>;
}

#[derive(Debug, Constructor)]
#[derive(Debug)]
/// Overrides applied to the `eth_` namespace of the RPC API for historical proofs ExEx.
pub struct EthApiExt<Eth, P> {
eth_api: Eth,
preimage_store: OpProofsStorage<P>,
metrics: EthApiExtMetrics,
}

impl<Eth, P> EthApiExt<Eth, P>
Expand All @@ -41,6 +43,12 @@ where
ErrorObject<'static>: From<Eth::Error>,
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<P>) -> Self {
let metrics = EthApiExtMetrics::default();
Self { eth_api, preimage_store, metrics }
}

async fn state_provider(
&self,
block_id: Option<BlockId>,
Expand Down Expand Up @@ -95,11 +103,28 @@ where
keys: Vec<JsonStorageKey>,
block_number: Option<BlockId>,
) -> RpcResult<EIP1186AccountProofResponse> {
let state = self.state_provider(block_number).await.map_err(Into::into)?;
let storage_keys = keys.iter().map(|key| key.as_b256()).collect::<Vec<_>>();
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
}
}
2 changes: 1 addition & 1 deletion crates/optimism/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
19 changes: 18 additions & 1 deletion crates/optimism/rpc/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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,
}