chore: add OpEthApiBuilder and OpEthApiInner (#13009)

This commit is contained in:
joshieDo
2024-12-02 14:56:55 +00:00
committed by GitHub
parent 332cce1f9b
commit 6789ff4a1e
11 changed files with 145 additions and 69 deletions

1
Cargo.lock generated
View File

@ -8483,7 +8483,6 @@ dependencies = [
"alloy-primitives",
"alloy-rpc-types-debug",
"alloy-rpc-types-eth",
"derive_more 1.0.0",
"jsonrpsee-core",
"jsonrpsee-types",
"op-alloy-consensus",

View File

@ -3,9 +3,9 @@
#![cfg(feature = "optimism")]
use clap::Parser;
use reth_node_builder::{engine_tree_config::TreeConfig, EngineNodeLauncher};
use reth_node_builder::{engine_tree_config::TreeConfig, EngineNodeLauncher, Node};
use reth_optimism_cli::{chainspec::OpChainSpecParser, Cli};
use reth_optimism_node::{args::RollupArgs, node::OpAddOns, OpNode};
use reth_optimism_node::{args::RollupArgs, OpNode};
use reth_provider::providers::BlockchainProvider2;
use tracing as _;
@ -27,7 +27,6 @@ fn main() {
tracing::warn!(target: "reth::cli", "Experimental engine is default now, and the --engine.experimental flag is deprecated. To enable the legacy functionality, use --engine.legacy.");
}
let use_legacy_engine = rollup_args.legacy;
let sequencer_http_arg = rollup_args.sequencer_http.clone();
match use_legacy_engine {
false => {
let engine_tree_config = TreeConfig::default()
@ -35,8 +34,8 @@ fn main() {
.with_memory_block_buffer_target(rollup_args.memory_block_buffer_target);
let handle = builder
.with_types_and_provider::<OpNode, BlockchainProvider2<_>>()
.with_components(OpNode::components(rollup_args))
.with_add_ons(OpAddOns::new(sequencer_http_arg))
.with_components(OpNode::components(rollup_args.clone()))
.with_add_ons(OpNode::new(rollup_args).add_ons())
.launch_with_fn(|builder| {
let launcher = EngineNodeLauncher::new(
builder.task_executor().clone(),

View File

@ -31,7 +31,7 @@ use reth_optimism_payload_builder::builder::OpPayloadTransactions;
use reth_optimism_primitives::OpPrimitives;
use reth_optimism_rpc::{
witness::{DebugExecutionWitnessApiServer, OpDebugWitnessApi},
OpEthApi,
OpEthApi, SequencerClient,
};
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
use reth_primitives::BlockBody;
@ -178,12 +178,11 @@ where
OpAddOns<NodeAdapter<N, <Self::ComponentsBuilder as NodeComponentsBuilder<N>>::Components>>;
fn components_builder(&self) -> Self::ComponentsBuilder {
let Self { args } = self;
Self::components(args.clone())
Self::components(self.args.clone())
}
fn add_ons(&self) -> Self::AddOns {
OpAddOns::new(self.args.sequencer_http.clone())
Self::AddOns::builder().with_sequencer(self.args.sequencer_http.clone()).build()
}
}
@ -204,14 +203,14 @@ pub struct OpAddOns<N: FullNodeComponents>(pub RpcAddOns<N, OpEthApi<N>, OpEngin
impl<N: FullNodeComponents<Types: NodeTypes<Primitives = OpPrimitives>>> Default for OpAddOns<N> {
fn default() -> Self {
Self::new(None)
Self::builder().build()
}
}
impl<N: FullNodeComponents<Types: NodeTypes<Primitives = OpPrimitives>>> OpAddOns<N> {
/// Create a new instance with the given `sequencer_http` URL.
pub fn new(sequencer_http: Option<String>) -> Self {
Self(RpcAddOns::new(move |ctx| OpEthApi::new(ctx, sequencer_http), Default::default()))
/// Build a [`OpAddOns`] using [`OpAddOnsBuilder`].
pub fn builder() -> OpAddOnsBuilder {
OpAddOnsBuilder::default()
}
}
@ -270,6 +269,38 @@ where
}
}
/// A regular optimism evm and executor builder.
#[derive(Debug, Default, Clone)]
#[non_exhaustive]
pub struct OpAddOnsBuilder {
/// Sequencer client, configured to forward submitted transactions to sequencer of given OP
/// network.
sequencer_client: Option<SequencerClient>,
}
impl OpAddOnsBuilder {
/// With a [`SequencerClient`].
pub fn with_sequencer(mut self, sequencer_client: Option<String>) -> Self {
self.sequencer_client = sequencer_client.map(SequencerClient::new);
self
}
}
impl OpAddOnsBuilder {
/// Builds an instance of [`OpAddOns`].
pub fn build<N>(self) -> OpAddOns<N>
where
N: FullNodeComponents<Types: NodeTypes<Primitives = OpPrimitives>>,
{
let Self { sequencer_client, .. } = self;
OpAddOns(RpcAddOns::new(
move |ctx| OpEthApi::<N>::builder().with_sequencer(sequencer_client).build(ctx),
Default::default(),
))
}
}
/// A regular optimism evm and executor builder.
#[derive(Debug, Default, Clone, Copy)]
#[non_exhaustive]

View File

@ -2,20 +2,21 @@
use reth_db::test_utils::create_test_rw_db;
use reth_node_api::FullNodeComponents;
use reth_node_builder::{NodeBuilder, NodeConfig};
use reth_node_builder::{Node, NodeBuilder, NodeConfig};
use reth_optimism_chainspec::BASE_MAINNET;
use reth_optimism_node::{node::OpAddOns, OpNode};
use reth_optimism_node::{args::RollupArgs, OpNode};
#[test]
fn test_basic_setup() {
// parse CLI -> config
let config = NodeConfig::new(BASE_MAINNET.clone());
let db = create_test_rw_db();
let args = RollupArgs::default();
let _builder = NodeBuilder::new(config)
.with_database(db)
.with_types::<OpNode>()
.with_components(OpNode::components(Default::default()))
.with_add_ons(OpAddOns::new(None))
.with_components(OpNode::components(args.clone()))
.with_add_ons(OpNode::new(args).add_ons())
.on_component_initialized(move |ctx| {
let _provider = ctx.provider();
Ok(())

View File

@ -61,7 +61,6 @@ serde_json.workspace = true
# misc
thiserror.workspace = true
tracing.workspace = true
derive_more = { workspace = true, features = ["constructor", "deref"] }
[dev-dependencies]
reth-optimism-chainspec.workspace = true

View File

@ -57,7 +57,7 @@ where
};
Ok(OpReceiptBuilder::new(
&self.inner.provider().chain_spec(),
&self.inner.eth_api.provider().chain_spec(),
tx,
meta,
receipt,

View File

@ -33,12 +33,12 @@ where
{
#[inline]
fn call_gas_limit(&self) -> u64 {
self.inner.gas_cap()
self.inner.eth_api.gas_cap()
}
#[inline]
fn max_simulate_blocks(&self) -> u64 {
self.inner.max_simulate_blocks()
self.inner.eth_api.max_simulate_blocks()
}
fn create_txn_env(

View File

@ -14,7 +14,6 @@ use std::{fmt, sync::Arc};
use alloy_consensus::Header;
use alloy_primitives::U256;
use derive_more::Deref;
use op_alloy_network::Optimism;
use reth_chainspec::{EthChainSpec, EthereumHardforks};
use reth_evm::ConfigureEvm;
@ -59,14 +58,10 @@ 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(Deref, Clone)]
#[derive(Clone)]
pub struct OpEthApi<N: RpcNodeCore> {
/// Gateway to node's core components.
#[deref]
inner: Arc<EthApiNodeBackend<N>>,
/// Sequencer client, configured to forward submitted transactions to sequencer of given OP
/// network.
sequencer_client: Option<SequencerClient>,
inner: Arc<OpEthApiInner<N>>,
}
impl<N> OpEthApi<N>
@ -79,28 +74,9 @@ where
+ 'static,
>,
{
/// Creates a new instance for given context.
pub fn new(ctx: &EthApiBuilderCtx<N>, sequencer_http: Option<String>) -> Self {
let blocking_task_pool =
BlockingTaskPool::build().expect("failed to build blocking task pool");
let inner = EthApiInner::new(
ctx.provider.clone(),
ctx.pool.clone(),
ctx.network.clone(),
ctx.cache.clone(),
ctx.new_gas_price_oracle(),
ctx.config.rpc_gas_cap,
ctx.config.rpc_max_simulate_blocks,
ctx.config.eth_proof_window,
blocking_task_pool,
ctx.new_fee_history_cache(),
ctx.evm_config.clone(),
ctx.executor.clone(),
ctx.config.proof_permits,
);
Self { inner: Arc::new(inner), sequencer_client: sequencer_http.map(SequencerClient::new) }
/// Build a [`OpEthApi`] using [`OpEthApiBuilder`].
pub const fn builder() -> OpEthApiBuilder {
OpEthApiBuilder::new()
}
}
@ -130,17 +106,17 @@ where
#[inline]
fn pool(&self) -> &Self::Pool {
self.inner.pool()
self.inner.eth_api.pool()
}
#[inline]
fn evm_config(&self) -> &Self::Evm {
self.inner.evm_config()
self.inner.eth_api.evm_config()
}
#[inline]
fn network(&self) -> &Self::Network {
self.inner.network()
self.inner.eth_api.network()
}
#[inline]
@ -150,7 +126,7 @@ where
#[inline]
fn provider(&self) -> &Self::Provider {
self.inner.provider()
self.inner.eth_api.provider()
}
}
@ -160,7 +136,7 @@ where
{
#[inline]
fn cache(&self) -> &EthStateCache {
self.inner.cache()
self.inner.eth_api.cache()
}
}
@ -175,12 +151,12 @@ where
{
#[inline]
fn starting_block(&self) -> U256 {
self.inner.starting_block()
self.inner.eth_api.starting_block()
}
#[inline]
fn signers(&self) -> &parking_lot::RwLock<Vec<Box<dyn EthSigner>>> {
self.inner.signers()
self.inner.eth_api.signers()
}
}
@ -191,17 +167,17 @@ where
{
#[inline]
fn io_task_spawner(&self) -> impl TaskSpawner {
self.inner.task_spawner()
self.inner.eth_api.task_spawner()
}
#[inline]
fn tracing_task_pool(&self) -> &BlockingTaskPool {
self.inner.blocking_task_pool()
self.inner.eth_api.blocking_task_pool()
}
#[inline]
fn tracing_task_guard(&self) -> &BlockingTaskGuard {
self.inner.blocking_task_guard()
self.inner.eth_api.blocking_task_guard()
}
}
@ -217,12 +193,12 @@ where
{
#[inline]
fn gas_oracle(&self) -> &GasPriceOracle<Self::Provider> {
self.inner.gas_oracle()
self.inner.eth_api.gas_oracle()
}
#[inline]
fn fee_history_cache(&self) -> &FeeHistoryCache {
self.inner.fee_history_cache()
self.inner.eth_api.fee_history_cache()
}
}
@ -241,7 +217,7 @@ where
{
#[inline]
fn max_proof_window(&self) -> u64 {
self.inner.eth_proof_window()
self.inner.eth_api.eth_proof_window()
}
}
@ -264,7 +240,7 @@ where
N: RpcNodeCore,
{
fn with_dev_accounts(&self) {
*self.inner.signers().write() = DevSigner::random_signers(20)
*self.inner.eth_api.signers().write() = DevSigner::random_signers(20)
}
}
@ -273,3 +249,71 @@ impl<N: RpcNodeCore> fmt::Debug for OpEthApi<N> {
f.debug_struct("OpEthApi").finish_non_exhaustive()
}
}
/// Container type `OpEthApi`
#[allow(missing_debug_implementations)]
struct OpEthApiInner<N: RpcNodeCore> {
/// Gateway to node's core components.
eth_api: EthApiNodeBackend<N>,
/// Sequencer client, configured to forward submitted transactions to sequencer of given OP
/// network.
sequencer_client: Option<SequencerClient>,
}
/// A type that knows how to build a [`OpEthApi`].
#[derive(Debug, Default)]
pub struct OpEthApiBuilder {
/// Sequencer client, configured to forward submitted transactions to sequencer of given OP
/// network.
sequencer_client: Option<SequencerClient>,
}
impl OpEthApiBuilder {
/// Creates a [`OpEthApiBuilder`] instance from [`EthApiBuilderCtx`].
pub const fn new() -> Self {
Self { sequencer_client: None }
}
/// With a [`SequencerClient`].
pub fn with_sequencer(mut self, sequencer_client: Option<SequencerClient>) -> Self {
self.sequencer_client = sequencer_client;
self
}
}
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>
+ Clone
+ 'static,
>,
{
let blocking_task_pool =
BlockingTaskPool::build().expect("failed to build blocking task pool");
let eth_api = EthApiInner::new(
ctx.provider.clone(),
ctx.pool.clone(),
ctx.network.clone(),
ctx.cache.clone(),
ctx.new_gas_price_oracle(),
ctx.config.rpc_gas_cap,
ctx.config.rpc_max_simulate_blocks,
ctx.config.eth_proof_window,
blocking_task_pool,
ctx.new_fee_history_cache(),
ctx.evm_config.clone(),
ctx.executor.clone(),
ctx.config.proof_permits,
);
OpEthApi {
inner: Arc::new(OpEthApiInner { eth_api, sequencer_client: self.sequencer_client }),
}
}
}

View File

@ -37,7 +37,7 @@ where
{
#[inline]
fn pending_block(&self) -> &tokio::sync::Mutex<Option<PendingBlock>> {
self.inner.pending_block()
self.inner.eth_api.pending_block()
}
/// Returns the locally built pending block

View File

@ -31,6 +31,8 @@ where
receipt: Receipt,
) -> Result<RpcReceipt<Self::NetworkTypes>, Self::Error> {
let (block, receipts) = self
.inner
.eth_api
.cache()
.get_block_and_receipts(meta.block_hash)
.await
@ -43,7 +45,7 @@ where
reth_optimism_evm::extract_l1_info(&block.body).map_err(OpEthApiError::from)?;
Ok(OpReceiptBuilder::new(
&self.inner.provider().chain_spec(),
&self.inner.eth_api.provider().chain_spec(),
&tx,
meta,
&receipt,

View File

@ -23,7 +23,7 @@ where
N: RpcNodeCore,
{
fn signers(&self) -> &parking_lot::RwLock<Vec<Box<dyn EthSigner>>> {
self.inner.signers()
self.inner.eth_api.signers()
}
/// Decodes and recovers the transaction and submits it to the pool.
@ -68,7 +68,7 @@ where
{
/// Returns the [`SequencerClient`] if one is set.
pub fn raw_tx_forwarder(&self) -> Option<SequencerClient> {
self.sequencer_client.clone()
self.inner.sequencer_client.clone()
}
}
@ -106,6 +106,7 @@ where
}
reth_primitives::Transaction::Deposit(tx) => {
self.inner
.eth_api
.provider()
.receipt_by_hash(hash)
.map_err(Self::Error::from_eth_err)?