diff --git a/crates/node/builder/src/rpc.rs b/crates/node/builder/src/rpc.rs index 4530bbe70144..9680c221d7ce 100644 --- a/crates/node/builder/src/rpc.rs +++ b/crates/node/builder/src/rpc.rs @@ -17,6 +17,7 @@ use reth_node_core::{ version::{CARGO_PKG_VERSION, CLIENT_CODE, NAME_CLIENT, VERGEN_GIT_SHA}, }; use reth_payload_builder::PayloadStore; +use reth_payload_primitives::PayloadBuilder; use reth_provider::providers::ProviderNodeTypes; use reth_rpc::{ eth::{EthApiTypes, FullEthApiServer}, @@ -402,7 +403,7 @@ impl NodeAddOns for RpcAddOns where N: FullNodeComponents< Types: ProviderNodeTypes, - PayloadBuilder: Into::Engine>>, + PayloadBuilder: PayloadBuilder::Engine>, >, EthApi: EthApiTypes + FullEthApiServer + AddDevSigners + Unpin + 'static, EV: EngineValidatorBuilder, @@ -426,7 +427,7 @@ where node.provider().clone(), config.chain.clone(), beacon_engine_handle, - node.payload_builder().clone().into(), + PayloadStore::new(node.payload_builder().clone()), node.pool().clone(), Box::new(node.task_executor().clone()), client, diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index e97924d4b554..efc8964ffabd 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -7,7 +7,7 @@ use reth_chainspec::{EthChainSpec, Hardforks}; use reth_evm::{execute::BasicBlockExecutorProvider, ConfigureEvm}; use reth_network::{NetworkConfig, NetworkHandle, NetworkManager, PeersInfo}; use reth_node_api::{ - AddOnsContext, EngineValidator, FullNodeComponents, NodeAddOns, NodePrimitives, + AddOnsContext, EngineValidator, FullNodeComponents, NodeAddOns, NodePrimitives, PayloadBuilder, }; use reth_node_builder::{ components::{ @@ -23,7 +23,7 @@ use reth_optimism_consensus::OpBeaconConsensus; use reth_optimism_evm::{OpEvmConfig, OpExecutionStrategyFactory}; use reth_optimism_payload_builder::builder::OpPayloadTransactions; use reth_optimism_rpc::OpEthApi; -use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService, PayloadStore}; +use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use reth_primitives::{Block, Header, Receipt, TransactionSigned, TxType}; use reth_provider::CanonStateSubscriptions; use reth_tracing::tracing::{debug, info}; @@ -152,7 +152,7 @@ impl NodeAddOns for OpAddOns where N: FullNodeComponents< Types: NodeTypes, - PayloadBuilder: Into::Engine>>, + PayloadBuilder: PayloadBuilder::Engine>, >, OpEngineValidator: EngineValidator<::Engine>, { @@ -170,7 +170,7 @@ impl RethRpcAddOns for OpAddOns where N: FullNodeComponents< Types: NodeTypes, - PayloadBuilder: Into::Engine>>, + PayloadBuilder: PayloadBuilder::Engine>, >, OpEngineValidator: EngineValidator<::Engine>, { diff --git a/crates/payload/builder/src/service.rs b/crates/payload/builder/src/service.rs index 2c9975cb4c36..267a1e355b0e 100644 --- a/crates/payload/builder/src/service.rs +++ b/crates/payload/builder/src/service.rs @@ -12,12 +12,13 @@ use futures_util::{future::FutureExt, Stream, StreamExt}; use reth_chain_state::CanonStateNotification; use reth_payload_primitives::{ BuiltPayload, Events, PayloadBuilder, PayloadBuilderAttributes, PayloadBuilderError, - PayloadEvents, PayloadKind, PayloadTypes, + PayloadEvents, PayloadKind, PayloadStoreExt, PayloadTypes, }; use std::{ fmt, future::Future, pin::Pin, + sync::Arc, task::{Context, Poll}, }; use tokio::sync::{ @@ -30,13 +31,14 @@ use tracing::{debug, info, trace, warn}; type PayloadFuture

= Pin> + Send + Sync>>; /// A communication channel to the [`PayloadBuilderService`] that can retrieve payloads. +/// +/// This type is intended to be used to retrieve payloads from the service (e.g. from the engine +/// API). #[derive(Debug)] pub struct PayloadStore { - inner: PayloadBuilderHandle, + inner: Arc>, } -// === impl PayloadStore === - impl PayloadStore where T: PayloadTypes, @@ -82,12 +84,16 @@ where } } -impl Clone for PayloadStore +impl PayloadStore where T: PayloadTypes, { - fn clone(&self) -> Self { - Self { inner: self.inner.clone() } + /// Create a new instance + pub fn new

(inner: P) -> Self + where + P: PayloadStoreExt + 'static, + { + Self { inner: Arc::new(inner) } } } @@ -96,7 +102,7 @@ where T: PayloadTypes, { fn from(inner: PayloadBuilderHandle) -> Self { - Self { inner } + Self::new(inner) } } diff --git a/crates/payload/primitives/src/lib.rs b/crates/payload/primitives/src/lib.rs index 7013d9fd913c..3604ff5d8d81 100644 --- a/crates/payload/primitives/src/lib.rs +++ b/crates/payload/primitives/src/lib.rs @@ -20,7 +20,7 @@ pub use crate::events::{Events, PayloadEvents}; mod traits; pub use traits::{ BuiltPayload, PayloadAttributes, PayloadAttributesBuilder, PayloadBuilder, - PayloadBuilderAttributes, + PayloadBuilderAttributes, PayloadStoreExt, }; mod payload; diff --git a/crates/payload/primitives/src/traits.rs b/crates/payload/primitives/src/traits.rs index 86f04a5b5509..197a7fe3af99 100644 --- a/crates/payload/primitives/src/traits.rs +++ b/crates/payload/primitives/src/traits.rs @@ -7,11 +7,12 @@ use alloy_primitives::{Address, B256, U256}; use alloy_rpc_types_engine::{PayloadAttributes as EthPayloadAttributes, PayloadId}; use reth_chain_state::ExecutedBlock; use reth_primitives::SealedBlock; +use std::fmt::Debug; use tokio::sync::oneshot; /// A type that can request, subscribe to and resolve payloads. #[async_trait::async_trait] -pub trait PayloadBuilder: Send + Sync + Unpin { +pub trait PayloadBuilder: Debug + Send + Sync + Unpin { /// The Payload type for the builder. type PayloadType: PayloadTypes; /// The error type returned by the builder. @@ -58,6 +59,63 @@ pub trait PayloadBuilder: Send + Sync + Unpin { ) -> Option::PayloadBuilderAttributes, Self::Error>>; } +/// A helper trait for internal usage to retrieve and resolve payloads. +#[async_trait::async_trait] +pub trait PayloadStoreExt: Debug + Send + Sync + Unpin { + /// Resolves the payload job and returns the best payload that has been built so far. + async fn resolve_kind( + &self, + id: PayloadId, + kind: PayloadKind, + ) -> Option>; + + /// Resolves the payload job as fast and possible and returns the best payload that has been + /// built so far. + async fn resolve(&self, id: PayloadId) -> Option> { + self.resolve_kind(id, PayloadKind::Earliest).await + } + + /// Returns the best payload for the given identifier. + async fn best_payload( + &self, + id: PayloadId, + ) -> Option>; + + /// Returns the payload attributes associated with the given identifier. + async fn payload_attributes( + &self, + id: PayloadId, + ) -> Option>; +} + +#[async_trait::async_trait] +impl PayloadStoreExt for P +where + P: PayloadBuilder, +{ + async fn resolve_kind( + &self, + id: PayloadId, + kind: PayloadKind, + ) -> Option> { + Some(PayloadBuilder::resolve_kind(self, id, kind).await?.map_err(Into::into)) + } + + async fn best_payload( + &self, + id: PayloadId, + ) -> Option> { + Some(PayloadBuilder::best_payload(self, id).await?.map_err(Into::into)) + } + + async fn payload_attributes( + &self, + id: PayloadId, + ) -> Option> { + Some(PayloadBuilder::payload_attributes(self, id).await?.map_err(Into::into)) + } +} + /// Represents a built payload type that contains a built [`SealedBlock`] and can be converted into /// engine API execution payloads. pub trait BuiltPayload: Send + Sync + std::fmt::Debug {