Skip to content

Commit

Permalink
feat(api,rpc): improve engine API abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
fgimenez committed Feb 29, 2024
1 parent c5955f1 commit 87b8880
Show file tree
Hide file tree
Showing 15 changed files with 102 additions and 96 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.

15 changes: 14 additions & 1 deletion crates/node-api/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use reth_primitives::{ChainSpec, Hardfork};
/// Contains traits to abstract over payload attributes types and default implementations of the
/// [PayloadAttributes] trait for ethereum mainnet and optimism types.
pub mod traits;
use serde::{de::DeserializeOwned, ser::Serialize};
pub use traits::{BuiltPayload, PayloadAttributes, PayloadBuilderAttributes};

/// Contains error types used in the traits defined in this crate.
Expand All @@ -29,7 +30,19 @@ pub trait EngineTypes:
+ Unpin;

/// The built payload type.
type BuiltPayload: BuiltPayload + Clone + Unpin;
type BuiltPayload: BuiltPayload
+ Clone
+ Unpin
+ TryInto<Self::ExecutionPayloadV1>
+ TryInto<Self::ExecutionPayloadV2>
+ TryInto<Self::ExecutionPayloadV3>;

/// Execution Payload V1 type.
type ExecutionPayloadV1: DeserializeOwned + Serialize + Clone + Unpin + Send + Sync + 'static;
/// Execution Payload V2 type.
type ExecutionPayloadV2: DeserializeOwned + Serialize + Clone + Unpin + Send + Sync + 'static;
/// Execution Payload V3 type.
type ExecutionPayloadV3: DeserializeOwned + Serialize + Clone + Unpin + Send + Sync + 'static;

/// Validates the presence or exclusion of fork-specific fields based on the payload attributes
/// and the message version.
Expand Down
15 changes: 1 addition & 14 deletions crates/node-api/src/engine/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@ use reth_primitives::{
Address, ChainSpec, Header, SealedBlock, Withdrawals, B256, U256,
};
use reth_rpc_types::{
engine::{
ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, OptimismPayloadAttributes,
PayloadAttributes as EthPayloadAttributes, PayloadId,
},
engine::{OptimismPayloadAttributes, PayloadAttributes as EthPayloadAttributes, PayloadId},
withdrawal::Withdrawal,
ExecutionPayloadV1,
};

/// Represents a built payload type that contains a built [SealedBlock] and can be converted into
Expand All @@ -20,15 +16,6 @@ pub trait BuiltPayload: Send + Sync + std::fmt::Debug {

/// Returns the fees collected for the built block
fn fees(&self) -> U256;

/// Converts the type into the response expected by `engine_getPayloadV1`
fn into_v1_payload(self) -> ExecutionPayloadV1;

/// Converts the type into the response expected by `engine_getPayloadV2`
fn into_v2_payload(self) -> ExecutionPayloadEnvelopeV2;

/// Converts the type into the response expected by `engine_getPayloadV3`
fn into_v3_payload(self) -> ExecutionPayloadEnvelopeV3;
}

/// This can be implemented by types that describe a currently running payload job.
Expand Down
1 change: 1 addition & 0 deletions crates/node-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ tokio = { workspace = true, features = [
eyre.workspace = true
fdlimit = "0.3.0"
confy.workspace = true
serde.workspace = true
11 changes: 9 additions & 2 deletions crates/node-builder/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,10 @@ where
Components::Pool,
>,
>,
> {
>
where
Types::Engine: serde::Serialize,
{
// get config from file
let reth_config = self.load_config(&data_dir)?;

Expand Down Expand Up @@ -810,6 +813,7 @@ where
RethFullAdapter<DB, N>,
<N::PoolBuilder as PoolBuilder<RethFullAdapter<DB, N>>>::Pool,
>,
N::Engine: serde::Serialize,
{
self.node(node).launch().await
}
Expand Down Expand Up @@ -962,7 +966,10 @@ where
Components::Pool,
>,
>,
> {
>
where
Types::Engine: serde::Serialize,
{
let Self { builder, task_executor, data_dir } = self;

builder.launch(task_executor, data_dir).await
Expand Down
1 change: 1 addition & 0 deletions crates/node-builder/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ pub(crate) async fn launch_rpc_servers<Node, Engine>(
where
Node: FullNodeComponents + Clone,
Engine: EngineApiServer<Node::Engine>,
Node::Engine: serde::Serialize,
{
let RpcHooks { on_rpc_started, extend_rpc_modules } = hooks;

Expand Down
2 changes: 1 addition & 1 deletion crates/node-core/src/args/rpc_server_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ impl RpcServerArgs {
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
Tasks: TaskSpawner + Clone + 'static,
EngineT: EngineTypes + 'static,
EngineT: EngineTypes + serde::Serialize + 'static,
EvmConfig: ConfigureEvmEnv + 'static,
{
let socket_address = SocketAddr::new(self.auth_addr, self.auth_port);
Expand Down
13 changes: 11 additions & 2 deletions crates/node-ethereum/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@ use reth_node_api::{
};
use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes};
use reth_primitives::ChainSpec;
use reth_rpc_types::engine::PayloadAttributes as EthPayloadAttributes;
use reth_rpc_types::{
engine::{
ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3,
PayloadAttributes as EthPayloadAttributes,
},
ExecutionPayloadV1,
};

/// The types used in the default mainnet ethereum beacon consensus engine.
#[derive(Debug, Default, Clone, serde::Deserialize)]
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
#[non_exhaustive]
pub struct EthEngineTypes;

impl EngineTypes for EthEngineTypes {
type PayloadAttributes = EthPayloadAttributes;
type PayloadBuilderAttributes = EthPayloadBuilderAttributes;
type BuiltPayload = EthBuiltPayload;
type ExecutionPayloadV1 = ExecutionPayloadV1;
type ExecutionPayloadV2 = ExecutionPayloadEnvelopeV2;
type ExecutionPayloadV3 = ExecutionPayloadEnvelopeV3;

fn validate_version_specific_fields(
chain_spec: &ChainSpec,
Expand Down
10 changes: 8 additions & 2 deletions crates/node-optimism/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@ use reth_node_api::{
};
use reth_payload_builder::{EthBuiltPayload, OptimismPayloadBuilderAttributes};
use reth_primitives::{ChainSpec, Hardfork};
use reth_rpc_types::engine::OptimismPayloadAttributes;
use reth_rpc_types::{
engine::{ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, OptimismPayloadAttributes},
ExecutionPayloadV1,
};

/// The types used in the optimism beacon consensus engine.
#[derive(Debug, Default, Clone, serde::Deserialize)]
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
#[non_exhaustive]
pub struct OptimismEngineTypes;

impl EngineTypes for OptimismEngineTypes {
type PayloadAttributes = OptimismPayloadAttributes;
type PayloadBuilderAttributes = OptimismPayloadBuilderAttributes;
type BuiltPayload = EthBuiltPayload;
type ExecutionPayloadV1 = ExecutionPayloadV1;
type ExecutionPayloadV2 = ExecutionPayloadEnvelopeV2;
type ExecutionPayloadV3 = ExecutionPayloadEnvelopeV3;

fn validate_version_specific_fields(
chain_spec: &ChainSpec,
Expand Down
27 changes: 0 additions & 27 deletions crates/payload/builder/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,6 @@ impl EthBuiltPayload {
pub fn extend_sidecars(&mut self, sidecars: Vec<BlobTransactionSidecar>) {
self.sidecars.extend(sidecars)
}

/// Converts the type into the response expected by `engine_getPayloadV1`
pub fn into_v1_payload(self) -> ExecutionPayloadV1 {
self.into()
}

/// Converts the type into the response expected by `engine_getPayloadV2`
pub fn into_v2_payload(self) -> ExecutionPayloadEnvelopeV2 {
self.into()
}

/// Converts the type into the response expected by `engine_getPayloadV3`
pub fn into_v3_payload(self) -> ExecutionPayloadEnvelopeV3 {
self.into()
}
}

impl BuiltPayload for EthBuiltPayload {
Expand All @@ -87,18 +72,6 @@ impl BuiltPayload for EthBuiltPayload {
fn fees(&self) -> U256 {
self.fees
}

fn into_v1_payload(self) -> ExecutionPayloadV1 {
self.into()
}

fn into_v2_payload(self) -> ExecutionPayloadEnvelopeV2 {
self.into()
}

fn into_v3_payload(self) -> ExecutionPayloadEnvelopeV3 {
self.into()
}
}

// V1 engine_getPayloadV1 response
Expand Down
11 changes: 5 additions & 6 deletions crates/rpc/rpc-api/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ use reth_node_api::EngineTypes;
use reth_primitives::{Address, BlockHash, BlockId, BlockNumberOrTag, Bytes, B256, U256, U64};
use reth_rpc_types::{
engine::{
ExecutionPayloadBodiesV1, ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3,
ExecutionPayloadInputV2, ExecutionPayloadV1, ExecutionPayloadV3, ForkchoiceState,
ForkchoiceUpdated, PayloadId, PayloadStatus, TransitionConfiguration,
ExecutionPayloadBodiesV1, ExecutionPayloadInputV2, ExecutionPayloadV1, ExecutionPayloadV3,
ForkchoiceState, ForkchoiceUpdated, PayloadId, PayloadStatus, TransitionConfiguration,
},
state::StateOverride,
BlockOverrides, Filter, Log, RichBlock, SyncStatus, TransactionRequest,
Expand Down Expand Up @@ -96,15 +95,15 @@ pub trait EngineApi<Engine: EngineTypes> {
/// Note:
/// > Provider software MAY stop the corresponding build process after serving this call.
#[method(name = "getPayloadV1")]
async fn get_payload_v1(&self, payload_id: PayloadId) -> RpcResult<ExecutionPayloadV1>;
async fn get_payload_v1(&self, payload_id: PayloadId) -> RpcResult<Engine::ExecutionPayloadV1>;

/// See also <https://github.com/ethereum/execution-apis/blob/6709c2a795b707202e93c4f2867fa0bf2640a84f/src/engine/shanghai.md#engine_getpayloadv2>
///
/// Returns the most recent version of the payload that is available in the corresponding
/// payload build process at the time of receiving this call. Note:
/// > Provider software MAY stop the corresponding build process after serving this call.
#[method(name = "getPayloadV2")]
async fn get_payload_v2(&self, payload_id: PayloadId) -> RpcResult<ExecutionPayloadEnvelopeV2>;
async fn get_payload_v2(&self, payload_id: PayloadId) -> RpcResult<Engine::ExecutionPayloadV2>;

/// Post Cancun payload handler which also returns a blobs bundle.
///
Expand All @@ -114,7 +113,7 @@ pub trait EngineApi<Engine: EngineTypes> {
/// payload build process at the time of receiving this call. Note:
/// > Provider software MAY stop the corresponding build process after serving this call.
#[method(name = "getPayloadV3")]
async fn get_payload_v3(&self, payload_id: PayloadId) -> RpcResult<ExecutionPayloadEnvelopeV3>;
async fn get_payload_v3(&self, payload_id: PayloadId) -> RpcResult<Engine::ExecutionPayloadV3>;

/// See also <https://github.com/ethereum/execution-apis/blob/6452a6b194d7db269bf1dbd087a267251d3cc7f8/src/engine/shanghai.md#engine_getpayloadbodiesbyhashv1>
#[method(name = "getPayloadBodiesByHashV1")]
Expand Down
6 changes: 3 additions & 3 deletions crates/rpc/rpc-builder/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ where
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
Tasks: TaskSpawner + Clone + 'static,
EngineT: EngineTypes + 'static,
EngineT: EngineTypes + serde::Serialize + 'static,
EngineApi: EngineApiServer<EngineT>,
EvmConfig: ConfigureEvmEnv + 'static,
{
Expand Down Expand Up @@ -113,7 +113,7 @@ where
+ 'static,
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
EngineT: EngineTypes + 'static,
EngineT: EngineTypes + serde::Serialize + 'static,
EngineApi: EngineApiServer<EngineT>,
EvmConfig: ConfigureEvmEnv + 'static,
{
Expand Down Expand Up @@ -267,7 +267,7 @@ impl AuthRpcModule {
/// Create a new `AuthRpcModule` with the given `engine_api`.
pub fn new<EngineApi, EngineT>(engine: EngineApi) -> Self
where
EngineT: EngineTypes + 'static,
EngineT: EngineTypes + serde::Serialize + 'static,
EngineApi: EngineApiServer<EngineT>,
{
let mut module = RpcModule::new(());
Expand Down
6 changes: 3 additions & 3 deletions crates/rpc/rpc-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
//! Network: NetworkInfo + Peers + Clone + 'static,
//! Events: CanonStateSubscriptions + Clone + 'static,
//! EngineApi: EngineApiServer<EngineT>,
//! EngineT: EngineTypes + 'static,
//! EngineT: EngineTypes + serde::Serialize + 'static,
//! EvmConfig: ConfigureEvmEnv + 'static,
//! {
//! // configure the rpc module per transport
Expand Down Expand Up @@ -456,7 +456,7 @@ where
RethModuleRegistry<Provider, Pool, Network, Tasks, Events, EvmConfig>,
)
where
EngineT: EngineTypes + 'static,
EngineT: EngineTypes + serde::Serialize + 'static,
EngineApi: EngineApiServer<EngineT>,
{
let mut modules = TransportRpcModules::default();
Expand Down Expand Up @@ -1110,7 +1110,7 @@ where
/// Note: This does _not_ register the `engine_` in this registry.
pub fn create_auth_module<EngineApi, EngineT>(&mut self, engine_api: EngineApi) -> AuthRpcModule
where
EngineT: EngineTypes + 'static,
EngineT: EngineTypes + serde::Serialize + 'static,
EngineApi: EngineApiServer<EngineT>,
{
let eth_handlers = self.eth_handlers();
Expand Down
Loading

0 comments on commit 87b8880

Please sign in to comment.