mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add version_specific_fields method to EngineTypes (#6050)
This commit is contained in:
@ -154,6 +154,7 @@ optimism = [
|
||||
"reth-optimism-payload-builder/optimism",
|
||||
"reth-ethereum-payload-builder/optimism",
|
||||
"reth-node-api/optimism",
|
||||
"reth-node-builder/optimism",
|
||||
]
|
||||
|
||||
# no-op feature flag for switching between the `optimism` and default functionality in CI matrices
|
||||
|
||||
@ -24,4 +24,4 @@ serde.workspace = true
|
||||
reth-payload-builder.workspace = true
|
||||
|
||||
[features]
|
||||
optimism = []
|
||||
optimism = []
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
//! ```no_run
|
||||
//! # use reth_rpc_types::engine::{PayloadAttributes as EthPayloadAttributes, PayloadId, Withdrawal};
|
||||
//! # use reth_primitives::{B256, ChainSpec, Address};
|
||||
//! # use reth_node_api::{EngineTypes, EngineApiMessageVersion, validate_version_specific_fields, AttributesValidationError, PayloadAttributes, PayloadBuilderAttributes};
|
||||
//! # use reth_node_api::{EngineTypes, EngineApiMessageVersion, validate_version_specific_fields, AttributesValidationError, PayloadAttributes, PayloadBuilderAttributes, PayloadOrAttributes};
|
||||
//! # use reth_payload_builder::{EthPayloadBuilderAttributes, EthBuiltPayload};
|
||||
//! # use serde::{Deserialize, Serialize};
|
||||
//! # use thiserror::Error;
|
||||
@ -58,7 +58,7 @@
|
||||
//! chain_spec: &ChainSpec,
|
||||
//! version: EngineApiMessageVersion,
|
||||
//! ) -> Result<(), AttributesValidationError> {
|
||||
//! validate_version_specific_fields(chain_spec, version, &self.into())?;
|
||||
//! validate_version_specific_fields(chain_spec, version, self.into())?;
|
||||
//!
|
||||
//! // custom validation logic - ensure that the custom field is not zero
|
||||
//! if self.custom == 0 {
|
||||
@ -122,6 +122,14 @@
|
||||
//! type PayloadAttributes = CustomPayloadAttributes;
|
||||
//! type PayloadBuilderAttributes = CustomPayloadBuilderAttributes;
|
||||
//! type BuiltPayload = EthBuiltPayload;
|
||||
//!
|
||||
//! fn validate_version_specific_fields(
|
||||
//! chain_spec: &ChainSpec,
|
||||
//! version: EngineApiMessageVersion,
|
||||
//! payload_or_attrs: PayloadOrAttributes<'_, CustomPayloadAttributes>,
|
||||
//! ) -> Result<(), AttributesValidationError> {
|
||||
//! validate_version_specific_fields(chain_spec, version, payload_or_attrs)
|
||||
//! }
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
@ -152,6 +160,14 @@ pub trait EngineTypes: Send + Sync {
|
||||
|
||||
/// The built payload type.
|
||||
type BuiltPayload: BuiltPayload + Clone + Unpin;
|
||||
|
||||
/// Validates the presence or exclusion of fork-specific fields based on the payload attributes
|
||||
/// and the message version.
|
||||
fn validate_version_specific_fields(
|
||||
chain_spec: &ChainSpec,
|
||||
version: EngineApiMessageVersion,
|
||||
payload_or_attrs: PayloadOrAttributes<'_, Self::PayloadAttributes>,
|
||||
) -> Result<(), AttributesValidationError>;
|
||||
}
|
||||
|
||||
/// Validates the timestamp depending on the version called:
|
||||
@ -198,6 +214,44 @@ pub fn validate_payload_timestamp(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
/// Validates the presence of the `withdrawals` field according to the payload timestamp.
|
||||
///
|
||||
/// After Canyon, withdrawals field must be [Some].
|
||||
/// Before Canyon, withdrawals field must be [None];
|
||||
///
|
||||
/// Canyon activates the Shanghai EIPs, see the Canyon specs for more details:
|
||||
/// <https://github.com/ethereum-optimism/optimism/blob/ab926c5fd1e55b5c864341c44842d6d1ca679d99/specs/superchain-upgrades.md#canyon>
|
||||
pub fn optimism_validate_withdrawals_presence(
|
||||
chain_spec: &ChainSpec,
|
||||
version: EngineApiMessageVersion,
|
||||
timestamp: u64,
|
||||
has_withdrawals: bool,
|
||||
) -> Result<(), AttributesValidationError> {
|
||||
let is_shanghai = chain_spec.fork(Hardfork::Canyon).active_at_timestamp(timestamp);
|
||||
|
||||
match version {
|
||||
EngineApiMessageVersion::V1 => {
|
||||
if has_withdrawals {
|
||||
return Err(AttributesValidationError::WithdrawalsNotSupportedInV1)
|
||||
}
|
||||
if is_shanghai {
|
||||
return Err(AttributesValidationError::NoWithdrawalsPostShanghai)
|
||||
}
|
||||
}
|
||||
EngineApiMessageVersion::V2 | EngineApiMessageVersion::V3 => {
|
||||
if is_shanghai && !has_withdrawals {
|
||||
return Err(AttributesValidationError::NoWithdrawalsPostShanghai)
|
||||
}
|
||||
if !is_shanghai && has_withdrawals {
|
||||
return Err(AttributesValidationError::HasWithdrawalsPreShanghai)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Validates the presence of the `withdrawals` field according to the payload timestamp.
|
||||
/// After Shanghai, withdrawals field must be [Some].
|
||||
/// Before Shanghai, withdrawals field must be [None];
|
||||
@ -290,7 +344,7 @@ pub fn validate_parent_beacon_block_root_presence(
|
||||
pub fn validate_version_specific_fields<Type>(
|
||||
chain_spec: &ChainSpec,
|
||||
version: EngineApiMessageVersion,
|
||||
payload_or_attrs: &PayloadOrAttributes<'_, Type>,
|
||||
payload_or_attrs: PayloadOrAttributes<'_, Type>,
|
||||
) -> Result<(), AttributesValidationError>
|
||||
where
|
||||
Type: PayloadAttributes,
|
||||
@ -309,6 +363,31 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
/// Validates the presence or exclusion of fork-specific fields based on the payload attributes
|
||||
/// and the message version.
|
||||
pub fn optimism_validate_version_specific_fields<Type>(
|
||||
chain_spec: &ChainSpec,
|
||||
version: EngineApiMessageVersion,
|
||||
payload_or_attrs: PayloadOrAttributes<'_, Type>,
|
||||
) -> Result<(), AttributesValidationError>
|
||||
where
|
||||
Type: PayloadAttributes,
|
||||
{
|
||||
optimism_validate_withdrawals_presence(
|
||||
chain_spec,
|
||||
version,
|
||||
payload_or_attrs.timestamp(),
|
||||
payload_or_attrs.withdrawals().is_some(),
|
||||
)?;
|
||||
validate_parent_beacon_block_root_presence(
|
||||
chain_spec,
|
||||
version,
|
||||
payload_or_attrs.timestamp(),
|
||||
payload_or_attrs.parent_beacon_block_root().is_some(),
|
||||
)
|
||||
}
|
||||
|
||||
/// The version of Engine API message.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum EngineApiMessageVersion {
|
||||
|
||||
@ -180,7 +180,7 @@ impl PayloadAttributes for EthPayloadAttributes {
|
||||
chain_spec: &ChainSpec,
|
||||
version: EngineApiMessageVersion,
|
||||
) -> Result<(), AttributesValidationError> {
|
||||
validate_version_specific_fields(chain_spec, version, &self.into())
|
||||
validate_version_specific_fields(chain_spec, version, self.into())
|
||||
}
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ impl PayloadAttributes for OptimismPayloadAttributes {
|
||||
chain_spec: &ChainSpec,
|
||||
version: EngineApiMessageVersion,
|
||||
) -> Result<(), AttributesValidationError> {
|
||||
validate_version_specific_fields(chain_spec, version, &self.into())?;
|
||||
validate_version_specific_fields(chain_spec, version, self.into())?;
|
||||
|
||||
if self.gas_limit.is_none() && chain_spec.is_optimism() {
|
||||
return Err(AttributesValidationError::InvalidParams(
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
///
|
||||
/// Notably contains the [EngineTypes] trait and implementations for ethereum mainnet types.
|
||||
pub mod engine;
|
||||
#[cfg(feature = "optimism")]
|
||||
pub use engine::optimism_validate_version_specific_fields;
|
||||
pub use engine::{
|
||||
validate_payload_timestamp, validate_version_specific_fields, validate_withdrawals_presence,
|
||||
AttributesValidationError, BuiltPayload, EngineApiMessageVersion, EngineTypes,
|
||||
|
||||
@ -19,3 +19,6 @@ reth-node-api.workspace = true
|
||||
|
||||
# io
|
||||
serde.workspace = true
|
||||
|
||||
[features]
|
||||
optimism = ["reth-node-api/optimism"]
|
||||
|
||||
@ -1,8 +1,16 @@
|
||||
use reth_node_api::EngineTypes;
|
||||
use reth_payload_builder::{
|
||||
EthBuiltPayload, EthPayloadBuilderAttributes, OptimismPayloadBuilderAttributes,
|
||||
#[cfg(feature = "optimism")]
|
||||
use reth_node_api::optimism_validate_version_specific_fields;
|
||||
use reth_node_api::{
|
||||
validate_version_specific_fields, AttributesValidationError, EngineApiMessageVersion,
|
||||
EngineTypes, PayloadOrAttributes,
|
||||
};
|
||||
use reth_rpc_types::engine::{OptimismPayloadAttributes, PayloadAttributes};
|
||||
#[cfg(feature = "optimism")]
|
||||
use reth_payload_builder::OptimismPayloadBuilderAttributes;
|
||||
use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes};
|
||||
use reth_primitives::ChainSpec;
|
||||
#[cfg(feature = "optimism")]
|
||||
use reth_rpc_types::engine::OptimismPayloadAttributes;
|
||||
use reth_rpc_types::engine::PayloadAttributes as EthPayloadAttributes;
|
||||
|
||||
/// The types used in the default mainnet ethereum beacon consensus engine.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
@ -10,18 +18,37 @@ use reth_rpc_types::engine::{OptimismPayloadAttributes, PayloadAttributes};
|
||||
pub struct EthEngineTypes;
|
||||
|
||||
impl EngineTypes for EthEngineTypes {
|
||||
type PayloadAttributes = PayloadAttributes;
|
||||
type PayloadAttributes = EthPayloadAttributes;
|
||||
type PayloadBuilderAttributes = EthPayloadBuilderAttributes;
|
||||
type BuiltPayload = EthBuiltPayload;
|
||||
|
||||
fn validate_version_specific_fields(
|
||||
chain_spec: &ChainSpec,
|
||||
version: EngineApiMessageVersion,
|
||||
payload_or_attrs: PayloadOrAttributes<'_, EthPayloadAttributes>,
|
||||
) -> Result<(), AttributesValidationError> {
|
||||
validate_version_specific_fields(chain_spec, version, payload_or_attrs)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
/// The types used in the optimism beacon consensus engine.
|
||||
#[derive(Debug, Default, Clone)]
|
||||
#[non_exhaustive]
|
||||
pub struct OptimismEngineTypes;
|
||||
|
||||
// TODO: remove cfg once Hardfork::Canyon can be used without the flag
|
||||
#[cfg(feature = "optimism")]
|
||||
impl EngineTypes for OptimismEngineTypes {
|
||||
type PayloadAttributes = OptimismPayloadAttributes;
|
||||
type PayloadBuilderAttributes = OptimismPayloadBuilderAttributes;
|
||||
type BuiltPayload = EthBuiltPayload;
|
||||
|
||||
fn validate_version_specific_fields(
|
||||
chain_spec: &ChainSpec,
|
||||
version: EngineApiMessageVersion,
|
||||
payload_or_attrs: PayloadOrAttributes<'_, OptimismPayloadAttributes>,
|
||||
) -> Result<(), AttributesValidationError> {
|
||||
optimism_validate_version_specific_fields(chain_spec, version, payload_or_attrs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,4 +10,7 @@
|
||||
/// Exports commonly used concrete instances of the [EngineTypes](reth_node_api::EngineTypes)
|
||||
/// trait.
|
||||
pub mod engine;
|
||||
pub use engine::{EthEngineTypes, OptimismEngineTypes};
|
||||
pub use engine::EthEngineTypes;
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
pub use engine::OptimismEngineTypes;
|
||||
|
||||
@ -4,9 +4,8 @@ use jsonrpsee_core::RpcResult;
|
||||
use reth_beacon_consensus::BeaconConsensusEngineHandle;
|
||||
use reth_interfaces::consensus::ForkchoiceState;
|
||||
use reth_node_api::{
|
||||
validate_payload_timestamp, validate_version_specific_fields, BuiltPayload,
|
||||
EngineApiMessageVersion, EngineTypes, PayloadAttributes, PayloadBuilderAttributes,
|
||||
PayloadOrAttributes,
|
||||
validate_payload_timestamp, BuiltPayload, EngineApiMessageVersion, EngineTypes,
|
||||
PayloadAttributes, PayloadBuilderAttributes, PayloadOrAttributes,
|
||||
};
|
||||
use reth_payload_builder::PayloadStore;
|
||||
use reth_primitives::{BlockHash, BlockHashOrNumber, BlockNumber, ChainSpec, Hardfork, B256, U64};
|
||||
@ -100,10 +99,10 @@ where
|
||||
PayloadOrAttributes::<'_, EngineT::PayloadAttributes>::from_execution_payload(
|
||||
&payload, None,
|
||||
);
|
||||
validate_version_specific_fields(
|
||||
EngineT::validate_version_specific_fields(
|
||||
&self.inner.chain_spec,
|
||||
EngineApiMessageVersion::V1,
|
||||
&payload_or_attrs,
|
||||
payload_or_attrs,
|
||||
)?;
|
||||
Ok(self.inner.beacon_consensus.new_payload(payload, None).await?)
|
||||
}
|
||||
@ -118,10 +117,10 @@ where
|
||||
PayloadOrAttributes::<'_, EngineT::PayloadAttributes>::from_execution_payload(
|
||||
&payload, None,
|
||||
);
|
||||
validate_version_specific_fields(
|
||||
EngineT::validate_version_specific_fields(
|
||||
&self.inner.chain_spec,
|
||||
EngineApiMessageVersion::V2,
|
||||
&payload_or_attrs,
|
||||
payload_or_attrs,
|
||||
)?;
|
||||
Ok(self.inner.beacon_consensus.new_payload(payload, None).await?)
|
||||
}
|
||||
@ -139,10 +138,10 @@ where
|
||||
&payload,
|
||||
Some(parent_beacon_block_root),
|
||||
);
|
||||
validate_version_specific_fields(
|
||||
EngineT::validate_version_specific_fields(
|
||||
&self.inner.chain_spec,
|
||||
EngineApiMessageVersion::V3,
|
||||
&payload_or_attrs,
|
||||
payload_or_attrs,
|
||||
)?;
|
||||
|
||||
let cancun_fields = CancunPayloadFields { versioned_hashes, parent_beacon_block_root };
|
||||
|
||||
Reference in New Issue
Block a user