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-optimism-payload-builder/optimism",
|
||||||
"reth-ethereum-payload-builder/optimism",
|
"reth-ethereum-payload-builder/optimism",
|
||||||
"reth-node-api/optimism",
|
"reth-node-api/optimism",
|
||||||
|
"reth-node-builder/optimism",
|
||||||
]
|
]
|
||||||
|
|
||||||
# no-op feature flag for switching between the `optimism` and default functionality in CI matrices
|
# 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
|
reth-payload-builder.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
optimism = []
|
optimism = []
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! # use reth_rpc_types::engine::{PayloadAttributes as EthPayloadAttributes, PayloadId, Withdrawal};
|
//! # use reth_rpc_types::engine::{PayloadAttributes as EthPayloadAttributes, PayloadId, Withdrawal};
|
||||||
//! # use reth_primitives::{B256, ChainSpec, Address};
|
//! # 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 reth_payload_builder::{EthPayloadBuilderAttributes, EthBuiltPayload};
|
||||||
//! # use serde::{Deserialize, Serialize};
|
//! # use serde::{Deserialize, Serialize};
|
||||||
//! # use thiserror::Error;
|
//! # use thiserror::Error;
|
||||||
@ -58,7 +58,7 @@
|
|||||||
//! chain_spec: &ChainSpec,
|
//! chain_spec: &ChainSpec,
|
||||||
//! version: EngineApiMessageVersion,
|
//! version: EngineApiMessageVersion,
|
||||||
//! ) -> Result<(), AttributesValidationError> {
|
//! ) -> 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
|
//! // custom validation logic - ensure that the custom field is not zero
|
||||||
//! if self.custom == 0 {
|
//! if self.custom == 0 {
|
||||||
@ -122,6 +122,14 @@
|
|||||||
//! type PayloadAttributes = CustomPayloadAttributes;
|
//! type PayloadAttributes = CustomPayloadAttributes;
|
||||||
//! type PayloadBuilderAttributes = CustomPayloadBuilderAttributes;
|
//! type PayloadBuilderAttributes = CustomPayloadBuilderAttributes;
|
||||||
//! type BuiltPayload = EthBuiltPayload;
|
//! 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.
|
/// The built payload type.
|
||||||
type BuiltPayload: BuiltPayload + Clone + Unpin;
|
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:
|
/// Validates the timestamp depending on the version called:
|
||||||
@ -198,6 +214,44 @@ pub fn validate_payload_timestamp(
|
|||||||
Ok(())
|
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.
|
/// Validates the presence of the `withdrawals` field according to the payload timestamp.
|
||||||
/// After Shanghai, withdrawals field must be [Some].
|
/// After Shanghai, withdrawals field must be [Some].
|
||||||
/// Before Shanghai, withdrawals field must be [None];
|
/// 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>(
|
pub fn validate_version_specific_fields<Type>(
|
||||||
chain_spec: &ChainSpec,
|
chain_spec: &ChainSpec,
|
||||||
version: EngineApiMessageVersion,
|
version: EngineApiMessageVersion,
|
||||||
payload_or_attrs: &PayloadOrAttributes<'_, Type>,
|
payload_or_attrs: PayloadOrAttributes<'_, Type>,
|
||||||
) -> Result<(), AttributesValidationError>
|
) -> Result<(), AttributesValidationError>
|
||||||
where
|
where
|
||||||
Type: PayloadAttributes,
|
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.
|
/// The version of Engine API message.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum EngineApiMessageVersion {
|
pub enum EngineApiMessageVersion {
|
||||||
|
|||||||
@ -180,7 +180,7 @@ impl PayloadAttributes for EthPayloadAttributes {
|
|||||||
chain_spec: &ChainSpec,
|
chain_spec: &ChainSpec,
|
||||||
version: EngineApiMessageVersion,
|
version: EngineApiMessageVersion,
|
||||||
) -> Result<(), AttributesValidationError> {
|
) -> 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,
|
chain_spec: &ChainSpec,
|
||||||
version: EngineApiMessageVersion,
|
version: EngineApiMessageVersion,
|
||||||
) -> Result<(), AttributesValidationError> {
|
) -> 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() {
|
if self.gas_limit.is_none() && chain_spec.is_optimism() {
|
||||||
return Err(AttributesValidationError::InvalidParams(
|
return Err(AttributesValidationError::InvalidParams(
|
||||||
|
|||||||
@ -11,6 +11,8 @@
|
|||||||
///
|
///
|
||||||
/// Notably contains the [EngineTypes] trait and implementations for ethereum mainnet types.
|
/// Notably contains the [EngineTypes] trait and implementations for ethereum mainnet types.
|
||||||
pub mod engine;
|
pub mod engine;
|
||||||
|
#[cfg(feature = "optimism")]
|
||||||
|
pub use engine::optimism_validate_version_specific_fields;
|
||||||
pub use engine::{
|
pub use engine::{
|
||||||
validate_payload_timestamp, validate_version_specific_fields, validate_withdrawals_presence,
|
validate_payload_timestamp, validate_version_specific_fields, validate_withdrawals_presence,
|
||||||
AttributesValidationError, BuiltPayload, EngineApiMessageVersion, EngineTypes,
|
AttributesValidationError, BuiltPayload, EngineApiMessageVersion, EngineTypes,
|
||||||
|
|||||||
@ -19,3 +19,6 @@ reth-node-api.workspace = true
|
|||||||
|
|
||||||
# io
|
# io
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
optimism = ["reth-node-api/optimism"]
|
||||||
|
|||||||
@ -1,8 +1,16 @@
|
|||||||
use reth_node_api::EngineTypes;
|
#[cfg(feature = "optimism")]
|
||||||
use reth_payload_builder::{
|
use reth_node_api::optimism_validate_version_specific_fields;
|
||||||
EthBuiltPayload, EthPayloadBuilderAttributes, OptimismPayloadBuilderAttributes,
|
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.
|
/// The types used in the default mainnet ethereum beacon consensus engine.
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
@ -10,18 +18,37 @@ use reth_rpc_types::engine::{OptimismPayloadAttributes, PayloadAttributes};
|
|||||||
pub struct EthEngineTypes;
|
pub struct EthEngineTypes;
|
||||||
|
|
||||||
impl EngineTypes for EthEngineTypes {
|
impl EngineTypes for EthEngineTypes {
|
||||||
type PayloadAttributes = PayloadAttributes;
|
type PayloadAttributes = EthPayloadAttributes;
|
||||||
type PayloadBuilderAttributes = EthPayloadBuilderAttributes;
|
type PayloadBuilderAttributes = EthPayloadBuilderAttributes;
|
||||||
type BuiltPayload = EthBuiltPayload;
|
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.
|
/// The types used in the optimism beacon consensus engine.
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct OptimismEngineTypes;
|
pub struct OptimismEngineTypes;
|
||||||
|
|
||||||
|
// TODO: remove cfg once Hardfork::Canyon can be used without the flag
|
||||||
|
#[cfg(feature = "optimism")]
|
||||||
impl EngineTypes for OptimismEngineTypes {
|
impl EngineTypes for OptimismEngineTypes {
|
||||||
type PayloadAttributes = OptimismPayloadAttributes;
|
type PayloadAttributes = OptimismPayloadAttributes;
|
||||||
type PayloadBuilderAttributes = OptimismPayloadBuilderAttributes;
|
type PayloadBuilderAttributes = OptimismPayloadBuilderAttributes;
|
||||||
type BuiltPayload = EthBuiltPayload;
|
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)
|
/// Exports commonly used concrete instances of the [EngineTypes](reth_node_api::EngineTypes)
|
||||||
/// trait.
|
/// trait.
|
||||||
pub mod engine;
|
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_beacon_consensus::BeaconConsensusEngineHandle;
|
||||||
use reth_interfaces::consensus::ForkchoiceState;
|
use reth_interfaces::consensus::ForkchoiceState;
|
||||||
use reth_node_api::{
|
use reth_node_api::{
|
||||||
validate_payload_timestamp, validate_version_specific_fields, BuiltPayload,
|
validate_payload_timestamp, BuiltPayload, EngineApiMessageVersion, EngineTypes,
|
||||||
EngineApiMessageVersion, EngineTypes, PayloadAttributes, PayloadBuilderAttributes,
|
PayloadAttributes, PayloadBuilderAttributes, PayloadOrAttributes,
|
||||||
PayloadOrAttributes,
|
|
||||||
};
|
};
|
||||||
use reth_payload_builder::PayloadStore;
|
use reth_payload_builder::PayloadStore;
|
||||||
use reth_primitives::{BlockHash, BlockHashOrNumber, BlockNumber, ChainSpec, Hardfork, B256, U64};
|
use reth_primitives::{BlockHash, BlockHashOrNumber, BlockNumber, ChainSpec, Hardfork, B256, U64};
|
||||||
@ -100,10 +99,10 @@ where
|
|||||||
PayloadOrAttributes::<'_, EngineT::PayloadAttributes>::from_execution_payload(
|
PayloadOrAttributes::<'_, EngineT::PayloadAttributes>::from_execution_payload(
|
||||||
&payload, None,
|
&payload, None,
|
||||||
);
|
);
|
||||||
validate_version_specific_fields(
|
EngineT::validate_version_specific_fields(
|
||||||
&self.inner.chain_spec,
|
&self.inner.chain_spec,
|
||||||
EngineApiMessageVersion::V1,
|
EngineApiMessageVersion::V1,
|
||||||
&payload_or_attrs,
|
payload_or_attrs,
|
||||||
)?;
|
)?;
|
||||||
Ok(self.inner.beacon_consensus.new_payload(payload, None).await?)
|
Ok(self.inner.beacon_consensus.new_payload(payload, None).await?)
|
||||||
}
|
}
|
||||||
@ -118,10 +117,10 @@ where
|
|||||||
PayloadOrAttributes::<'_, EngineT::PayloadAttributes>::from_execution_payload(
|
PayloadOrAttributes::<'_, EngineT::PayloadAttributes>::from_execution_payload(
|
||||||
&payload, None,
|
&payload, None,
|
||||||
);
|
);
|
||||||
validate_version_specific_fields(
|
EngineT::validate_version_specific_fields(
|
||||||
&self.inner.chain_spec,
|
&self.inner.chain_spec,
|
||||||
EngineApiMessageVersion::V2,
|
EngineApiMessageVersion::V2,
|
||||||
&payload_or_attrs,
|
payload_or_attrs,
|
||||||
)?;
|
)?;
|
||||||
Ok(self.inner.beacon_consensus.new_payload(payload, None).await?)
|
Ok(self.inner.beacon_consensus.new_payload(payload, None).await?)
|
||||||
}
|
}
|
||||||
@ -139,10 +138,10 @@ where
|
|||||||
&payload,
|
&payload,
|
||||||
Some(parent_beacon_block_root),
|
Some(parent_beacon_block_root),
|
||||||
);
|
);
|
||||||
validate_version_specific_fields(
|
EngineT::validate_version_specific_fields(
|
||||||
&self.inner.chain_spec,
|
&self.inner.chain_spec,
|
||||||
EngineApiMessageVersion::V3,
|
EngineApiMessageVersion::V3,
|
||||||
&payload_or_attrs,
|
payload_or_attrs,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let cancun_fields = CancunPayloadFields { versioned_hashes, parent_beacon_block_root };
|
let cancun_fields = CancunPayloadFields { versioned_hashes, parent_beacon_block_root };
|
||||||
|
|||||||
Reference in New Issue
Block a user