Skip to content

Commit

Permalink
feat: add additional conversion fn (#1883)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse authored Jan 3, 2025
1 parent ccf0fd3 commit fa109e3
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
44 changes: 43 additions & 1 deletion crates/rpc-types-engine/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use alloc::{
vec::Vec,
};
use alloy_consensus::{
constants::MAXIMUM_EXTRA_DATA_SIZE, Blob, Block, BlockBody, Bytes48, Header,
constants::MAXIMUM_EXTRA_DATA_SIZE, Blob, Block, BlockBody, Bytes48, Header, Transaction,
EMPTY_OMMER_ROOT_HASH,
};
use alloy_eips::{
Expand Down Expand Up @@ -770,6 +770,48 @@ pub enum ExecutionPayload {
}

impl ExecutionPayload {
/// Converts [`alloy_consensus::Block`] to [`ExecutionPayload`] and also returns the
/// [`ExecutionPayloadSidecar`] extracted from the block.
///
/// See also [`ExecutionPayloadV3::from_block_unchecked`].
/// See also [`ExecutionPayloadSidecar::from_block`].
///
/// Note: This re-calculates the block hash.
pub fn from_block_slow<T>(block: &Block<T>) -> (Self, ExecutionPayloadSidecar)
where
T: Encodable2718 + Transaction,
{
Self::from_block_unchecked(block.hash_slow(), block)
}

/// Converts [`alloy_consensus::Block`] to [`ExecutionPayload`] and also returns the
/// [`ExecutionPayloadSidecar`] extracted from the block.
///
/// See also [`ExecutionPayloadV3::from_block_unchecked`].
/// See also [`ExecutionPayloadSidecar::from_block`].
pub fn from_block_unchecked<T>(
block_hash: B256,
block: &Block<T>,
) -> (Self, ExecutionPayloadSidecar)
where
T: Encodable2718 + Transaction,
{
let sidecar = ExecutionPayloadSidecar::from_block(block);

let execution_payload = if block.header.parent_beacon_block_root.is_some() {
// block with parent beacon block root: V3
Self::V3(ExecutionPayloadV3::from_block_unchecked(block_hash, block))
} else if block.body.withdrawals.is_some() {
// block with withdrawals: V2
Self::V2(ExecutionPayloadV2::from_block_unchecked(block_hash, block))
} else {
// otherwise V1
Self::V1(ExecutionPayloadV1::from_block_unchecked(block_hash, block))
};

(execution_payload, sidecar)
}

/// Tries to create a new unsealed block from the given payload and payload sidecar.
///
/// Performs additional validation of `extra_data` and `base_fee_per_gas` fields.
Expand Down
27 changes: 27 additions & 0 deletions crates/rpc-types-engine/src/sidecar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
CancunPayloadFields, MaybeCancunPayloadFields, MaybePraguePayloadFields, PraguePayloadFields,
};
use alloc::vec::Vec;
use alloy_consensus::{Block, Transaction};
use alloy_eips::eip7685::Requests;
use alloy_primitives::B256;

Expand All @@ -21,6 +22,32 @@ pub struct ExecutionPayloadSidecar {
}

impl ExecutionPayloadSidecar {
/// Extracts the [`ExecutionPayloadSidecar`] from the given [`alloy_consensus::Block`].
///
/// Returns [`ExecutionPayloadSidecar::none`] if the block does not contain any sidecar fields
/// (pre-cancun): `requests_hash`, `parent_beacon_block_root`, `blob_versioned_hashes`.
///
/// Note: This returns [`RequestOrHash::Hash`](alloy_eips::eip7685::RequestsOrHash::Hash) for
/// the EIP-7685 requests.
pub fn from_block<T>(block: &Block<T>) -> Self
where
T: Transaction,
{
let cancun =
block.parent_beacon_block_root.map(|parent_beacon_block_root| CancunPayloadFields {
parent_beacon_block_root,
versioned_hashes: block.body.blob_versioned_hashes_iter().copied().collect(),
});

let prague = block.requests_hash.map(PraguePayloadFields::new);

match (cancun, prague) {
(Some(cancun), Some(prague)) => Self::v4(cancun, prague),
(Some(cancun), None) => Self::v3(cancun),
_ => Self::none(),
}
}

/// Returns a new empty instance (pre-cancun, v1, v2)
pub const fn none() -> Self {
Self { cancun: MaybeCancunPayloadFields::none(), prague: MaybePraguePayloadFields::none() }
Expand Down

0 comments on commit fa109e3

Please sign in to comment.