mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
docs: add payload builder example (#3545)
This commit is contained in:
@ -16,13 +16,89 @@
|
||||
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
|
||||
))]
|
||||
|
||||
//! This trait implements the [PayloadBuilderService] responsible for managing payload jobs.
|
||||
//!
|
||||
//! It Defines the abstractions to create and update payloads:
|
||||
//! This crate defines the abstractions to create and update payloads:
|
||||
//! - [PayloadJobGenerator]: a type that knows how to create new jobs for creating payloads based
|
||||
//! on [PayloadAttributes](reth_rpc_types::engine::PayloadAttributes).
|
||||
//! - [PayloadJob]: a type that can yields (better) payloads over time.
|
||||
//!
|
||||
//! This crate comes with the generic [PayloadBuilderService] responsible for managing payload jobs.
|
||||
//!
|
||||
//! ## Node integration
|
||||
//!
|
||||
//! In a standard node the [PayloadBuilderService] sits downstream of the engine API or rather the
|
||||
//! component that handles requests from the Beacon Node like `engine_forkchoiceUpdatedV1`.
|
||||
//! Payload building is enabled if the forkchoice update request contains payload attributes.
|
||||
//! See also <https://github.com/ethereum/execution-apis/blob/6709c2a795b707202e93c4f2867fa0bf2640a84f/src/engine/shanghai.md#engine_forkchoiceupdatedv2>
|
||||
//! If the forkchoice update request is VALID and contains payload attributes the
|
||||
//! [PayloadBuilderService] will create a new [PayloadJob] via the [PayloadJobGenerator] and start
|
||||
//! polling it until the payload is requested by the CL and the payload job is resolved:
|
||||
//! [PayloadJob::resolve]
|
||||
//!
|
||||
//! ## Example
|
||||
//!
|
||||
//! A simple example of a [PayloadJobGenerator] that creates empty blocks:
|
||||
//!
|
||||
//! ```
|
||||
//! use std::future::Future;
|
||||
//! use std::pin::Pin;
|
||||
//! use std::sync::Arc;
|
||||
//! use std::task::{Context, Poll};
|
||||
//! use reth_payload_builder::{BuiltPayload, KeepPayloadJobAlive, PayloadBuilderAttributes, PayloadJob, PayloadJobGenerator};
|
||||
//! use reth_payload_builder::error::PayloadBuilderError;
|
||||
//! use reth_primitives::{Block, Header, U256};
|
||||
//!
|
||||
//! /// The generator type that creates new jobs that builds empty blocks.
|
||||
//! pub struct EmptyBlockPayloadJobGenerator;
|
||||
//!
|
||||
//! impl PayloadJobGenerator for EmptyBlockPayloadJobGenerator {
|
||||
//! type Job = EmptyBlockPayloadJob;
|
||||
//!
|
||||
//! /// This is invoked when the node receives payload attributes from the beacon node via `engine_forkchoiceUpdatedV1`
|
||||
//! fn new_payload_job(&self, attr: PayloadBuilderAttributes) -> Result<Self::Job, PayloadBuilderError> {
|
||||
//! Ok(EmptyBlockPayloadJob{ attributes: attr,})
|
||||
//! }
|
||||
//!
|
||||
//! }
|
||||
//!
|
||||
//! /// A [PayloadJob] that builds empty blocks.
|
||||
//! pub struct EmptyBlockPayloadJob {
|
||||
//! attributes: PayloadBuilderAttributes,
|
||||
//! }
|
||||
//!
|
||||
//! impl PayloadJob for EmptyBlockPayloadJob {
|
||||
//! type ResolvePayloadFuture = futures_util::future::Ready<Result<Arc<BuiltPayload>, PayloadBuilderError>>;
|
||||
//!
|
||||
//! fn best_payload(&self) -> Result<Arc<BuiltPayload>, PayloadBuilderError> {
|
||||
//! // NOTE: some fields are omitted here for brevity
|
||||
//! let payload = Block {
|
||||
//! header: Header {
|
||||
//! parent_hash: self.attributes.parent,
|
||||
//! timestamp: self.attributes.timestamp,
|
||||
//! beneficiary: self.attributes.suggested_fee_recipient,
|
||||
//! ..Default::default()
|
||||
//! },
|
||||
//! ..Default::default()
|
||||
//! };
|
||||
//! let payload = BuiltPayload::new(self.attributes.id, payload.seal_slow(), U256::ZERO);
|
||||
//! Ok(Arc::new(payload))
|
||||
//! }
|
||||
//!
|
||||
//! fn resolve(&mut self) -> (Self::ResolvePayloadFuture, KeepPayloadJobAlive) {
|
||||
//! let payload = self.best_payload();
|
||||
//! (futures_util::future::ready(payload), KeepPayloadJobAlive::No)
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! /// A [PayloadJob] is a a future that's being polled by the `PayloadBuilderService`
|
||||
//! impl Future for EmptyBlockPayloadJob {
|
||||
//! type Output = Result<(), PayloadBuilderError>;
|
||||
//!
|
||||
//! fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
//! Poll::Pending
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Feature Flags
|
||||
//!
|
||||
//! - `test-utils`: Export utilities for testing
|
||||
|
||||
Reference in New Issue
Block a user