Skip to content

Commit

Permalink
feat: make RPC cache generic over primitives (paradigmxyz#13146)
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr authored Dec 5, 2024
1 parent 804dc99 commit b4124dd
Show file tree
Hide file tree
Showing 31 changed files with 354 additions and 274 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/optimism/evm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ reth-chainspec.workspace = true
reth-ethereum-forks.workspace = true
reth-evm.workspace = true
reth-primitives.workspace = true
reth-primitives-traits.workspace = true
reth-revm.workspace = true
reth-execution-errors.workspace = true
reth-execution-types.workspace = true
Expand Down Expand Up @@ -63,6 +64,7 @@ std = [
"alloy-genesis/std",
"alloy-primitives/std",
"revm-primitives/std",
"reth-primitives-traits/std",
"revm/std",
"reth-optimism-primitives/std",
"reth-ethereum-forks/std",
Expand Down
6 changes: 3 additions & 3 deletions crates/optimism/evm/src/l1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use reth_chainspec::ChainSpec;
use reth_execution_errors::BlockExecutionError;
use reth_optimism_chainspec::OpChainSpec;
use reth_optimism_forks::OpHardfork;
use reth_primitives::BlockBody;
use reth_primitives_traits::BlockBody;
use revm::{
primitives::{Bytecode, HashMap, SpecId},
DatabaseCommit, L1BlockInfo,
Expand All @@ -32,9 +32,9 @@ const L1_BLOCK_ECOTONE_SELECTOR: [u8; 4] = hex!("440a5e20");
/// transaction in the L2 block.
///
/// Returns an error if the L1 info transaction is not found, if the block is empty.
pub fn extract_l1_info(body: &BlockBody) -> Result<L1BlockInfo, OpBlockExecutionError> {
pub fn extract_l1_info<B: BlockBody>(body: &B) -> Result<L1BlockInfo, OpBlockExecutionError> {
let l1_info_tx_data = body
.transactions
.transactions()
.first()
.ok_or_else(|| OpBlockExecutionError::L1BlockInfoError {
message: "could not find l1 block info tx in the L2 block".to_string(),
Expand Down
8 changes: 4 additions & 4 deletions crates/optimism/rpc/src/eth/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ use reth_primitives::TransactionMeta;
use reth_provider::HeaderProvider;
use reth_rpc_eth_api::{
helpers::{EthBlocks, LoadBlock, LoadPendingBlock, LoadReceipt, SpawnBlocking},
RpcNodeCore, RpcReceipt,
RpcReceipt,
};

use crate::{OpEthApi, OpEthApiError, OpReceiptBuilder};
use crate::{eth::OpNodeCore, OpEthApi, OpEthApiError, OpReceiptBuilder};

impl<N> EthBlocks for OpEthApi<N>
where
Self: LoadBlock<
Error = OpEthApiError,
NetworkTypes: Network<ReceiptResponse = OpTransactionReceipt>,
>,
N: RpcNodeCore<Provider: ChainSpecProvider<ChainSpec = OpChainSpec> + HeaderProvider>,
N: OpNodeCore<Provider: ChainSpecProvider<ChainSpec = OpChainSpec> + HeaderProvider>,
{
async fn block_receipts(
&self,
Expand Down Expand Up @@ -77,6 +77,6 @@ where
impl<N> LoadBlock for OpEthApi<N>
where
Self: LoadPendingBlock + SpawnBlocking,
N: RpcNodeCore,
N: OpNodeCore,
{
}
9 changes: 5 additions & 4 deletions crates/optimism/rpc/src/eth/call.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
use super::OpNodeCore;
use crate::{OpEthApi, OpEthApiError};
use alloy_consensus::Header;
use alloy_primitives::{Bytes, TxKind, U256};
use alloy_rpc_types_eth::transaction::TransactionRequest;
use reth_evm::ConfigureEvm;
use reth_rpc_eth_api::{
helpers::{estimate::EstimateCall, Call, EthCall, LoadPendingBlock, LoadState, SpawnBlocking},
FromEthApiError, IntoEthApiError, RpcNodeCore,
FromEthApiError, IntoEthApiError,
};
use reth_rpc_eth_types::{revm_utils::CallFees, RpcInvalidTransactionError};
use revm::primitives::{BlockEnv, OptimismFields, TxEnv};

impl<N> EthCall for OpEthApi<N>
where
Self: EstimateCall + LoadPendingBlock,
N: RpcNodeCore,
N: OpNodeCore,
{
}

impl<N> EstimateCall for OpEthApi<N>
where
Self: Call,
Self::Error: From<OpEthApiError>,
N: RpcNodeCore,
N: OpNodeCore,
{
}

impl<N> Call for OpEthApi<N>
where
Self: LoadState<Evm: ConfigureEvm<Header = Header>> + SpawnBlocking,
Self::Error: From<OpEthApiError>,
N: RpcNodeCore,
N: OpNodeCore,
{
#[inline]
fn call_gas_limit(&self) -> u64 {
Expand Down
50 changes: 29 additions & 21 deletions crates/optimism/rpc/src/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod call;
mod pending_block;

pub use receipt::{OpReceiptBuilder, OpReceiptFieldsBuilder};
use reth_node_api::NodePrimitives;
use reth_optimism_primitives::OpPrimitives;

use std::{fmt, sync::Arc};
Expand All @@ -21,7 +22,8 @@ use reth_network_api::NetworkInfo;
use reth_node_builder::EthApiBuilderCtx;
use reth_provider::{
BlockNumReader, BlockReader, BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider,
EvmEnvProvider, StageCheckpointReader, StateProviderFactory,
EvmEnvProvider, NodePrimitivesProvider, ProviderBlock, ProviderReceipt, StageCheckpointReader,
StateProviderFactory,
};
use reth_rpc::eth::{core::EthApiInner, DevSigner};
use reth_rpc_eth_api::{
Expand All @@ -48,6 +50,10 @@ pub type EthApiNodeBackend<N> = EthApiInner<
<N as RpcNodeCore>::Evm,
>;

/// A helper trait with requirements for [`RpcNodeCore`] to be used in [`OpEthApi`].
pub trait OpNodeCore: RpcNodeCore<Provider: BlockReader> {}
impl<T> OpNodeCore for T where T: RpcNodeCore<Provider: BlockReader> {}

/// OP-Reth `Eth` API implementation.
///
/// This type provides the functionality for handling `eth_` related requests.
Expand All @@ -59,14 +65,14 @@ pub type EthApiNodeBackend<N> = EthApiInner<
/// This type implements the [`FullEthApi`](reth_rpc_eth_api::helpers::FullEthApi) by implemented
/// all the `Eth` helper traits and prerequisite traits.
#[derive(Clone)]
pub struct OpEthApi<N: RpcNodeCore> {
pub struct OpEthApi<N: OpNodeCore> {
/// Gateway to node's core components.
inner: Arc<OpEthApiInner<N>>,
}

impl<N> OpEthApi<N>
where
N: RpcNodeCore<
N: OpNodeCore<
Provider: BlockReaderIdExt
+ ChainSpecProvider
+ CanonStateSubscriptions<Primitives = OpPrimitives>
Expand All @@ -83,7 +89,7 @@ where
impl<N> EthApiTypes for OpEthApi<N>
where
Self: Send + Sync,
N: RpcNodeCore,
N: OpNodeCore,
{
type Error = OpEthApiError;
type NetworkTypes = Optimism;
Expand All @@ -96,7 +102,7 @@ where

impl<N> RpcNodeCore for OpEthApi<N>
where
N: RpcNodeCore,
N: OpNodeCore,
{
type Provider = N::Provider;
type Pool = N::Pool;
Expand Down Expand Up @@ -132,17 +138,17 @@ where

impl<N> RpcNodeCoreExt for OpEthApi<N>
where
N: RpcNodeCore,
N: OpNodeCore,
{
#[inline]
fn cache(&self) -> &EthStateCache {
fn cache(&self) -> &EthStateCache<ProviderBlock<N::Provider>, ProviderReceipt<N::Provider>> {
self.inner.eth_api.cache()
}
}

impl<N> EthApiSpec for OpEthApi<N>
where
N: RpcNodeCore<
N: OpNodeCore<
Provider: ChainSpecProvider<ChainSpec: EthereumHardforks>
+ BlockNumReader
+ StageCheckpointReader,
Expand All @@ -163,7 +169,7 @@ where
impl<N> SpawnBlocking for OpEthApi<N>
where
Self: Send + Sync + Clone + 'static,
N: RpcNodeCore,
N: OpNodeCore,
{
#[inline]
fn io_task_spawner(&self) -> impl TaskSpawner {
Expand All @@ -184,7 +190,7 @@ where
impl<N> LoadFee for OpEthApi<N>
where
Self: LoadBlock<Provider = N::Provider>,
N: RpcNodeCore<
N: OpNodeCore<
Provider: BlockReaderIdExt
+ EvmEnvProvider
+ ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
Expand All @@ -203,7 +209,7 @@ where
}

impl<N> LoadState for OpEthApi<N> where
N: RpcNodeCore<
N: OpNodeCore<
Provider: StateProviderFactory + ChainSpecProvider<ChainSpec: EthereumHardforks>,
Pool: TransactionPool,
>
Expand All @@ -213,7 +219,7 @@ impl<N> LoadState for OpEthApi<N> where
impl<N> EthState for OpEthApi<N>
where
Self: LoadState + SpawnBlocking,
N: RpcNodeCore,
N: OpNodeCore,
{
#[inline]
fn max_proof_window(&self) -> u64 {
Expand All @@ -224,35 +230,35 @@ where
impl<N> EthFees for OpEthApi<N>
where
Self: LoadFee,
N: RpcNodeCore,
N: OpNodeCore,
{
}

impl<N> Trace for OpEthApi<N>
where
Self: RpcNodeCore<Provider: BlockReader> + LoadState<Evm: ConfigureEvm<Header = Header>>,
N: RpcNodeCore,
N: OpNodeCore,
{
}

impl<N> AddDevSigners for OpEthApi<N>
where
N: RpcNodeCore,
N: OpNodeCore,
{
fn with_dev_accounts(&self) {
*self.inner.eth_api.signers().write() = DevSigner::random_signers(20)
}
}

impl<N: RpcNodeCore> fmt::Debug for OpEthApi<N> {
impl<N: OpNodeCore> fmt::Debug for OpEthApi<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OpEthApi").finish_non_exhaustive()
}
}

/// Container type `OpEthApi`
#[allow(missing_debug_implementations)]
struct OpEthApiInner<N: RpcNodeCore> {
struct OpEthApiInner<N: OpNodeCore> {
/// Gateway to node's core components.
eth_api: EthApiNodeBackend<N>,
/// Sequencer client, configured to forward submitted transactions to sequencer of given OP
Expand Down Expand Up @@ -285,10 +291,12 @@ impl OpEthApiBuilder {
/// Builds an instance of [`OpEthApi`]
pub fn build<N>(self, ctx: &EthApiBuilderCtx<N>) -> OpEthApi<N>
where
N: RpcNodeCore<
Provider: BlockReaderIdExt
+ ChainSpecProvider
+ CanonStateSubscriptions<Primitives = OpPrimitives>
N: OpNodeCore<
Provider: BlockReaderIdExt<
Block = <<N::Provider as NodePrimitivesProvider>::Primitives as NodePrimitives>::Block,
Receipt = <<N::Provider as NodePrimitivesProvider>::Primitives as NodePrimitives>::Receipt,
> + ChainSpecProvider
+ CanonStateSubscriptions
+ Clone
+ 'static,
>,
Expand Down
12 changes: 6 additions & 6 deletions crates/optimism/rpc/src/eth/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ use reth_primitives::{RecoveredTx, TransactionSigned};
use reth_provider::{BlockReaderIdExt, ReceiptProvider, TransactionsProvider};
use reth_rpc_eth_api::{
helpers::{EthSigner, EthTransactions, LoadTransaction, SpawnBlocking},
FromEthApiError, FullEthApiTypes, RpcNodeCore, TransactionCompat,
FromEthApiError, FullEthApiTypes, RpcNodeCore, RpcNodeCoreExt, TransactionCompat,
};
use reth_rpc_eth_types::utils::recover_raw_transaction;
use reth_transaction_pool::{PoolTransaction, TransactionOrigin, TransactionPool};

use crate::{OpEthApi, OpEthApiError, SequencerClient};
use crate::{eth::OpNodeCore, OpEthApi, OpEthApiError, SequencerClient};

impl<N> EthTransactions for OpEthApi<N>
where
Self: LoadTransaction<Provider: BlockReaderIdExt>,
N: RpcNodeCore,
N: OpNodeCore,
{
fn signers(&self) -> &parking_lot::RwLock<Vec<Box<dyn EthSigner>>> {
self.inner.eth_api.signers()
Expand Down Expand Up @@ -56,15 +56,15 @@ where

impl<N> LoadTransaction for OpEthApi<N>
where
Self: SpawnBlocking + FullEthApiTypes,
N: RpcNodeCore<Provider: TransactionsProvider, Pool: TransactionPool>,
Self: SpawnBlocking + FullEthApiTypes + RpcNodeCoreExt,
N: OpNodeCore<Provider: TransactionsProvider, Pool: TransactionPool>,
Self::Pool: TransactionPool,
{
}

impl<N> OpEthApi<N>
where
N: RpcNodeCore,
N: OpNodeCore,
{
/// Returns the [`SequencerClient`] if one is set.
pub fn raw_tx_forwarder(&self) -> Option<SequencerClient> {
Expand Down
4 changes: 2 additions & 2 deletions crates/rpc/rpc-builder/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ pub type DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, Eth

/// Handlers for core, filter and pubsub `eth` namespace APIs.
#[derive(Debug, Clone)]
pub struct EthHandlers<Provider, Pool, Network, Events, EthApi: EthApiTypes> {
pub struct EthHandlers<Provider: BlockReader, Pool, Network, Events, EthApi: EthApiTypes> {
/// Main `eth_` request handler
pub api: EthApi,
/// The async caching layer used by the eth handlers
pub cache: EthStateCache,
pub cache: EthStateCache<Provider::Block, Provider::Receipt>,
/// Polling based filter handler available on all transports
pub filter: EthFilter<Provider, Pool, EthApi>,
/// Handler for subscriptions only available for transports that support it (ws, ipc)
Expand Down
7 changes: 4 additions & 3 deletions crates/rpc/rpc-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -925,7 +925,7 @@ impl RpcModuleConfigBuilder {
/// A Helper type the holds instances of the configured modules.
#[derive(Debug, Clone)]
pub struct RpcRegistryInner<
Provider,
Provider: BlockReader,
Pool,
Network,
Tasks,
Expand Down Expand Up @@ -1029,6 +1029,7 @@ where
impl<Provider, Pool, Network, Tasks, Events, EthApi, BlockExecutor, Consensus>
RpcRegistryInner<Provider, Pool, Network, Tasks, Events, EthApi, BlockExecutor, Consensus>
where
Provider: BlockReader,
EthApi: EthApiTypes,
{
/// Returns a reference to the installed [`EthApi`](reth_rpc::eth::EthApi).
Expand All @@ -1045,7 +1046,7 @@ where
///
/// This will spawn exactly one [`EthStateCache`] service if this is the first time the cache is
/// requested.
pub const fn eth_cache(&self) -> &EthStateCache {
pub const fn eth_cache(&self) -> &EthStateCache<Provider::Block, Provider::Receipt> {
&self.eth.cache
}

Expand Down Expand Up @@ -1089,7 +1090,7 @@ impl<Provider, Pool, Network, Tasks, Events, EthApi, BlockExecutor, Consensus>
where
Network: NetworkInfo + Clone + 'static,
EthApi: EthApiTypes,
Provider: ChainSpecProvider<ChainSpec: EthereumHardforks>,
Provider: BlockReader + ChainSpecProvider<ChainSpec: EthereumHardforks>,
BlockExecutor: BlockExecutorProvider,
{
/// Instantiates `AdminApi`
Expand Down
Loading

0 comments on commit b4124dd

Please sign in to comment.