Make PayloadOrAttributes generic over ExecutionData (#14666)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Yohann Kazoula
2025-02-24 10:50:39 +02:00
committed by GitHub
parent c72731e913
commit 33443de09a
7 changed files with 144 additions and 98 deletions

View File

@ -29,7 +29,7 @@ pub use traits::{
};
mod payload;
pub use payload::PayloadOrAttributes;
pub use payload::{ExecutionPayload, PayloadOrAttributes};
/// The types that are used by the engine API.
pub trait PayloadTypes: Send + Sync + Unpin + core::fmt::Debug + Clone + 'static {
@ -302,12 +302,13 @@ impl MessageValidationKind {
/// either an execution payload, or payload attributes.
///
/// The version is provided by the [`EngineApiMessageVersion`] argument.
pub fn validate_version_specific_fields<Type, T>(
pub fn validate_version_specific_fields<Payload, Type, T>(
chain_spec: &T,
version: EngineApiMessageVersion,
payload_or_attrs: PayloadOrAttributes<'_, Type>,
payload_or_attrs: PayloadOrAttributes<'_, Payload, Type>,
) -> Result<(), EngineObjectValidationError>
where
Payload: ExecutionPayload,
Type: PayloadAttributes,
T: EthereumHardforks,
{

View File

@ -2,32 +2,75 @@ use crate::{MessageValidationKind, PayloadAttributes};
use alloc::vec::Vec;
use alloy_eips::eip4895::Withdrawal;
use alloy_primitives::B256;
use alloy_rpc_types_engine::ExecutionPayload;
use alloy_rpc_types_engine::ExecutionData;
use core::fmt::Debug;
use serde::{de::DeserializeOwned, Serialize};
/// Either an [`ExecutionPayload`] or a type that implements the [`PayloadAttributes`] trait.
/// An execution payload.
pub trait ExecutionPayload:
Serialize + DeserializeOwned + Debug + Clone + Send + Sync + 'static
{
/// Returns the parent hash of the block.
fn parent_hash(&self) -> B256;
/// Returns the hash of the block.
fn block_hash(&self) -> B256;
/// Returns the number of the block.
fn block_number(&self) -> u64;
/// Returns the withdrawals for the payload, if it exists.
fn withdrawals(&self) -> Option<&Vec<Withdrawal>>;
/// Return the parent beacon block root for the payload, if it exists.
fn parent_beacon_block_root(&self) -> Option<B256>;
/// Returns the timestamp to be used in the payload.
fn timestamp(&self) -> u64;
}
impl ExecutionPayload for ExecutionData {
fn parent_hash(&self) -> B256 {
self.payload.parent_hash()
}
fn block_hash(&self) -> B256 {
self.payload.block_hash()
}
fn block_number(&self) -> u64 {
self.payload.block_number()
}
fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
self.payload.withdrawals()
}
fn parent_beacon_block_root(&self) -> Option<B256> {
self.sidecar.parent_beacon_block_root()
}
fn timestamp(&self) -> u64 {
self.payload.timestamp()
}
}
/// Either a type that implements the [`ExecutionPayload`] or a type that implements the
/// [`PayloadAttributes`] trait.
///
/// This is a helper type to unify pre-validation of version specific fields of the engine API.
#[derive(Debug)]
pub enum PayloadOrAttributes<'a, Attributes> {
/// An [`ExecutionPayload`] and optional parent beacon block root.
ExecutionPayload {
/// The inner execution payload
payload: &'a ExecutionPayload,
/// The parent beacon block root
parent_beacon_block_root: Option<B256>,
},
pub enum PayloadOrAttributes<'a, Payload, Attributes> {
/// An [`ExecutionPayload`]
ExecutionPayload(&'a Payload),
/// A payload attributes type.
PayloadAttributes(&'a Attributes),
}
impl<'a, Attributes> PayloadOrAttributes<'a, Attributes> {
/// Construct a [`PayloadOrAttributes`] from an [`ExecutionPayload`] and optional parent beacon
/// block root.
pub const fn from_execution_payload(
payload: &'a ExecutionPayload,
parent_beacon_block_root: Option<B256>,
) -> Self {
Self::ExecutionPayload { payload, parent_beacon_block_root }
impl<'a, Payload, Attributes> PayloadOrAttributes<'a, Payload, Attributes> {
/// Construct a [`PayloadOrAttributes::ExecutionPayload`] variant
pub const fn from_execution_payload(payload: &'a Payload) -> Self {
Self::ExecutionPayload(payload)
}
/// Construct a [`PayloadOrAttributes::PayloadAttributes`] variant
@ -36,14 +79,15 @@ impl<'a, Attributes> PayloadOrAttributes<'a, Attributes> {
}
}
impl<Attributes> PayloadOrAttributes<'_, Attributes>
impl<Payload, Attributes> PayloadOrAttributes<'_, Payload, Attributes>
where
Payload: ExecutionPayload,
Attributes: PayloadAttributes,
{
/// Return the withdrawals for the payload or attributes.
pub fn withdrawals(&self) -> Option<&Vec<Withdrawal>> {
match self {
Self::ExecutionPayload { payload, .. } => payload.withdrawals(),
Self::ExecutionPayload(payload) => payload.withdrawals(),
Self::PayloadAttributes(attributes) => attributes.withdrawals(),
}
}
@ -51,7 +95,7 @@ where
/// Return the timestamp for the payload or attributes.
pub fn timestamp(&self) -> u64 {
match self {
Self::ExecutionPayload { payload, .. } => payload.timestamp(),
Self::ExecutionPayload(payload) => payload.timestamp(),
Self::PayloadAttributes(attributes) => attributes.timestamp(),
}
}
@ -59,7 +103,7 @@ where
/// Return the parent beacon block root for the payload or attributes.
pub fn parent_beacon_block_root(&self) -> Option<B256> {
match self {
Self::ExecutionPayload { parent_beacon_block_root, .. } => *parent_beacon_block_root,
Self::ExecutionPayload(payload) => payload.parent_beacon_block_root(),
Self::PayloadAttributes(attributes) => attributes.parent_beacon_block_root(),
}
}
@ -73,7 +117,8 @@ where
}
}
impl<'a, AttributesType> From<&'a AttributesType> for PayloadOrAttributes<'a, AttributesType>
impl<'a, Payload, AttributesType> From<&'a AttributesType>
for PayloadOrAttributes<'a, Payload, AttributesType>
where
AttributesType: PayloadAttributes,
{