diff --git a/Cargo.lock b/Cargo.lock index 53695d9130db..46b3031a818e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8637,6 +8637,7 @@ dependencies = [ "reth-provider", "reth-rpc", "reth-rpc-api", + "reth-rpc-engine-api", "reth-rpc-eth-api", "reth-rpc-eth-types", "reth-rpc-server-types", diff --git a/crates/optimism/rpc/Cargo.toml b/crates/optimism/rpc/Cargo.toml index 0e6c29545d73..7ee491a61ad4 100644 --- a/crates/optimism/rpc/Cargo.toml +++ b/crates/optimism/rpc/Cargo.toml @@ -28,6 +28,7 @@ reth-node-api.workspace = true reth-network-api.workspace = true reth-node-builder.workspace = true reth-chainspec.workspace = true +reth-rpc-engine-api.workspace = true # op-reth reth-optimism-chainspec.workspace = true diff --git a/crates/optimism/rpc/src/engine.rs b/crates/optimism/rpc/src/engine.rs index 7db38d7ad98b..e34de69da68a 100644 --- a/crates/optimism/rpc/src/engine.rs +++ b/crates/optimism/rpc/src/engine.rs @@ -1,7 +1,7 @@ //! Implements the Optimism engine API RPC methods. use alloy_eips::eip7685::Requests; -use alloy_primitives::{BlockHash, B256}; +use alloy_primitives::{BlockHash, B256, U64}; use alloy_rpc_types_engine::{ ClientVersionV1, ExecutionPayloadBodiesV1, ExecutionPayloadInputV2, ExecutionPayloadV3, ForkchoiceState, ForkchoiceUpdated, PayloadId, PayloadStatus, @@ -9,7 +9,11 @@ use alloy_rpc_types_engine::{ use jsonrpsee::proc_macros::rpc; use jsonrpsee_core::RpcResult; use op_alloy_rpc_types_engine::OpExecutionPayloadV4; -use reth_node_api::EngineTypes; +use reth_chainspec::EthereumHardforks; +use reth_node_api::{EngineTypes, EngineValidator, ExecutionData}; +use reth_provider::{BlockReader, HeaderProvider, StateProviderFactory}; +use reth_rpc_engine_api::{EngineApi, EngineApiServer}; +use reth_transaction_pool::TransactionPool; /// Extension trait that gives access to Optimism engine API RPC methods. /// @@ -42,7 +46,7 @@ pub trait OpEngineApi { #[method(name = "newPayloadV3")] async fn new_payload_v3( &self, - payload: OpExecutionPayloadV4, + payload: ExecutionPayloadV3, versioned_hashes: Vec, parent_beacon_block_root: B256, ) -> RpcResult; @@ -56,7 +60,7 @@ pub trait OpEngineApi { #[method(name = "newPayloadV4")] async fn new_payload_v4( &self, - payload: ExecutionPayloadV3, + payload: OpExecutionPayloadV4, versioned_hashes: Vec, parent_beacon_block_root: B256, execution_requests: Requests, @@ -165,8 +169,8 @@ pub trait OpEngineApi { #[method(name = "getPayloadBodiesByRangeV1")] async fn get_payload_bodies_by_range_v1( &self, - start: u64, - count: u64, + start: U64, + count: U64, ) -> RpcResult; /// Returns the execution client version information. @@ -187,3 +191,124 @@ pub trait OpEngineApi { #[method(name = "exchangeCapabilities")] async fn exchange_capabilities(&self, capabilities: Vec) -> RpcResult>; } + +/// The Engine API implementation that grants the Consensus layer access to data and +/// functions in the Execution layer that are crucial for the consensus process. +#[derive(Debug)] +pub struct OpEngineApi { + inner: EngineApi, +} + +#[async_trait::async_trait] +impl OpEngineApiServer + for OpEngineApi +where + Provider: HeaderProvider + BlockReader + StateProviderFactory + 'static, + EngineT: EngineTypes, + Pool: TransactionPool + 'static, + Validator: EngineValidator, + ChainSpec: EthereumHardforks + Send + Sync + 'static, +{ + async fn new_payload_v2(&self, payload: ExecutionPayloadInputV2) -> RpcResult { + EngineApiServer::new_payload_v2(&self.inner, payload).await + } + + async fn new_payload_v3( + &self, + payload: ExecutionPayloadV3, + versioned_hashes: Vec, + parent_beacon_block_root: B256, + ) -> RpcResult { + EngineApiServer::new_payload_v3( + &self.inner, + payload, + versioned_hashes, + parent_beacon_block_root, + ) + .await + } + + async fn new_payload_v4( + &self, + payload: OpExecutionPayloadV4, + versioned_hashes: Vec, + parent_beacon_block_root: B256, + execution_requests: Requests, + ) -> RpcResult { + // todo: custom op engine validator + let payload = payload.payload_inner; + EngineApiServer::new_payload_v4( + &self.inner, + payload, + versioned_hashes, + parent_beacon_block_root, + execution_requests, + ) + .await + } + + async fn fork_choice_updated_v2( + &self, + fork_choice_state: ForkchoiceState, + payload_attributes: Option, + ) -> RpcResult { + EngineApiServer::fork_choice_updated_v2(&self.inner, fork_choice_state, payload_attributes) + .await + } + + async fn fork_choice_updated_v3( + &self, + fork_choice_state: ForkchoiceState, + payload_attributes: Option, + ) -> RpcResult { + EngineApiServer::fork_choice_updated_v3(&self.inner, fork_choice_state, payload_attributes) + .await + } + + async fn get_payload_v2( + &self, + payload_id: PayloadId, + ) -> RpcResult { + EngineApiServer::get_payload_v2(&self.inner, payload_id).await + } + + async fn get_payload_v3( + &self, + payload_id: PayloadId, + ) -> RpcResult { + EngineApiServer::get_payload_v3(&self.inner, payload_id).await + } + + async fn get_payload_v4( + &self, + payload_id: PayloadId, + ) -> RpcResult { + EngineApiServer::get_payload_v4(&self.inner, payload_id).await + } + + async fn get_payload_bodies_by_hash_v1( + &self, + block_hashes: Vec, + ) -> RpcResult { + EngineApiServer::get_payload_bodies_by_hash_v1(&self.inner, block_hashes).await + } + + async fn get_payload_bodies_by_range_v1( + &self, + start: U64, + count: U64, + ) -> RpcResult { + EngineApiServer::get_payload_bodies_by_range_v1(&self.inner, start, count).await + } + + async fn get_client_version_v1( + &self, + client: ClientVersionV1, + ) -> RpcResult> { + EngineApiServer::get_client_version_v1(&self.inner, client).await + } + + async fn exchange_capabilities(&self, _capabilities: Vec) -> RpcResult> { + EngineApiServer::exchange_capabilities(&self.inner, _capabilities).await + } +} diff --git a/crates/optimism/rpc/src/lib.rs b/crates/optimism/rpc/src/lib.rs index d98b67191ccf..be17084a9e72 100644 --- a/crates/optimism/rpc/src/lib.rs +++ b/crates/optimism/rpc/src/lib.rs @@ -19,7 +19,7 @@ pub mod witness; #[cfg(feature = "client")] pub use engine::OpEngineApiClient; -pub use engine::OpEngineApiServer; +pub use engine::{OpEngineApi, OpEngineApiServer}; pub use error::{OpEthApiError, OpInvalidTransactionError, SequencerClientError}; pub use eth::{OpEthApi, OpReceiptBuilder}; pub use sequencer::SequencerClient;