diff --git a/crates/node/builder/src/launch/mod.rs b/crates/node/builder/src/launch/mod.rs index 328a77e0db..3ca4e29fc8 100644 --- a/crates/node/builder/src/launch/mod.rs +++ b/crates/node/builder/src/launch/mod.rs @@ -25,7 +25,7 @@ use reth_node_core::{ use reth_node_events::{cl::ConsensusLayerHealthEvents, node}; use reth_primitives::format_ether; use reth_provider::providers::BlockchainProvider; -use reth_rpc_engine_api::EngineApi; +use reth_rpc_engine_api::{capabilities::EngineCapabilities, EngineApi}; use reth_rpc_types::engine::ClientVersionV1; use reth_tasks::TaskExecutor; use reth_tracing::tracing::{debug, info}; @@ -299,6 +299,7 @@ where ctx.components().payload_builder().clone().into(), Box::new(ctx.task_executor().clone()), client, + EngineCapabilities::default(), ); info!(target: "reth::cli", "Engine API handler initialized"); diff --git a/crates/rpc/rpc-builder/tests/it/utils.rs b/crates/rpc/rpc-builder/tests/it/utils.rs index ea9954f23c..d5fe508aaa 100644 --- a/crates/rpc/rpc-builder/tests/it/utils.rs +++ b/crates/rpc/rpc-builder/tests/it/utils.rs @@ -11,7 +11,7 @@ use reth_rpc_builder::{ auth::{AuthRpcModule, AuthServerConfig, AuthServerHandle}, EthApiBuild, RpcModuleBuilder, RpcServerConfig, RpcServerHandle, TransportRpcModuleConfig, }; -use reth_rpc_engine_api::EngineApi; +use reth_rpc_engine_api::{capabilities::EngineCapabilities, EngineApi}; use reth_rpc_layer::JwtSecret; use reth_rpc_server_types::RpcModuleSelection; use reth_rpc_types::engine::{ClientCode, ClientVersionV1}; @@ -44,6 +44,7 @@ pub async fn launch_auth(secret: JwtSecret) -> AuthServerHandle { spawn_test_payload_service().into(), Box::::default(), client, + EngineCapabilities::default(), ); let module = AuthRpcModule::new(engine_api); module.start_server(config).await.unwrap() diff --git a/crates/rpc/rpc-engine-api/src/capabilities.rs b/crates/rpc/rpc-engine-api/src/capabilities.rs new file mode 100644 index 0000000000..a96db527bd --- /dev/null +++ b/crates/rpc/rpc-engine-api/src/capabilities.rs @@ -0,0 +1,48 @@ +use std::collections::HashSet; + +/// The list of all supported Engine capabilities available over the engine endpoint. +pub const CAPABILITIES: &[&str] = &[ + "engine_forkchoiceUpdatedV1", + "engine_forkchoiceUpdatedV2", + "engine_forkchoiceUpdatedV3", + "engine_exchangeTransitionConfigurationV1", + "engine_getClientVersionV1", + "engine_getPayloadV1", + "engine_getPayloadV2", + "engine_getPayloadV3", + "engine_getPayloadV4", + "engine_newPayloadV1", + "engine_newPayloadV2", + "engine_newPayloadV3", + "engine_newPayloadV4", + "engine_getPayloadBodiesByHashV1", + "engine_getPayloadBodiesByRangeV1", + "engine_getPayloadBodiesByHashV2", + "engine_getPayloadBodiesByRangeV2", +]; + +// The list of all supported Engine capabilities available over the engine endpoint. +/// +/// Latest spec: Prague +#[derive(Debug, Clone)] +pub struct EngineCapabilities { + inner: HashSet, +} + +impl EngineCapabilities { + /// Returns the list of all supported Engine capabilities for Prague spec. + fn prague() -> Self { + Self { inner: CAPABILITIES.iter().cloned().map(str::to_owned).collect() } + } + + /// Returns the list of all supported Engine capabilities. + pub fn list(&self) -> Vec { + self.inner.iter().cloned().collect() + } +} + +impl Default for EngineCapabilities { + fn default() -> Self { + Self::prague() + } +} diff --git a/crates/rpc/rpc-engine-api/src/engine_api.rs b/crates/rpc/rpc-engine-api/src/engine_api.rs index b64b9fa20e..4ec832053d 100644 --- a/crates/rpc/rpc-engine-api/src/engine_api.rs +++ b/crates/rpc/rpc-engine-api/src/engine_api.rs @@ -1,4 +1,6 @@ -use crate::{metrics::EngineApiMetrics, EngineApiError, EngineApiResult}; +use crate::{ + capabilities::EngineCapabilities, metrics::EngineApiMetrics, EngineApiError, EngineApiResult, +}; use async_trait::async_trait; use jsonrpsee_core::RpcResult; use reth_beacon_consensus::BeaconConsensusEngineHandle; @@ -18,7 +20,7 @@ use reth_rpc_types::engine::{ CancunPayloadFields, ClientVersionV1, ExecutionPayload, ExecutionPayloadBodiesV1, ExecutionPayloadBodiesV2, ExecutionPayloadInputV2, ExecutionPayloadV1, ExecutionPayloadV3, ExecutionPayloadV4, ForkchoiceState, ForkchoiceUpdated, PayloadId, PayloadStatus, - TransitionConfiguration, CAPABILITIES, + TransitionConfiguration, }; use reth_rpc_types_compat::engine::payload::{ convert_payload_input_v2_to_payload, convert_to_payload_body_v1, convert_to_payload_body_v2, @@ -56,6 +58,8 @@ struct EngineApiInner { metrics: EngineApiMetrics, /// Identification of the execution client used by the consensus client client: ClientVersionV1, + /// The list of all supported Engine capabilities available over the engine endpoint. + capabilities: EngineCapabilities, } impl EngineApi @@ -71,6 +75,7 @@ where payload_store: PayloadStore, task_spawner: Box, client: ClientVersionV1, + capabilities: EngineCapabilities, ) -> Self { let inner = Arc::new(EngineApiInner { provider, @@ -80,6 +85,7 @@ where task_spawner, metrics: EngineApiMetrics::default(), client, + capabilities, }); Self { inner } } @@ -896,7 +902,7 @@ where /// Handler for `engine_exchangeCapabilitiesV1` /// See also async fn exchange_capabilities(&self, _capabilities: Vec) -> RpcResult> { - Ok(CAPABILITIES.iter().cloned().map(str::to_owned).collect()) + Ok(self.inner.capabilities.list()) } } @@ -949,6 +955,7 @@ mod tests { payload_store.into(), task_executor, client, + EngineCapabilities::default(), ); let handle = EngineApiTestHandle { chain_spec, provider, from_api: engine_rx }; (handle, api) diff --git a/crates/rpc/rpc-engine-api/src/lib.rs b/crates/rpc/rpc-engine-api/src/lib.rs index 0f9323c007..a2da00eee7 100644 --- a/crates/rpc/rpc-engine-api/src/lib.rs +++ b/crates/rpc/rpc-engine-api/src/lib.rs @@ -12,6 +12,9 @@ /// The Engine API implementation. mod engine_api; +/// Engine API capabilities. +pub mod capabilities; + /// The Engine API message type. mod message;