feat(examples): route engine messages from custom engine api in custom-node example (#15458)

This commit is contained in:
Federico Gimenez
2025-04-02 16:09:58 +02:00
committed by GitHub
parent 7305c9ee0d
commit d3ec6abd08
3 changed files with 78 additions and 19 deletions

View File

@@ -1,28 +1,48 @@
use crate::{
chainspec::CustomChainSpec,
engine::{CustomPayloadAttributes, CustomPayloadTypes},
engine::{
CustomBuiltPayload, CustomExecutionData, CustomPayloadAttributes, CustomPayloadTypes,
},
primitives::CustomNodePrimitives,
};
use alloy_rpc_types_engine::{
ForkchoiceState, ForkchoiceUpdated, PayloadId, PayloadStatus, PayloadStatusEnum,
ExecutionPayloadV3, ForkchoiceState, ForkchoiceUpdated, PayloadId, PayloadStatus,
};
use async_trait::async_trait;
use jsonrpsee::{core::RpcResult, proc_macros::rpc, RpcModule};
use reth_node_api::{AddOnsContext, FullNodeComponents, NodeTypes};
use reth_node_api::{
AddOnsContext, BeaconConsensusEngineHandle, EngineApiMessageVersion, FullNodeComponents,
NodeTypes,
};
use reth_node_builder::rpc::EngineApiBuilder;
use reth_optimism_node::node::OpStorage;
use reth_payload_builder::PayloadStore;
use reth_rpc_api::IntoEngineApiRpcModule;
use reth_rpc_engine_api::EngineApiError;
use std::sync::Arc;
#[derive(serde::Deserialize)]
pub struct CustomExecutionPayloadInput {}
#[derive(Clone, serde::Serialize)]
pub struct CustomExecutionPayloadEnvelope {}
pub struct CustomExecutionPayloadEnvelope {
execution_payload: ExecutionPayloadV3,
}
impl From<CustomBuiltPayload> for CustomExecutionPayloadEnvelope {
fn from(value: CustomBuiltPayload) -> Self {
let sealed_block = value.0.into_sealed_block();
let hash = sealed_block.hash();
let block = sealed_block.into_block();
Self { execution_payload: ExecutionPayloadV3::from_block_unchecked(hash, &block.clone()) }
}
}
#[rpc(server, namespace = "engine")]
pub trait CustomEngineApi {
#[method(name = "newPayload")]
async fn new_payload(&self, payload: CustomExecutionPayloadInput) -> RpcResult<PayloadStatus>;
async fn new_payload(&self, payload: CustomExecutionData) -> RpcResult<PayloadStatus>;
#[method(name = "forkchoiceUpdated")]
async fn fork_choice_updated(
@@ -36,30 +56,60 @@ pub trait CustomEngineApi {
-> RpcResult<CustomExecutionPayloadEnvelope>;
}
pub struct CustomEngineApi {}
pub struct CustomEngineApi {
inner: Arc<CustomEngineApiInner>,
}
struct CustomEngineApiInner {
beacon_consensus: BeaconConsensusEngineHandle<CustomPayloadTypes>,
payload_store: PayloadStore<CustomPayloadTypes>,
}
impl CustomEngineApiInner {
fn new(
beacon_consensus: BeaconConsensusEngineHandle<CustomPayloadTypes>,
payload_store: PayloadStore<CustomPayloadTypes>,
) -> Self {
Self { beacon_consensus, payload_store }
}
}
#[async_trait]
impl CustomEngineApiServer for CustomEngineApi {
async fn new_payload(&self, _payload: CustomExecutionPayloadInput) -> RpcResult<PayloadStatus> {
Ok(PayloadStatus::from_status(PayloadStatusEnum::Valid))
async fn new_payload(&self, payload: CustomExecutionData) -> RpcResult<PayloadStatus> {
Ok(self
.inner
.beacon_consensus
.new_payload(payload)
.await
.map_err(EngineApiError::NewPayload)?)
}
async fn fork_choice_updated(
&self,
_fork_choice_state: ForkchoiceState,
_payload_attributes: Option<CustomPayloadAttributes>,
fork_choice_state: ForkchoiceState,
payload_attributes: Option<CustomPayloadAttributes>,
) -> RpcResult<ForkchoiceUpdated> {
Ok(ForkchoiceUpdated {
payload_status: PayloadStatus::from_status(PayloadStatusEnum::Valid),
payload_id: Some(PayloadId::default()),
})
Ok(self
.inner
.beacon_consensus
.fork_choice_updated(fork_choice_state, payload_attributes, EngineApiMessageVersion::V3)
.await
.map_err(EngineApiError::ForkChoiceUpdate)?)
}
async fn get_payload(
&self,
_payload_id: PayloadId,
payload_id: PayloadId,
) -> RpcResult<CustomExecutionPayloadEnvelope> {
Ok(CustomExecutionPayloadEnvelope {})
Ok(self
.inner
.payload_store
.resolve(payload_id)
.await
.ok_or(EngineApiError::UnknownPayload)?
.map_err(|_| EngineApiError::UnknownPayload)?
.into())
}
}
@@ -88,7 +138,12 @@ where
{
type EngineApi = CustomEngineApi;
async fn build_engine_api(self, _ctx: &AddOnsContext<'_, N>) -> eyre::Result<Self::EngineApi> {
Ok(CustomEngineApi {})
async fn build_engine_api(self, ctx: &AddOnsContext<'_, N>) -> eyre::Result<Self::EngineApi> {
Ok(CustomEngineApi {
inner: Arc::new(CustomEngineApiInner::new(
ctx.beacon_engine_handle.clone(),
PayloadStore::new(ctx.node.payload_builder_handle().clone()),
)),
})
}
}