mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
121 lines
4.7 KiB
Rust
121 lines
4.7 KiB
Rust
//! This crate defines abstractions to create and update payloads (blocks):
|
|
//! - [`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 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 consensus layer like `engine_forkchoiceUpdatedV1`.
|
|
//!
|
|
//! Payload building is enabled if the forkchoice update request contains payload attributes.
|
|
//!
|
|
//! See also [the engine API docs](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 given [`PayloadJobGenerator`]
|
|
//! and start polling it until the payload is requested by the CL and the payload job is resolved
|
|
//! (see [`PayloadJob::resolve`]).
|
|
//!
|
|
//! ## Example
|
|
//!
|
|
//! A simple example of a [`PayloadJobGenerator`] that creates empty blocks:
|
|
//!
|
|
//! ```
|
|
//! use std::future::Future;
|
|
//! use std::pin::Pin;
|
|
//! use std::task::{Context, Poll};
|
|
//! use reth_payload_builder::{EthBuiltPayload, KeepPayloadJobAlive, EthPayloadBuilderAttributes, 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: EthPayloadBuilderAttributes) -> Result<Self::Job, PayloadBuilderError> {
|
|
//! Ok(EmptyBlockPayloadJob{ attributes: attr,})
|
|
//! }
|
|
//!
|
|
//! }
|
|
//!
|
|
//! /// A [PayloadJob] that builds empty blocks.
|
|
//! pub struct EmptyBlockPayloadJob {
|
|
//! attributes: EthPayloadBuilderAttributes,
|
|
//! }
|
|
//!
|
|
//! impl PayloadJob for EmptyBlockPayloadJob {
|
|
//! type PayloadAttributes = EthPayloadBuilderAttributes;
|
|
//! type ResolvePayloadFuture = futures_util::future::Ready<Result<EthBuiltPayload, PayloadBuilderError>>;
|
|
//! type BuiltPayload = EthBuiltPayload;
|
|
//!
|
|
//! fn best_payload(&self) -> Result<EthBuiltPayload, 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 = EthBuiltPayload::new(self.attributes.id, payload.seal_slow(), U256::ZERO);
|
|
//! Ok(payload)
|
|
//! }
|
|
//!
|
|
//! fn payload_attributes(&self) -> Result<EthPayloadBuilderAttributes, PayloadBuilderError> {
|
|
//! Ok(self.attributes.clone())
|
|
//! }
|
|
//!
|
|
//! fn resolve(&mut self) -> (Self::ResolvePayloadFuture, KeepPayloadJobAlive) {
|
|
//! let payload = self.best_payload();
|
|
//! (futures_util::future::ready(payload), KeepPayloadJobAlive::No)
|
|
//! }
|
|
//! }
|
|
//!
|
|
//! /// A [PayloadJob] is 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
|
|
|
|
#![doc(
|
|
html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
|
|
html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
|
|
issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/"
|
|
)]
|
|
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
|
|
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
|
|
|
|
pub mod database;
|
|
pub mod error;
|
|
mod events;
|
|
mod metrics;
|
|
mod payload;
|
|
mod service;
|
|
mod traits;
|
|
|
|
pub mod noop;
|
|
|
|
#[cfg(any(test, feature = "test-utils"))]
|
|
pub mod test_utils;
|
|
|
|
pub use payload::{EthBuiltPayload, EthPayloadBuilderAttributes};
|
|
pub use reth_rpc_types::engine::PayloadId;
|
|
pub use service::{PayloadBuilderHandle, PayloadBuilderService, PayloadStore};
|
|
pub use traits::{KeepPayloadJobAlive, PayloadJob, PayloadJobGenerator};
|