mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add CancunPayloadFields for engine_newPayloadV3 (#4407)
This commit is contained in:
@ -5,9 +5,9 @@ use crate::{
|
|||||||
BeaconForkChoiceUpdateError, BeaconOnNewPayloadError,
|
BeaconForkChoiceUpdateError, BeaconOnNewPayloadError,
|
||||||
};
|
};
|
||||||
use futures::TryFutureExt;
|
use futures::TryFutureExt;
|
||||||
use reth_primitives::H256;
|
|
||||||
use reth_rpc_types::engine::{
|
use reth_rpc_types::engine::{
|
||||||
ExecutionPayload, ForkchoiceState, ForkchoiceUpdated, PayloadAttributes, PayloadStatus,
|
CancunPayloadFields, ExecutionPayload, ForkchoiceState, ForkchoiceUpdated, PayloadAttributes,
|
||||||
|
PayloadStatus,
|
||||||
};
|
};
|
||||||
use tokio::sync::{mpsc, mpsc::UnboundedSender, oneshot};
|
use tokio::sync::{mpsc, mpsc::UnboundedSender, oneshot};
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||||
@ -35,14 +35,10 @@ impl BeaconConsensusEngineHandle {
|
|||||||
pub async fn new_payload(
|
pub async fn new_payload(
|
||||||
&self,
|
&self,
|
||||||
payload: ExecutionPayload,
|
payload: ExecutionPayload,
|
||||||
parent_beacon_block_root: Option<H256>,
|
cancun_fields: Option<CancunPayloadFields>,
|
||||||
) -> Result<PayloadStatus, BeaconOnNewPayloadError> {
|
) -> Result<PayloadStatus, BeaconOnNewPayloadError> {
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
let _ = self.to_engine.send(BeaconEngineMessage::NewPayload {
|
let _ = self.to_engine.send(BeaconEngineMessage::NewPayload { payload, cancun_fields, tx });
|
||||||
payload,
|
|
||||||
parent_beacon_block_root,
|
|
||||||
tx,
|
|
||||||
});
|
|
||||||
rx.await.map_err(|_| BeaconOnNewPayloadError::EngineUnavailable)?
|
rx.await.map_err(|_| BeaconOnNewPayloadError::EngineUnavailable)?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,10 +5,9 @@ use crate::{
|
|||||||
use futures::{future::Either, FutureExt};
|
use futures::{future::Either, FutureExt};
|
||||||
use reth_interfaces::consensus::ForkchoiceState;
|
use reth_interfaces::consensus::ForkchoiceState;
|
||||||
use reth_payload_builder::error::PayloadBuilderError;
|
use reth_payload_builder::error::PayloadBuilderError;
|
||||||
use reth_primitives::H256;
|
|
||||||
use reth_rpc_types::engine::{
|
use reth_rpc_types::engine::{
|
||||||
ExecutionPayload, ForkChoiceUpdateResult, ForkchoiceUpdateError, ForkchoiceUpdated,
|
CancunPayloadFields, ExecutionPayload, ForkChoiceUpdateResult, ForkchoiceUpdateError,
|
||||||
PayloadAttributes, PayloadId, PayloadStatus, PayloadStatusEnum,
|
ForkchoiceUpdated, PayloadAttributes, PayloadId, PayloadStatus, PayloadStatusEnum,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
@ -147,8 +146,8 @@ pub enum BeaconEngineMessage {
|
|||||||
NewPayload {
|
NewPayload {
|
||||||
/// The execution payload received by Engine API.
|
/// The execution payload received by Engine API.
|
||||||
payload: ExecutionPayload,
|
payload: ExecutionPayload,
|
||||||
/// The parent beacon block root, if any.
|
/// The cancun-related newPayload fields, if any.
|
||||||
parent_beacon_block_root: Option<H256>,
|
cancun_fields: Option<CancunPayloadFields>,
|
||||||
/// The sender for returning payload status result.
|
/// The sender for returning payload status result.
|
||||||
tx: oneshot::Sender<Result<PayloadStatus, BeaconOnNewPayloadError>>,
|
tx: oneshot::Sender<Result<PayloadStatus, BeaconOnNewPayloadError>>,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -31,7 +31,8 @@ use reth_provider::{
|
|||||||
};
|
};
|
||||||
use reth_prune::Pruner;
|
use reth_prune::Pruner;
|
||||||
use reth_rpc_types::engine::{
|
use reth_rpc_types::engine::{
|
||||||
ExecutionPayload, PayloadAttributes, PayloadStatus, PayloadStatusEnum, PayloadValidationError,
|
CancunPayloadFields, ExecutionPayload, PayloadAttributes, PayloadStatus, PayloadStatusEnum,
|
||||||
|
PayloadValidationError,
|
||||||
};
|
};
|
||||||
use reth_stages::{ControlFlow, Pipeline, PipelineError};
|
use reth_stages::{ControlFlow, Pipeline, PipelineError};
|
||||||
use reth_tasks::TaskSpawner;
|
use reth_tasks::TaskSpawner;
|
||||||
@ -1049,13 +1050,16 @@ where
|
|||||||
///
|
///
|
||||||
/// This returns a [`PayloadStatus`] that represents the outcome of a processed new payload and
|
/// This returns a [`PayloadStatus`] that represents the outcome of a processed new payload and
|
||||||
/// returns an error if an internal error occurred.
|
/// returns an error if an internal error occurred.
|
||||||
#[instrument(level = "trace", skip(self, payload, parent_beacon_block_root), fields(block_hash= ?payload.block_hash(), block_number = %payload.block_number(), is_pipeline_idle = %self.sync.is_pipeline_idle()), target = "consensus::engine")]
|
#[instrument(level = "trace", skip(self, payload, cancun_fields), fields(block_hash= ?payload.block_hash(), block_number = %payload.block_number(), is_pipeline_idle = %self.sync.is_pipeline_idle()), target = "consensus::engine")]
|
||||||
fn on_new_payload(
|
fn on_new_payload(
|
||||||
&mut self,
|
&mut self,
|
||||||
payload: ExecutionPayload,
|
payload: ExecutionPayload,
|
||||||
parent_beacon_block_root: Option<H256>,
|
cancun_fields: Option<CancunPayloadFields>,
|
||||||
) -> Result<PayloadStatus, BeaconOnNewPayloadError> {
|
) -> Result<PayloadStatus, BeaconOnNewPayloadError> {
|
||||||
let block = match self.ensure_well_formed_payload(payload, parent_beacon_block_root) {
|
let block = match self.ensure_well_formed_payload(
|
||||||
|
payload,
|
||||||
|
cancun_fields.map(|fields| fields.parent_beacon_block_root),
|
||||||
|
) {
|
||||||
Ok(block) => block,
|
Ok(block) => block,
|
||||||
Err(status) => return Ok(status),
|
Err(status) => return Ok(status),
|
||||||
};
|
};
|
||||||
@ -1727,9 +1731,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BeaconEngineMessage::NewPayload { payload, parent_beacon_block_root, tx } => {
|
BeaconEngineMessage::NewPayload { payload, cancun_fields, tx } => {
|
||||||
this.metrics.new_payload_messages.increment(1);
|
this.metrics.new_payload_messages.increment(1);
|
||||||
let res = this.on_new_payload(payload, parent_beacon_block_root);
|
let res = this.on_new_payload(payload, cancun_fields);
|
||||||
let _ = tx.send(res);
|
let _ = tx.send(res);
|
||||||
}
|
}
|
||||||
BeaconEngineMessage::TransitionConfigurationExchanged => {
|
BeaconEngineMessage::TransitionConfigurationExchanged => {
|
||||||
|
|||||||
@ -27,7 +27,9 @@ use reth_provider::{
|
|||||||
};
|
};
|
||||||
use reth_prune::Pruner;
|
use reth_prune::Pruner;
|
||||||
use reth_revm::Factory;
|
use reth_revm::Factory;
|
||||||
use reth_rpc_types::engine::{ExecutionPayload, ForkchoiceState, ForkchoiceUpdated, PayloadStatus};
|
use reth_rpc_types::engine::{
|
||||||
|
CancunPayloadFields, ExecutionPayload, ForkchoiceState, ForkchoiceUpdated, PayloadStatus,
|
||||||
|
};
|
||||||
use reth_stages::{
|
use reth_stages::{
|
||||||
sets::DefaultStages, stages::HeaderSyncMode, test_utils::TestStages, ExecOutput, Pipeline,
|
sets::DefaultStages, stages::HeaderSyncMode, test_utils::TestStages, ExecOutput, Pipeline,
|
||||||
StageError,
|
StageError,
|
||||||
@ -69,9 +71,9 @@ impl<DB> TestEnv<DB> {
|
|||||||
pub async fn send_new_payload<T: Into<ExecutionPayload>>(
|
pub async fn send_new_payload<T: Into<ExecutionPayload>>(
|
||||||
&self,
|
&self,
|
||||||
payload: T,
|
payload: T,
|
||||||
parent_beacon_block_root: Option<H256>,
|
cancun_fields: Option<CancunPayloadFields>,
|
||||||
) -> Result<PayloadStatus, BeaconOnNewPayloadError> {
|
) -> Result<PayloadStatus, BeaconOnNewPayloadError> {
|
||||||
self.engine_handle.new_payload(payload.into(), parent_beacon_block_root).await
|
self.engine_handle.new_payload(payload.into(), cancun_fields).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends the `ExecutionPayload` message to the consensus engine and retries if the engine
|
/// Sends the `ExecutionPayload` message to the consensus engine and retries if the engine
|
||||||
@ -79,11 +81,11 @@ impl<DB> TestEnv<DB> {
|
|||||||
pub async fn send_new_payload_retry_on_syncing<T: Into<ExecutionPayload>>(
|
pub async fn send_new_payload_retry_on_syncing<T: Into<ExecutionPayload>>(
|
||||||
&self,
|
&self,
|
||||||
payload: T,
|
payload: T,
|
||||||
parent_beacon_block_root: Option<H256>,
|
cancun_fields: Option<CancunPayloadFields>,
|
||||||
) -> Result<PayloadStatus, BeaconOnNewPayloadError> {
|
) -> Result<PayloadStatus, BeaconOnNewPayloadError> {
|
||||||
let payload: ExecutionPayload = payload.into();
|
let payload: ExecutionPayload = payload.into();
|
||||||
loop {
|
loop {
|
||||||
let result = self.send_new_payload(payload.clone(), parent_beacon_block_root).await?;
|
let result = self.send_new_payload(payload.clone(), cancun_fields.clone()).await?;
|
||||||
if !result.is_syncing() {
|
if !result.is_syncing() {
|
||||||
return Ok(result)
|
return Ok(result)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use reth_primitives::{BlockHash, BlockHashOrNumber, BlockNumber, ChainSpec, Hard
|
|||||||
use reth_provider::{BlockReader, EvmEnvProvider, HeaderProvider, StateProviderFactory};
|
use reth_provider::{BlockReader, EvmEnvProvider, HeaderProvider, StateProviderFactory};
|
||||||
use reth_rpc_api::EngineApiServer;
|
use reth_rpc_api::EngineApiServer;
|
||||||
use reth_rpc_types::engine::{
|
use reth_rpc_types::engine::{
|
||||||
ExecutionPayload, ExecutionPayloadBodiesV1, ExecutionPayloadEnvelopeV2,
|
CancunPayloadFields, ExecutionPayload, ExecutionPayloadBodiesV1, ExecutionPayloadEnvelopeV2,
|
||||||
ExecutionPayloadEnvelopeV3, ExecutionPayloadV1, ExecutionPayloadV3, ForkchoiceUpdated,
|
ExecutionPayloadEnvelopeV3, ExecutionPayloadV1, ExecutionPayloadV3, ForkchoiceUpdated,
|
||||||
PayloadAttributes, PayloadId, PayloadStatus, TransitionConfiguration, CAPABILITIES,
|
PayloadAttributes, PayloadId, PayloadStatus, TransitionConfiguration, CAPABILITIES,
|
||||||
};
|
};
|
||||||
@ -92,8 +92,8 @@ where
|
|||||||
/// See also <https://github.com/ethereum/execution-apis/blob/fe8e13c288c592ec154ce25c534e26cb7ce0530d/src/engine/cancun.md#engine_newpayloadv3>
|
/// See also <https://github.com/ethereum/execution-apis/blob/fe8e13c288c592ec154ce25c534e26cb7ce0530d/src/engine/cancun.md#engine_newpayloadv3>
|
||||||
pub async fn new_payload_v3(
|
pub async fn new_payload_v3(
|
||||||
&self,
|
&self,
|
||||||
payload: ExecutionPayloadV1,
|
payload: ExecutionPayloadV3,
|
||||||
_versioned_hashes: Vec<H256>,
|
versioned_hashes: Vec<H256>,
|
||||||
parent_beacon_block_root: H256,
|
parent_beacon_block_root: H256,
|
||||||
) -> EngineApiResult<PayloadStatus> {
|
) -> EngineApiResult<PayloadStatus> {
|
||||||
let payload = ExecutionPayload::from(payload);
|
let payload = ExecutionPayload::from(payload);
|
||||||
@ -101,8 +101,10 @@ where
|
|||||||
PayloadOrAttributes::from_execution_payload(&payload, Some(parent_beacon_block_root));
|
PayloadOrAttributes::from_execution_payload(&payload, Some(parent_beacon_block_root));
|
||||||
self.validate_version_specific_fields(EngineApiMessageVersion::V3, &payload_or_attrs)?;
|
self.validate_version_specific_fields(EngineApiMessageVersion::V3, &payload_or_attrs)?;
|
||||||
|
|
||||||
|
let cancun_fields = CancunPayloadFields { versioned_hashes, parent_beacon_block_root };
|
||||||
|
|
||||||
// TODO: validate versioned hashes and figure out what to do with parent_beacon_block_root
|
// TODO: validate versioned hashes and figure out what to do with parent_beacon_block_root
|
||||||
Ok(self.inner.beacon_consensus.new_payload(payload, Some(parent_beacon_block_root)).await?)
|
Ok(self.inner.beacon_consensus.new_payload(payload, Some(cancun_fields)).await?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a message to the beacon consensus engine to update the fork choice _without_
|
/// Sends a message to the beacon consensus engine to update the fork choice _without_
|
||||||
|
|||||||
17
crates/rpc/rpc-types/src/eth/engine/cancun.rs
Normal file
17
crates/rpc/rpc-types/src/eth/engine/cancun.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//! Contains types related to the Cancun hardfork that will be used by RPC to communicate with the
|
||||||
|
//! beacon consensus engine.
|
||||||
|
use reth_primitives::H256;
|
||||||
|
|
||||||
|
/// Fields introduced in `engine_newPayloadV3` that are not present in the `ExecutionPayload` RPC
|
||||||
|
/// object.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
/// <https://github.com/ethereum/execution-apis/blob/fe8e13c288c592ec154ce25c534e26cb7ce0530d/src/engine/cancun.md#request>
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
|
||||||
|
pub struct CancunPayloadFields {
|
||||||
|
/// The parent beacon block root.
|
||||||
|
pub parent_beacon_block_root: H256,
|
||||||
|
|
||||||
|
/// The expected blob versioned hashes.
|
||||||
|
pub versioned_hashes: Vec<H256>,
|
||||||
|
}
|
||||||
@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
|
mod cancun;
|
||||||
mod forkchoice;
|
mod forkchoice;
|
||||||
mod payload;
|
mod payload;
|
||||||
mod transition;
|
mod transition;
|
||||||
|
|
||||||
pub use self::{forkchoice::*, payload::*, transition::*};
|
pub use self::{cancun::*, forkchoice::*, payload::*, transition::*};
|
||||||
|
|
||||||
/// The list of supported Engine capabilities
|
/// The list of supported Engine capabilities
|
||||||
pub const CAPABILITIES: [&str; 9] = [
|
pub const CAPABILITIES: [&str; 9] = [
|
||||||
|
|||||||
Reference in New Issue
Block a user