Skip to content
Draft
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
6 changes: 5 additions & 1 deletion crates/e2e-test-utils/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,11 @@ where
where
AddOns::EthApi: EthApiSpec<Provider: BlockReader<Block = BlockTy<Node::Types>>>
+ EthTransactions
+ TraceExt,
+ TraceExt
+ reth_rpc_eth_api::RpcNodeCore<
Provider = Node::Provider,
Primitives = <Node::Types as NodeTypes>::Primitives,
>,
{
let mut chain = Vec::with_capacity(length as usize);
for i in 0..length {
Expand Down
5 changes: 3 additions & 2 deletions crates/e2e-test-utils/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use reth_provider::BlockReader;
use reth_rpc_api::DebugApiServer;
use reth_rpc_eth_api::{
helpers::{EthApiSpec, EthTransactions, TraceExt},
EthApiTypes,
EthApiTypes, RpcNodeCore,
};

#[expect(missing_debug_implementations)]
Expand All @@ -22,7 +22,8 @@ where
Node: FullNodeComponents<Types: NodeTypes<ChainSpec: EthereumHardforks>>,
EthApi: EthApiSpec<Provider: BlockReader<Block = BlockTy<Node::Types>>>
+ EthTransactions
+ TraceExt,
+ TraceExt
+ RpcNodeCore<Provider = Node::Provider, Primitives = <Node::Types as NodeTypes>::Primitives>,
{
/// Injects a raw transaction into the node tx pool via RPC server
pub async fn inject_tx(&self, raw_tx: Bytes) -> Result<B256, EthApi::Error> {
Expand Down
19 changes: 17 additions & 2 deletions crates/node/builder/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ use reth_node_core::{
};
use reth_payload_builder::{PayloadBuilderHandle, PayloadStore};
use reth_rpc::{
eth::{core::EthRpcConverterFor, DevSigner, EthApiTypes, FullEthApiServer},
eth::{core::EthRpcConverterFor, DevSigner, EthApiTypes, FullEthApiServer, RpcNodeCore},
AdminApi,
};
use reth_rpc_api::{eth::helpers::EthTransactions, IntoEngineApiRpcModule};
use reth_rpc_builder::{
auth::{AuthRpcModule, AuthServerHandle},
config::RethRpcServerConfig,
RpcModuleBuilder, RpcRegistryInner, RpcServerConfig, RpcServerHandle, TransportRpcModules,
RethRpcModule, RpcModuleBuilder, RpcRegistryInner, RpcServerConfig, RpcServerHandle,
TransportRpcModules,
};
use reth_rpc_engine_api::{capabilities::EngineCapabilities, EngineApi};
use reth_rpc_eth_types::{cache::cache_new_blocks_task, EthConfig, EthStateCache};
Expand Down Expand Up @@ -1001,6 +1002,11 @@ where

let auth_config = config.rpc.auth_server_config(jwt_secret)?;
let module_config = config.rpc.transport_rpc_module_config();
// Only start collecting bad blocks if the debug_ endpoint installed
let debug_enabled =
module_config.http().is_some_and(|sel| sel.contains(&RethRpcModule::Debug)) ||
module_config.ws().is_some_and(|sel| sel.contains(&RethRpcModule::Debug)) ||
module_config.ipc().is_some_and(|sel| sel.contains(&RethRpcModule::Debug));
debug!(target: "reth::cli", http=?module_config.http(), ws=?module_config.ws(), "Using RPC module config");

let (mut modules, mut auth_module, registry) = RpcModuleBuilder::default()
Expand All @@ -1018,6 +1024,14 @@ where
registry.eth_api().signers().write().extend(signers);
}

// keep track of invalid blocks for `debug_getBadBlocks` only if debug RPC is enabled
if debug_enabled {
registry.debug_api().spawn_invalid_block_listener(
engine_events.new_listener(),
node.task_executor().clone(),
);
}

let mut registry = RpcRegistry { registry };
let ctx = RpcContext {
node: node.clone(),
Expand Down Expand Up @@ -1189,6 +1203,7 @@ impl<'a, N: FullNodeComponents<Types: NodeTypes<ChainSpec: Hardforks + EthereumH
pub trait EthApiBuilder<N: FullNodeComponents>: Default + Send + 'static {
/// The Ethapi implementation this builder will build.
type EthApi: EthApiTypes
+ RpcNodeCore<Primitives = PrimitivesTy<N::Types>>
+ FullEthApiServer<Provider = N::Provider, Pool = N::Pool>
+ Unpin
+ 'static;
Expand Down
6 changes: 3 additions & 3 deletions crates/optimism/rpc/src/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub use receipt::{OpReceiptBuilder, OpReceiptFieldsBuilder};
use reqwest::Url;
use reth_chainspec::{EthereumHardforks, Hardforks};
use reth_evm::ConfigureEvm;
use reth_node_api::{FullNodeComponents, FullNodeTypes, HeaderTy, NodeTypes};
use reth_node_api::{FullNodeComponents, FullNodeTypes, HeaderTy, NodeTypes, PrimitivesTy};
use reth_node_builder::rpc::{EthApiBuilder, EthApiCtx};
use reth_optimism_flashblocks::{
FlashBlockBuildInfo, FlashBlockCompleteSequence, FlashBlockCompleteSequenceRx,
Expand Down Expand Up @@ -487,8 +487,8 @@ where
>,
NetworkT: RpcTypes,
OpRpcConvert<N, NetworkT>: RpcConvert<Network = NetworkT>,
OpEthApi<N, OpRpcConvert<N, NetworkT>>:
FullEthApiServer<Provider = N::Provider, Pool = N::Pool>,
OpEthApi<N, OpRpcConvert<N, NetworkT>>: FullEthApiServer<Provider = N::Provider, Pool = N::Pool>
+ RpcNodeCore<Primitives = PrimitivesTy<N::Types>>,
{
type EthApi = OpEthApi<N, OpRpcConvert<N, NetworkT>>;

Expand Down
4 changes: 2 additions & 2 deletions crates/rpc/rpc-api/src/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use alloy_genesis::ChainConfig;
use alloy_json_rpc::RpcObject;
use alloy_primitives::{Address, Bytes, B256};
use alloy_rpc_types_debug::ExecutionWitness;
use alloy_rpc_types_eth::{Block, Bundle, StateContext};
use alloy_rpc_types_eth::{BadBlock, Bundle, StateContext};
use alloy_rpc_types_trace::geth::{
BlockTraceResult, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, TraceResult,
};
Expand Down Expand Up @@ -38,7 +38,7 @@ pub trait DebugApi<TxReq: RpcObject> {

/// Returns an array of recent bad blocks that the client has seen on the network.
#[method(name = "getBadBlocks")]
async fn bad_blocks(&self) -> RpcResult<Vec<Block>>;
async fn bad_blocks(&self) -> RpcResult<Vec<BadBlock>>;

/// Returns the structured logs created during the execution of EVM between two blocks
/// (excluding start) as a JSON object.
Expand Down
56 changes: 38 additions & 18 deletions crates/rpc/rpc-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ use reth_evm::ConfigureEvm;
use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers};
use reth_primitives_traits::{NodePrimitives, TxTy};
use reth_rpc::{
AdminApi, DebugApi, EngineEthApi, EthApi, EthApiBuilder, EthBundle, MinerApi, NetApi,
OtterscanApi, RPCApi, RethApi, TraceApi, TxPoolApi, ValidationApiConfig, Web3Api,
AdminApi, BadBlockStore, DebugApi, EngineEthApi, EthApi, EthApiBuilder, EthBundle, MinerApi,
NetApi, OtterscanApi, RPCApi, RethApi, TraceApi, TxPoolApi, ValidationApiConfig, Web3Api,
};
use reth_rpc_api::servers::*;
use reth_rpc_eth_api::{
Expand All @@ -52,8 +52,7 @@ use reth_rpc_eth_api::{
use reth_rpc_eth_types::{receipt::EthReceiptConverter, EthConfig, EthSubscriptionIdProvider};
use reth_rpc_layer::{AuthLayer, Claims, CompressionLayer, JwtAuthValidator, JwtSecret};
use reth_storage_api::{
AccountReader, BlockReader, ChangeSetReader, FullRpcProvider, ProviderBlock,
StateProviderFactory,
AccountReader, BlockReader, ChangeSetReader, FullRpcProvider, StateProviderFactory,
};
use reth_tasks::{pool::BlockingTaskGuard, TaskSpawner, TokioTaskExecutor};
use reth_transaction_pool::{noop::NoopTransactionPool, TransactionPool};
Expand Down Expand Up @@ -332,7 +331,8 @@ where
RpcRegistryInner<Provider, Pool, Network, EthApi, EvmConfig, Consensus>,
)
where
EthApi: FullEthApiServer<Provider = Provider, Pool = Pool>,
EthApi: FullEthApiServer<Provider = Provider, Pool = Pool>
+ RpcNodeCore<Provider = Provider, Primitives = N>,
{
let Self { provider, pool, network, executor, consensus, evm_config, .. } = self;

Expand All @@ -359,7 +359,7 @@ where
eth: EthApi,
) -> RpcRegistryInner<Provider, Pool, Network, EthApi, EvmConfig, Consensus>
where
EthApi: EthApiTypes + 'static,
EthApi: EthApiTypes + RpcNodeCore<Provider = Provider, Primitives = N> + 'static,
{
let Self { provider, pool, network, executor, consensus, evm_config, .. } = self;
RpcRegistryInner::new(provider, pool, network, executor, consensus, config, evm_config, eth)
Expand All @@ -373,7 +373,8 @@ where
eth: EthApi,
) -> TransportRpcModules<()>
where
EthApi: FullEthApiServer<Provider = Provider, Pool = Pool>,
EthApi: FullEthApiServer<Provider = Provider, Pool = Pool>
+ RpcNodeCore<Provider = Provider, Primitives = N>,
{
let mut modules = TransportRpcModules::default();

Expand Down Expand Up @@ -511,6 +512,8 @@ pub struct RpcRegistryInner<
modules: HashMap<RethRpcModule, Methods>,
/// eth config settings
eth_config: EthConfig,
/// Recent bad blocks observed by the node.
bad_block_store: BadBlockStore<Provider::Block>,
}

// === impl RpcRegistryInner ===
Expand All @@ -527,7 +530,7 @@ where
+ 'static,
Pool: Send + Sync + Clone + 'static,
Network: Clone + 'static,
EthApi: EthApiTypes + 'static,
EthApi: EthApiTypes + RpcNodeCore<Provider = Provider, Primitives = N> + 'static,
EvmConfig: ConfigureEvm<Primitives = N>,
{
/// Creates a new, empty instance.
Expand Down Expand Up @@ -560,6 +563,7 @@ where
blocking_pool_guard,
eth_config: config.eth,
evm_config,
bad_block_store: BadBlockStore::default(),
}
}
}
Expand Down Expand Up @@ -595,6 +599,11 @@ where
&self.provider
}

/// Returns the bad block store.
pub const fn bad_block_store(&self) -> &BadBlockStore<Provider::Block> {
&self.bad_block_store
}

/// Returns all installed methods
pub fn methods(&self) -> Vec<Methods> {
self.modules.values().cloned().collect()
Expand Down Expand Up @@ -706,8 +715,10 @@ where
/// If called outside of the tokio runtime. See also [`Self::eth_api`]
pub fn register_debug(&mut self) -> &mut Self
where
EthApi: EthApiSpec + EthTransactions + TraceExt,
EvmConfig::Primitives: NodePrimitives<Block = ProviderBlock<EthApi::Provider>>,
EthApi: EthApiSpec
+ EthTransactions
+ TraceExt
+ RpcNodeCore<Provider = Provider, Primitives = N>,
{
let debug_api = self.debug_api();
self.modules.insert(RethRpcModule::Debug, debug_api.into_rpc().into());
Expand Down Expand Up @@ -814,8 +825,15 @@ where
/// # Panics
///
/// If called outside of the tokio runtime. See also [`Self::eth_api`]
pub fn debug_api(&self) -> DebugApi<EthApi> {
DebugApi::new(self.eth_api().clone(), self.blocking_pool_guard.clone())
pub fn debug_api(&self) -> DebugApi<EthApi>
where
EthApi: EthApiTypes + RpcNodeCore<Provider = Provider, Primitives = N>,
{
DebugApi::new(
self.eth_api().clone(),
self.blocking_pool_guard.clone(),
self.bad_block_store.clone(),
)
}

/// Instantiates `NetApi`
Expand Down Expand Up @@ -847,7 +865,7 @@ where
+ ChangeSetReader,
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
EthApi: FullEthApiServer,
EthApi: FullEthApiServer + RpcNodeCore<Provider = Provider, Primitives = N>,
EvmConfig: ConfigureEvm<Primitives = N> + 'static,
Consensus: FullConsensus<N, Error = ConsensusError> + Clone + 'static,
{
Expand Down Expand Up @@ -933,11 +951,13 @@ where
)
.into_rpc()
.into(),
RethRpcModule::Debug => {
DebugApi::new(eth_api.clone(), self.blocking_pool_guard.clone())
.into_rpc()
.into()
}
RethRpcModule::Debug => DebugApi::new(
eth_api.clone(),
self.blocking_pool_guard.clone(),
self.bad_block_store.clone(),
)
.into_rpc()
.into(),
RethRpcModule::Eth => {
// merge all eth handlers
let mut module = eth_api.clone().into_rpc();
Expand Down
1 change: 0 additions & 1 deletion crates/rpc/rpc-eth-api/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ pub trait EthApiTypes: Send + Sync + Clone {
type NetworkTypes: RpcTypes;
/// Conversion methods for transaction RPC type.
type RpcConvert: RpcConvert<Network = Self::NetworkTypes>;

/// Returns reference to transaction response builder.
fn converter(&self) -> &Self::RpcConvert;
}
Expand Down
Loading