reth_seismic_rpc/eth/
mod.rs

1//! Seismic-Reth `eth_` endpoint implementation.
2
3pub mod api;
4pub mod ext;
5pub mod receipt;
6pub mod transaction;
7pub mod utils;
8
9mod block;
10mod call;
11mod pending_block;
12
13use alloy_primitives::U256;
14use reth_chain_state::CanonStateSubscriptions;
15use reth_chainspec::{ChainSpecProvider, EthChainSpec, EthereumHardforks};
16use reth_evm::ConfigureEvm;
17use reth_network_api::NetworkInfo;
18use reth_node_api::{FullNodeComponents, NodePrimitives};
19use reth_node_builder::rpc::{EthApiBuilder, EthApiCtx};
20use reth_rpc::eth::{core::EthApiInner, DevSigner};
21use reth_rpc_eth_api::{
22    helpers::{
23        AddDevSigners, EthApiSpec, EthFees, EthSigner, EthState, LoadBlock, LoadFee, LoadState,
24        SpawnBlocking, Trace,
25    },
26    EthApiTypes, FromEvmError, FullEthApiServer, RpcNodeCore, RpcNodeCoreExt,
27};
28use reth_rpc_eth_types::{EthApiError, EthStateCache, FeeHistoryCache, GasPriceOracle};
29use reth_seismic_primitives::SeismicPrimitives;
30use reth_storage_api::{
31    BlockNumReader, BlockReader, BlockReaderIdExt, ProviderBlock, ProviderHeader, ProviderReceipt,
32    ProviderTx, StageCheckpointReader, StateProviderFactory,
33};
34use reth_tasks::{
35    pool::{BlockingTaskGuard, BlockingTaskPool},
36    TaskSpawner,
37};
38use reth_transaction_pool::TransactionPool;
39use seismic_alloy_network::Seismic;
40use std::{fmt, sync::Arc};
41
42/// Adapter for [`EthApiInner`], which holds all the data required to serve core `eth_` API.
43pub type EthApiNodeBackend<N> = EthApiInner<
44    <N as RpcNodeCore>::Provider,
45    <N as RpcNodeCore>::Pool,
46    <N as RpcNodeCore>::Network,
47    <N as RpcNodeCore>::Evm,
48>;
49
50/// A helper trait with requirements for [`RpcNodeCore`] to be used in [`SeismicEthApi`].
51pub trait SeismicNodeCore: RpcNodeCore<Provider: BlockReader> {}
52impl<T> SeismicNodeCore for T where T: RpcNodeCore<Provider: BlockReader> {}
53
54/// seismic-reth `Eth` API implementation.
55#[derive(Clone)]
56pub struct SeismicEthApi<N: SeismicNodeCore> {
57    /// Inner `Eth` API implementation.
58    pub inner: Arc<EthApiInner<N::Provider, N::Pool, N::Network, N::Evm>>,
59}
60
61impl<N> SeismicEthApi<N>
62where
63    N: SeismicNodeCore<
64        Provider: BlockReaderIdExt
65                      + ChainSpecProvider
66                      + CanonStateSubscriptions<Primitives = SeismicPrimitives>
67                      + Clone
68                      + 'static,
69    >,
70{
71    /// Returns a reference to the [`EthApiNodeBackend`].
72    pub fn eth_api(&self) -> &EthApiNodeBackend<N> {
73        &self.inner
74    }
75
76    /// Build a [`SeismicEthApi`] using [`SeismicEthApiBuilder`].
77    pub const fn builder() -> SeismicEthApiBuilder {
78        SeismicEthApiBuilder::new()
79    }
80}
81
82impl<N> EthApiTypes for SeismicEthApi<N>
83where
84    Self: Send + Sync,
85    N: SeismicNodeCore,
86{
87    type Error = EthApiError;
88    type NetworkTypes = Seismic;
89    type TransactionCompat = Self;
90
91    fn tx_resp_builder(&self) -> &Self::TransactionCompat {
92        self
93    }
94}
95
96impl<N> RpcNodeCore for SeismicEthApi<N>
97where
98    N: SeismicNodeCore,
99{
100    type Primitives = SeismicPrimitives;
101    type Provider = N::Provider;
102    type Pool = N::Pool;
103    type Evm = <N as RpcNodeCore>::Evm;
104    type Network = <N as RpcNodeCore>::Network;
105    type PayloadBuilder = ();
106
107    #[inline]
108    fn pool(&self) -> &Self::Pool {
109        self.inner.pool()
110    }
111
112    #[inline]
113    fn evm_config(&self) -> &Self::Evm {
114        self.inner.evm_config()
115    }
116
117    #[inline]
118    fn network(&self) -> &Self::Network {
119        self.inner.network()
120    }
121
122    #[inline]
123    fn payload_builder(&self) -> &Self::PayloadBuilder {
124        &()
125    }
126
127    #[inline]
128    fn provider(&self) -> &Self::Provider {
129        self.inner.provider()
130    }
131}
132
133impl<N> RpcNodeCoreExt for SeismicEthApi<N>
134where
135    N: SeismicNodeCore,
136{
137    #[inline]
138    fn cache(&self) -> &EthStateCache<ProviderBlock<N::Provider>, ProviderReceipt<N::Provider>> {
139        self.inner.cache()
140    }
141}
142
143impl<N> EthApiSpec for SeismicEthApi<N>
144where
145    N: SeismicNodeCore<
146        Provider: ChainSpecProvider<ChainSpec: EthereumHardforks>
147                      + BlockNumReader
148                      + StageCheckpointReader,
149        Network: NetworkInfo,
150    >,
151{
152    type Transaction = ProviderTx<Self::Provider>;
153
154    #[inline]
155    fn starting_block(&self) -> U256 {
156        self.inner.starting_block()
157    }
158
159    #[inline]
160    fn signers(&self) -> &parking_lot::RwLock<Vec<Box<dyn EthSigner<ProviderTx<Self::Provider>>>>> {
161        self.inner.signers()
162    }
163}
164
165impl<N> SpawnBlocking for SeismicEthApi<N>
166where
167    Self: Send + Sync + Clone + 'static,
168    N: RpcNodeCore<Provider: BlockReader>,
169{
170    #[inline]
171    fn io_task_spawner(&self) -> impl TaskSpawner {
172        self.inner.task_spawner()
173    }
174
175    #[inline]
176    fn tracing_task_pool(&self) -> &BlockingTaskPool {
177        self.inner.blocking_task_pool()
178    }
179
180    #[inline]
181    fn tracing_task_guard(&self) -> &BlockingTaskGuard {
182        self.inner.blocking_task_guard()
183    }
184}
185
186impl<N> LoadFee for SeismicEthApi<N>
187where
188    Self: LoadBlock<Provider = N::Provider>,
189    N: SeismicNodeCore<
190        Provider: BlockReaderIdExt
191                      + ChainSpecProvider<ChainSpec: EthChainSpec + EthereumHardforks>
192                      + StateProviderFactory,
193    >,
194{
195    #[inline]
196    fn gas_oracle(&self) -> &GasPriceOracle<Self::Provider> {
197        self.inner.gas_oracle()
198    }
199
200    #[inline]
201    fn fee_history_cache(&self) -> &FeeHistoryCache {
202        self.inner.fee_history_cache()
203    }
204}
205
206impl<N> LoadState for SeismicEthApi<N> where
207    N: SeismicNodeCore<
208        Provider: StateProviderFactory + ChainSpecProvider<ChainSpec: EthereumHardforks>,
209        Pool: TransactionPool,
210    >
211{
212}
213
214impl<N> EthState for SeismicEthApi<N>
215where
216    Self: LoadState + SpawnBlocking,
217    N: SeismicNodeCore,
218{
219    #[inline]
220    fn max_proof_window(&self) -> u64 {
221        self.inner.eth_proof_window()
222    }
223}
224
225impl<N> EthFees for SeismicEthApi<N>
226where
227    Self: LoadFee,
228    N: SeismicNodeCore,
229{
230}
231
232impl<N> Trace for SeismicEthApi<N>
233where
234    Self: RpcNodeCore<Provider: BlockReader>
235        + LoadState<
236            Evm: ConfigureEvm<
237                Primitives: NodePrimitives<
238                    BlockHeader = ProviderHeader<Self::Provider>,
239                    SignedTx = ProviderTx<Self::Provider>,
240                >,
241            >,
242            Error: FromEvmError<Self::Evm>,
243        >,
244    N: SeismicNodeCore,
245{
246}
247
248impl<N> AddDevSigners for SeismicEthApi<N>
249where
250    N: SeismicNodeCore,
251{
252    fn with_dev_accounts(&self) {
253        *self.inner.signers().write() = DevSigner::random_signers(20)
254    }
255}
256
257impl<N: SeismicNodeCore> fmt::Debug for SeismicEthApi<N> {
258    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
259        f.debug_struct("SeismicEthApi").finish_non_exhaustive()
260    }
261}
262
263/// Builds [`SeismicEthApi`] for Optimism.
264#[derive(Debug, Default)]
265pub struct SeismicEthApiBuilder {}
266
267impl SeismicEthApiBuilder {
268    /// Creates a [`SeismicEthApiBuilder`] instance from core components.
269    pub const fn new() -> Self {
270        SeismicEthApiBuilder {}
271    }
272}
273
274impl<N> EthApiBuilder<N> for SeismicEthApiBuilder
275where
276    N: FullNodeComponents,
277    SeismicEthApi<N>: FullEthApiServer<Provider = N::Provider, Pool = N::Pool>,
278{
279    type EthApi = SeismicEthApi<N>;
280
281    async fn build_eth_api(self, ctx: EthApiCtx<'_, N>) -> eyre::Result<Self::EthApi> {
282        let eth_api = reth_rpc::EthApiBuilder::new(
283            ctx.components.provider().clone(),
284            ctx.components.pool().clone(),
285            ctx.components.network().clone(),
286            ctx.components.evm_config().clone(),
287        )
288        .eth_cache(ctx.cache)
289        .task_spawner(ctx.components.task_executor().clone())
290        .gas_cap(ctx.config.rpc_gas_cap.into())
291        .max_simulate_blocks(ctx.config.rpc_max_simulate_blocks)
292        .eth_proof_window(ctx.config.eth_proof_window)
293        .fee_history_cache_config(ctx.config.fee_history_cache)
294        .proof_permits(ctx.config.proof_permits)
295        .build_inner();
296
297        Ok(SeismicEthApi { inner: Arc::new(eth_api) })
298    }
299}