Skip to content

Commit

Permalink
feat(l2-withdrawals): Define OpEngineApi (#14414)
Browse files Browse the repository at this point in the history
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
  • Loading branch information
emhane and mattsse authored Feb 11, 2025
1 parent 974b197 commit 5f15d1e
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 7 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/optimism/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
137 changes: 131 additions & 6 deletions crates/optimism/rpc/src/engine.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
//! 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,
};
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.
///
Expand Down Expand Up @@ -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>;
Expand All @@ -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,
Expand Down Expand Up @@ -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.
Expand All @@ -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
}
}
2 changes: 1 addition & 1 deletion crates/optimism/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

0 comments on commit 5f15d1e

Please sign in to comment.