feat(l2-withdrawals): Define OpEngineApi (#14414)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Emilia Hane
2025-02-11 20:50:32 +01:00
committed by GitHub
parent 974b197d30
commit 5f15d1e2a9
4 changed files with 134 additions and 7 deletions

View File

@ -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

View File

@ -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<Engine: EngineTypes> {
#[method(name = "newPayloadV3")]
async fn new_payload_v3(
&self,
payload: OpExecutionPayloadV4,
payload: ExecutionPayloadV3,
versioned_hashes: Vec<B256>,
parent_beacon_block_root: B256,
) -> RpcResult<PayloadStatus>;
@ -56,7 +60,7 @@ pub trait OpEngineApi<Engine: EngineTypes> {
#[method(name = "newPayloadV4")]
async fn new_payload_v4(
&self,
payload: ExecutionPayloadV3,
payload: OpExecutionPayloadV4,
versioned_hashes: Vec<B256>,
parent_beacon_block_root: B256,
execution_requests: Requests,
@ -165,8 +169,8 @@ pub trait OpEngineApi<Engine: EngineTypes> {
#[method(name = "getPayloadBodiesByRangeV1")]
async fn get_payload_bodies_by_range_v1(
&self,
start: u64,
count: u64,
start: U64,
count: U64,
) -> RpcResult<ExecutionPayloadBodiesV1>;
/// Returns the execution client version information.
@ -187,3 +191,124 @@ pub trait OpEngineApi<Engine: EngineTypes> {
#[method(name = "exchangeCapabilities")]
async fn exchange_capabilities(&self, capabilities: Vec<String>) -> RpcResult<Vec<String>>;
}
/// 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<Provider, EngineT: EngineTypes, Pool, Validator, ChainSpec> {
inner: EngineApi<Provider, EngineT, Pool, Validator, ChainSpec>,
}
#[async_trait::async_trait]
impl<Provider, EngineT, Pool, Validator, ChainSpec> OpEngineApiServer<EngineT>
for OpEngineApi<Provider, EngineT, Pool, Validator, ChainSpec>
where
Provider: HeaderProvider + BlockReader + StateProviderFactory + 'static,
EngineT: EngineTypes<ExecutionData = ExecutionData>,
Pool: TransactionPool + 'static,
Validator: EngineValidator<EngineT>,
ChainSpec: EthereumHardforks + Send + Sync + 'static,
{
async fn new_payload_v2(&self, payload: ExecutionPayloadInputV2) -> RpcResult<PayloadStatus> {
EngineApiServer::new_payload_v2(&self.inner, payload).await
}
async fn new_payload_v3(
&self,
payload: ExecutionPayloadV3,
versioned_hashes: Vec<B256>,
parent_beacon_block_root: B256,
) -> RpcResult<PayloadStatus> {
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<B256>,
parent_beacon_block_root: B256,
execution_requests: Requests,
) -> RpcResult<PayloadStatus> {
// todo: custom op engine validator <https://github.com/paradigmxyz/reth/pull/14207>
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<EngineT::PayloadAttributes>,
) -> RpcResult<ForkchoiceUpdated> {
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<EngineT::PayloadAttributes>,
) -> RpcResult<ForkchoiceUpdated> {
EngineApiServer::fork_choice_updated_v3(&self.inner, fork_choice_state, payload_attributes)
.await
}
async fn get_payload_v2(
&self,
payload_id: PayloadId,
) -> RpcResult<EngineT::ExecutionPayloadEnvelopeV2> {
EngineApiServer::get_payload_v2(&self.inner, payload_id).await
}
async fn get_payload_v3(
&self,
payload_id: PayloadId,
) -> RpcResult<EngineT::ExecutionPayloadEnvelopeV3> {
EngineApiServer::get_payload_v3(&self.inner, payload_id).await
}
async fn get_payload_v4(
&self,
payload_id: PayloadId,
) -> RpcResult<EngineT::ExecutionPayloadEnvelopeV4> {
EngineApiServer::get_payload_v4(&self.inner, payload_id).await
}
async fn get_payload_bodies_by_hash_v1(
&self,
block_hashes: Vec<BlockHash>,
) -> RpcResult<ExecutionPayloadBodiesV1> {
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<ExecutionPayloadBodiesV1> {
EngineApiServer::get_payload_bodies_by_range_v1(&self.inner, start, count).await
}
async fn get_client_version_v1(
&self,
client: ClientVersionV1,
) -> RpcResult<Vec<ClientVersionV1>> {
EngineApiServer::get_client_version_v1(&self.inner, client).await
}
async fn exchange_capabilities(&self, _capabilities: Vec<String>) -> RpcResult<Vec<String>> {
EngineApiServer::exchange_capabilities(&self.inner, _capabilities).await
}
}

View File

@ -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;