mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(api,rpc): improve engine API abstraction (#6871)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -174,7 +174,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "alloy-eips"
|
name = "alloy-eips"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
|
source = "git+https://github.com/alloy-rs/alloy?rev=785c667#785c667813a6c76794044b943df58fc6e397734d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
"alloy-rlp",
|
"alloy-rlp",
|
||||||
@ -184,7 +184,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "alloy-genesis"
|
name = "alloy-genesis"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
|
source = "git+https://github.com/alloy-rs/alloy?rev=785c667#785c667813a6c76794044b943df58fc6e397734d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
"alloy-rpc-types",
|
"alloy-rpc-types",
|
||||||
@ -206,7 +206,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "alloy-node-bindings"
|
name = "alloy-node-bindings"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
|
source = "git+https://github.com/alloy-rs/alloy?rev=785c667#785c667813a6c76794044b943df58fc6e397734d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy-genesis",
|
"alloy-genesis",
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
@ -267,7 +267,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "alloy-rpc-engine-types"
|
name = "alloy-rpc-engine-types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
|
source = "git+https://github.com/alloy-rs/alloy?rev=785c667#785c667813a6c76794044b943df58fc6e397734d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
"alloy-rlp",
|
"alloy-rlp",
|
||||||
@ -282,7 +282,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "alloy-rpc-trace-types"
|
name = "alloy-rpc-trace-types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
|
source = "git+https://github.com/alloy-rs/alloy?rev=785c667#785c667813a6c76794044b943df58fc6e397734d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
"alloy-rpc-types",
|
"alloy-rpc-types",
|
||||||
@ -293,7 +293,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "alloy-rpc-types"
|
name = "alloy-rpc-types"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/alloy-rs/alloy?rev=76c70fb#76c70fb9d44ace661bbf33408c2527e3874c964e"
|
source = "git+https://github.com/alloy-rs/alloy?rev=785c667#785c667813a6c76794044b943df58fc6e397734d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
"alloy-rlp",
|
"alloy-rlp",
|
||||||
@ -7039,7 +7039,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "revm-inspectors"
|
name = "revm-inspectors"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=75a187b#75a187ba967a29b30af2e5e848073c755068da06"
|
source = "git+https://github.com/paradigmxyz/evm-inspectors?rev=7068d39#7068d395eb56ee5fee8e6acc7c32d3dbc4616f3b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy-primitives",
|
"alloy-primitives",
|
||||||
"alloy-rpc-trace-types",
|
"alloy-rpc-trace-types",
|
||||||
|
|||||||
14
Cargo.toml
14
Cargo.toml
@ -178,7 +178,7 @@ reth-trie = { path = "crates/trie" }
|
|||||||
# revm
|
# revm
|
||||||
revm = { version = "6.1.0", features = ["std", "secp256k1"], default-features = false }
|
revm = { version = "6.1.0", features = ["std", "secp256k1"], default-features = false }
|
||||||
revm-primitives = { version = "2.1.0", features = ["std"], default-features = false }
|
revm-primitives = { version = "2.1.0", features = ["std"], default-features = false }
|
||||||
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "75a187b" }
|
revm-inspectors = { git = "https://github.com/paradigmxyz/evm-inspectors", rev = "7068d39" }
|
||||||
|
|
||||||
# eth
|
# eth
|
||||||
alloy-chains = { version = "0.1", feature = ["serde", "rlp", "arbitrary"] }
|
alloy-chains = { version = "0.1", feature = ["serde", "rlp", "arbitrary"] }
|
||||||
@ -187,12 +187,12 @@ alloy-dyn-abi = "0.6"
|
|||||||
alloy-sol-types = "0.6"
|
alloy-sol-types = "0.6"
|
||||||
alloy-rlp = "0.3"
|
alloy-rlp = "0.3"
|
||||||
alloy-trie = "0.3"
|
alloy-trie = "0.3"
|
||||||
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
|
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "785c667" }
|
||||||
alloy-rpc-trace-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
|
alloy-rpc-trace-types = { git = "https://github.com/alloy-rs/alloy", rev = "785c667" }
|
||||||
alloy-rpc-engine-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
|
alloy-rpc-engine-types = { git = "https://github.com/alloy-rs/alloy", rev = "785c667" }
|
||||||
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
|
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "785c667" }
|
||||||
alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
|
alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "785c667" }
|
||||||
alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
|
alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "785c667" }
|
||||||
ethers-core = { version = "2.0", default-features = false }
|
ethers-core = { version = "2.0", default-features = false }
|
||||||
ethers-providers = { version = "2.0", default-features = false }
|
ethers-providers = { version = "2.0", default-features = false }
|
||||||
ethers-signers = { version = "2.0", default-features = false }
|
ethers-signers = { version = "2.0", default-features = false }
|
||||||
|
|||||||
@ -296,8 +296,9 @@ impl Command {
|
|||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "optimism")]
|
#[cfg(feature = "optimism")]
|
||||||
let payload_builder = reth_optimism_payload_builder::OptimismPayloadBuilder::default()
|
let payload_builder =
|
||||||
.compute_pending_block();
|
reth_optimism_payload_builder::OptimismPayloadBuilder::new(self.chain.clone())
|
||||||
|
.compute_pending_block();
|
||||||
|
|
||||||
#[cfg(not(feature = "optimism"))]
|
#[cfg(not(feature = "optimism"))]
|
||||||
let payload_builder = reth_ethereum_payload_builder::EthereumPayloadBuilder::default();
|
let payload_builder = reth_ethereum_payload_builder::EthereumPayloadBuilder::default();
|
||||||
|
|||||||
@ -169,7 +169,8 @@ impl Command {
|
|||||||
|
|
||||||
// Optimism's payload builder is implemented on the OptimismPayloadBuilder type.
|
// Optimism's payload builder is implemented on the OptimismPayloadBuilder type.
|
||||||
#[cfg(feature = "optimism")]
|
#[cfg(feature = "optimism")]
|
||||||
let payload_builder = reth_optimism_payload_builder::OptimismPayloadBuilder::default();
|
let payload_builder =
|
||||||
|
reth_optimism_payload_builder::OptimismPayloadBuilder::new(self.chain.clone());
|
||||||
|
|
||||||
let payload_generator = BasicPayloadJobGenerator::with_builder(
|
let payload_generator = BasicPayloadJobGenerator::with_builder(
|
||||||
blockchain_db.clone(),
|
blockchain_db.clone(),
|
||||||
|
|||||||
@ -6,6 +6,7 @@ use reth_primitives::{ChainSpec, Hardfork};
|
|||||||
/// Contains traits to abstract over payload attributes types and default implementations of the
|
/// Contains traits to abstract over payload attributes types and default implementations of the
|
||||||
/// [PayloadAttributes] trait for ethereum mainnet and optimism types.
|
/// [PayloadAttributes] trait for ethereum mainnet and optimism types.
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
|
use serde::{de::DeserializeOwned, ser::Serialize};
|
||||||
pub use traits::{BuiltPayload, PayloadAttributes, PayloadBuilderAttributes};
|
pub use traits::{BuiltPayload, PayloadAttributes, PayloadBuilderAttributes};
|
||||||
|
|
||||||
/// Contains error types used in the traits defined in this crate.
|
/// Contains error types used in the traits defined in this crate.
|
||||||
@ -18,7 +19,7 @@ pub use payload::PayloadOrAttributes;
|
|||||||
|
|
||||||
/// The types that are used by the engine API.
|
/// The types that are used by the engine API.
|
||||||
pub trait EngineTypes:
|
pub trait EngineTypes:
|
||||||
serde::de::DeserializeOwned + fmt::Debug + Unpin + Send + Sync + Clone
|
serde::de::DeserializeOwned + Serialize + fmt::Debug + Unpin + Send + Sync + Clone
|
||||||
{
|
{
|
||||||
/// The RPC payload attributes type the CL node emits via the engine API.
|
/// The RPC payload attributes type the CL node emits via the engine API.
|
||||||
type PayloadAttributes: PayloadAttributes + Unpin;
|
type PayloadAttributes: PayloadAttributes + Unpin;
|
||||||
@ -29,7 +30,19 @@ pub trait EngineTypes:
|
|||||||
+ Unpin;
|
+ Unpin;
|
||||||
|
|
||||||
/// The built payload type.
|
/// The built payload type.
|
||||||
type BuiltPayload: BuiltPayload + Clone + Unpin;
|
type BuiltPayload: BuiltPayload
|
||||||
|
+ Clone
|
||||||
|
+ Unpin
|
||||||
|
+ TryInto<Self::ExecutionPayloadV1>
|
||||||
|
+ TryInto<Self::ExecutionPayloadV2>
|
||||||
|
+ TryInto<Self::ExecutionPayloadV3>;
|
||||||
|
|
||||||
|
/// Execution Payload V1 type.
|
||||||
|
type ExecutionPayloadV1: DeserializeOwned + Serialize + Clone + Unpin + Send + Sync + 'static;
|
||||||
|
/// Execution Payload V2 type.
|
||||||
|
type ExecutionPayloadV2: DeserializeOwned + Serialize + Clone + Unpin + Send + Sync + 'static;
|
||||||
|
/// Execution Payload V3 type.
|
||||||
|
type ExecutionPayloadV3: DeserializeOwned + Serialize + Clone + Unpin + Send + Sync + 'static;
|
||||||
|
|
||||||
/// Validates the presence or exclusion of fork-specific fields based on the payload attributes
|
/// Validates the presence or exclusion of fork-specific fields based on the payload attributes
|
||||||
/// and the message version.
|
/// and the message version.
|
||||||
|
|||||||
@ -4,12 +4,8 @@ use reth_primitives::{
|
|||||||
Address, ChainSpec, Header, SealedBlock, Withdrawals, B256, U256,
|
Address, ChainSpec, Header, SealedBlock, Withdrawals, B256, U256,
|
||||||
};
|
};
|
||||||
use reth_rpc_types::{
|
use reth_rpc_types::{
|
||||||
engine::{
|
engine::{OptimismPayloadAttributes, PayloadAttributes as EthPayloadAttributes, PayloadId},
|
||||||
ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, OptimismPayloadAttributes,
|
|
||||||
PayloadAttributes as EthPayloadAttributes, PayloadId,
|
|
||||||
},
|
|
||||||
withdrawal::Withdrawal,
|
withdrawal::Withdrawal,
|
||||||
ExecutionPayloadV1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents a built payload type that contains a built [SealedBlock] and can be converted into
|
/// Represents a built payload type that contains a built [SealedBlock] and can be converted into
|
||||||
@ -20,15 +16,6 @@ pub trait BuiltPayload: Send + Sync + std::fmt::Debug {
|
|||||||
|
|
||||||
/// Returns the fees collected for the built block
|
/// Returns the fees collected for the built block
|
||||||
fn fees(&self) -> U256;
|
fn fees(&self) -> U256;
|
||||||
|
|
||||||
/// Converts the type into the response expected by `engine_getPayloadV1`
|
|
||||||
fn into_v1_payload(self) -> ExecutionPayloadV1;
|
|
||||||
|
|
||||||
/// Converts the type into the response expected by `engine_getPayloadV2`
|
|
||||||
fn into_v2_payload(self) -> ExecutionPayloadEnvelopeV2;
|
|
||||||
|
|
||||||
/// Converts the type into the response expected by `engine_getPayloadV3`
|
|
||||||
fn into_v3_payload(self) -> ExecutionPayloadEnvelopeV3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This can be implemented by types that describe a currently running payload job.
|
/// This can be implemented by types that describe a currently running payload job.
|
||||||
|
|||||||
@ -4,10 +4,16 @@ use reth_node_api::{
|
|||||||
};
|
};
|
||||||
use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes};
|
use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes};
|
||||||
use reth_primitives::ChainSpec;
|
use reth_primitives::ChainSpec;
|
||||||
use reth_rpc_types::engine::PayloadAttributes as EthPayloadAttributes;
|
use reth_rpc_types::{
|
||||||
|
engine::{
|
||||||
|
ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3,
|
||||||
|
PayloadAttributes as EthPayloadAttributes,
|
||||||
|
},
|
||||||
|
ExecutionPayloadV1,
|
||||||
|
};
|
||||||
|
|
||||||
/// 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, serde::Deserialize)]
|
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct EthEngineTypes;
|
pub struct EthEngineTypes;
|
||||||
|
|
||||||
@ -15,6 +21,9 @@ impl EngineTypes for EthEngineTypes {
|
|||||||
type PayloadAttributes = EthPayloadAttributes;
|
type PayloadAttributes = EthPayloadAttributes;
|
||||||
type PayloadBuilderAttributes = EthPayloadBuilderAttributes;
|
type PayloadBuilderAttributes = EthPayloadBuilderAttributes;
|
||||||
type BuiltPayload = EthBuiltPayload;
|
type BuiltPayload = EthBuiltPayload;
|
||||||
|
type ExecutionPayloadV1 = ExecutionPayloadV1;
|
||||||
|
type ExecutionPayloadV2 = ExecutionPayloadEnvelopeV2;
|
||||||
|
type ExecutionPayloadV3 = ExecutionPayloadEnvelopeV3;
|
||||||
|
|
||||||
fn validate_version_specific_fields(
|
fn validate_version_specific_fields(
|
||||||
chain_spec: &ChainSpec,
|
chain_spec: &ChainSpec,
|
||||||
|
|||||||
@ -2,19 +2,27 @@ use reth_node_api::{
|
|||||||
engine::validate_parent_beacon_block_root_presence, AttributesValidationError,
|
engine::validate_parent_beacon_block_root_presence, AttributesValidationError,
|
||||||
EngineApiMessageVersion, EngineTypes, PayloadOrAttributes,
|
EngineApiMessageVersion, EngineTypes, PayloadOrAttributes,
|
||||||
};
|
};
|
||||||
use reth_payload_builder::{EthBuiltPayload, OptimismPayloadBuilderAttributes};
|
use reth_payload_builder::{OptimismBuiltPayload, OptimismPayloadBuilderAttributes};
|
||||||
use reth_primitives::{ChainSpec, Hardfork};
|
use reth_primitives::{ChainSpec, Hardfork};
|
||||||
use reth_rpc_types::engine::OptimismPayloadAttributes;
|
use reth_rpc_types::{
|
||||||
|
engine::{
|
||||||
|
ExecutionPayloadEnvelopeV2, OptimismExecutionPayloadEnvelopeV3, OptimismPayloadAttributes,
|
||||||
|
},
|
||||||
|
ExecutionPayloadV1,
|
||||||
|
};
|
||||||
|
|
||||||
/// The types used in the optimism beacon consensus engine.
|
/// The types used in the optimism beacon consensus engine.
|
||||||
#[derive(Debug, Default, Clone, serde::Deserialize)]
|
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct OptimismEngineTypes;
|
pub struct OptimismEngineTypes;
|
||||||
|
|
||||||
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 = OptimismBuiltPayload;
|
||||||
|
type ExecutionPayloadV1 = ExecutionPayloadV1;
|
||||||
|
type ExecutionPayloadV2 = ExecutionPayloadEnvelopeV2;
|
||||||
|
type ExecutionPayloadV3 = OptimismExecutionPayloadEnvelopeV3;
|
||||||
|
|
||||||
fn validate_version_specific_fields(
|
fn validate_version_specific_fields(
|
||||||
chain_spec: &ChainSpec,
|
chain_spec: &ChainSpec,
|
||||||
|
|||||||
@ -172,8 +172,9 @@ where
|
|||||||
ctx: &BuilderContext<Node>,
|
ctx: &BuilderContext<Node>,
|
||||||
pool: Pool,
|
pool: Pool,
|
||||||
) -> eyre::Result<PayloadBuilderHandle<Node::Engine>> {
|
) -> eyre::Result<PayloadBuilderHandle<Node::Engine>> {
|
||||||
let payload_builder = reth_optimism_payload_builder::OptimismPayloadBuilder::default()
|
let payload_builder =
|
||||||
.set_compute_pending_block(self.compute_pending_block);
|
reth_optimism_payload_builder::OptimismPayloadBuilder::new(ctx.chain_spec())
|
||||||
|
.set_compute_pending_block(self.compute_pending_block);
|
||||||
let conf = ctx.payload_builder_config();
|
let conf = ctx.payload_builder_config();
|
||||||
|
|
||||||
let payload_job_config = BasicPayloadJobGeneratorConfig::default()
|
let payload_job_config = BasicPayloadJobGeneratorConfig::default()
|
||||||
|
|||||||
@ -15,8 +15,8 @@ use futures_util::FutureExt;
|
|||||||
use reth_interfaces::RethResult;
|
use reth_interfaces::RethResult;
|
||||||
use reth_node_api::{BuiltPayload, PayloadBuilderAttributes};
|
use reth_node_api::{BuiltPayload, PayloadBuilderAttributes};
|
||||||
use reth_payload_builder::{
|
use reth_payload_builder::{
|
||||||
database::CachedReads, error::PayloadBuilderError, EthBuiltPayload, KeepPayloadJobAlive,
|
database::CachedReads, error::PayloadBuilderError, KeepPayloadJobAlive, PayloadId, PayloadJob,
|
||||||
PayloadId, PayloadJob, PayloadJobGenerator,
|
PayloadJobGenerator,
|
||||||
};
|
};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
bytes::BytesMut,
|
bytes::BytesMut,
|
||||||
@ -890,7 +890,7 @@ where
|
|||||||
///
|
///
|
||||||
/// This compares the total fees of the blocks, higher is better.
|
/// This compares the total fees of the blocks, higher is better.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn is_better_payload(best_payload: Option<&EthBuiltPayload>, new_fees: U256) -> bool {
|
pub fn is_better_payload(best_payload: Option<impl BuiltPayload>, new_fees: U256) -> bool {
|
||||||
if let Some(best_payload) = best_payload {
|
if let Some(best_payload) = best_payload {
|
||||||
new_fees > best_payload.fees()
|
new_fees > best_payload.fees()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -115,7 +115,7 @@ pub mod noop;
|
|||||||
#[cfg(any(test, feature = "test-utils"))]
|
#[cfg(any(test, feature = "test-utils"))]
|
||||||
pub mod test_utils;
|
pub mod test_utils;
|
||||||
|
|
||||||
pub use optimism::OptimismPayloadBuilderAttributes;
|
pub use optimism::{OptimismBuiltPayload, OptimismPayloadBuilderAttributes};
|
||||||
pub use payload::{EthBuiltPayload, EthPayloadBuilderAttributes};
|
pub use payload::{EthBuiltPayload, EthPayloadBuilderAttributes};
|
||||||
pub use reth_rpc_types::engine::PayloadId;
|
pub use reth_rpc_types::engine::PayloadId;
|
||||||
pub use service::{PayloadBuilderHandle, PayloadBuilderService, PayloadStore};
|
pub use service::{PayloadBuilderHandle, PayloadBuilderService, PayloadStore};
|
||||||
|
|||||||
@ -1,13 +1,21 @@
|
|||||||
use crate::EthPayloadBuilderAttributes;
|
use crate::EthPayloadBuilderAttributes;
|
||||||
use alloy_rlp::{Encodable, Error as DecodeError};
|
use alloy_rlp::{Encodable, Error as DecodeError};
|
||||||
use reth_node_api::PayloadBuilderAttributes;
|
use reth_node_api::{BuiltPayload, PayloadBuilderAttributes};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
revm::config::revm_spec_by_timestamp_after_merge,
|
revm::config::revm_spec_by_timestamp_after_merge,
|
||||||
revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId},
|
revm_primitives::{BlobExcessGasAndPrice, BlockEnv, CfgEnv, CfgEnvWithHandlerCfg, SpecId},
|
||||||
Address, ChainSpec, Header, TransactionSigned, Withdrawals, B256, U256,
|
Address, BlobTransactionSidecar, ChainSpec, Header, SealedBlock, TransactionSigned,
|
||||||
|
Withdrawals, B256, U256,
|
||||||
};
|
};
|
||||||
use reth_rpc_types::engine::{OptimismPayloadAttributes, PayloadId};
|
use reth_rpc_types::engine::{
|
||||||
use reth_rpc_types_compat::engine::payload::convert_standalone_withdraw_to_withdrawal;
|
ExecutionPayloadEnvelopeV2, ExecutionPayloadV1, OptimismExecutionPayloadEnvelopeV3,
|
||||||
|
OptimismPayloadAttributes, PayloadId,
|
||||||
|
};
|
||||||
|
use reth_rpc_types_compat::engine::payload::{
|
||||||
|
block_to_payload_v3, convert_block_to_payload_field_v2,
|
||||||
|
convert_standalone_withdraw_to_withdrawal, try_block_to_payload_v1,
|
||||||
|
};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// Optimism Payload Builder Attributes
|
/// Optimism Payload Builder Attributes
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
@ -152,6 +160,126 @@ impl PayloadBuilderAttributes for OptimismPayloadBuilderAttributes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Contains the built payload.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct OptimismBuiltPayload {
|
||||||
|
/// Identifier of the payload
|
||||||
|
pub(crate) id: PayloadId,
|
||||||
|
/// The built block
|
||||||
|
pub(crate) block: SealedBlock,
|
||||||
|
/// The fees of the block
|
||||||
|
pub(crate) fees: U256,
|
||||||
|
/// The blobs, proofs, and commitments in the block. If the block is pre-cancun, this will be
|
||||||
|
/// empty.
|
||||||
|
pub(crate) sidecars: Vec<BlobTransactionSidecar>,
|
||||||
|
/// The rollup's chainspec.
|
||||||
|
pub(crate) chain_spec: Arc<ChainSpec>,
|
||||||
|
/// The payload attributes.
|
||||||
|
pub(crate) attributes: OptimismPayloadBuilderAttributes,
|
||||||
|
}
|
||||||
|
|
||||||
|
// === impl BuiltPayload ===
|
||||||
|
|
||||||
|
impl OptimismBuiltPayload {
|
||||||
|
/// Initializes the payload with the given initial block.
|
||||||
|
pub fn new(
|
||||||
|
id: PayloadId,
|
||||||
|
block: SealedBlock,
|
||||||
|
fees: U256,
|
||||||
|
chain_spec: Arc<ChainSpec>,
|
||||||
|
attributes: OptimismPayloadBuilderAttributes,
|
||||||
|
) -> Self {
|
||||||
|
Self { id, block, fees, sidecars: Vec::new(), chain_spec, attributes }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the identifier of the payload.
|
||||||
|
pub fn id(&self) -> PayloadId {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the built block(sealed)
|
||||||
|
pub fn block(&self) -> &SealedBlock {
|
||||||
|
&self.block
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fees of the block
|
||||||
|
pub fn fees(&self) -> U256 {
|
||||||
|
self.fees
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds sidecars to the payload.
|
||||||
|
pub fn extend_sidecars(&mut self, sidecars: Vec<BlobTransactionSidecar>) {
|
||||||
|
self.sidecars.extend(sidecars)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuiltPayload for OptimismBuiltPayload {
|
||||||
|
fn block(&self) -> &SealedBlock {
|
||||||
|
&self.block
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fees(&self) -> U256 {
|
||||||
|
self.fees
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> BuiltPayload for &'a OptimismBuiltPayload {
|
||||||
|
fn block(&self) -> &SealedBlock {
|
||||||
|
(**self).block()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fees(&self) -> U256 {
|
||||||
|
(**self).fees()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// V1 engine_getPayloadV1 response
|
||||||
|
impl From<OptimismBuiltPayload> for ExecutionPayloadV1 {
|
||||||
|
fn from(value: OptimismBuiltPayload) -> Self {
|
||||||
|
try_block_to_payload_v1(value.block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// V2 engine_getPayloadV2 response
|
||||||
|
impl From<OptimismBuiltPayload> for ExecutionPayloadEnvelopeV2 {
|
||||||
|
fn from(value: OptimismBuiltPayload) -> Self {
|
||||||
|
let OptimismBuiltPayload { block, fees, .. } = value;
|
||||||
|
|
||||||
|
ExecutionPayloadEnvelopeV2 {
|
||||||
|
block_value: fees,
|
||||||
|
execution_payload: convert_block_to_payload_field_v2(block),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<OptimismBuiltPayload> for OptimismExecutionPayloadEnvelopeV3 {
|
||||||
|
fn from(value: OptimismBuiltPayload) -> Self {
|
||||||
|
let OptimismBuiltPayload { block, fees, sidecars, chain_spec, attributes, .. } = value;
|
||||||
|
|
||||||
|
let parent_beacon_block_root =
|
||||||
|
if chain_spec.is_cancun_active_at_timestamp(attributes.timestamp()) {
|
||||||
|
attributes.parent_beacon_block_root().unwrap_or(B256::ZERO)
|
||||||
|
} else {
|
||||||
|
B256::ZERO
|
||||||
|
};
|
||||||
|
OptimismExecutionPayloadEnvelopeV3 {
|
||||||
|
execution_payload: block_to_payload_v3(block.clone()),
|
||||||
|
block_value: fees,
|
||||||
|
// From the engine API spec:
|
||||||
|
//
|
||||||
|
// > Client software **MAY** use any heuristics to decide whether to set
|
||||||
|
// `shouldOverrideBuilder` flag or not. If client software does not implement any
|
||||||
|
// heuristic this flag **SHOULD** be set to `false`.
|
||||||
|
//
|
||||||
|
// Spec:
|
||||||
|
// <https://github.com/ethereum/execution-apis/blob/fe8e13c288c592ec154ce25c534e26cb7ce0530d/src/engine/cancun.md#specification-2>
|
||||||
|
should_override_builder: false,
|
||||||
|
blobs_bundle: sidecars.into_iter().map(Into::into).collect::<Vec<_>>().into(),
|
||||||
|
parent_beacon_block_root,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Generates the payload id for the configured payload from the [OptimismPayloadAttributes].
|
/// Generates the payload id for the configured payload from the [OptimismPayloadAttributes].
|
||||||
///
|
///
|
||||||
/// Returns an 8-byte identifier by hashing the payload components with sha256 hash.
|
/// Returns an 8-byte identifier by hashing the payload components with sha256 hash.
|
||||||
|
|||||||
@ -62,21 +62,6 @@ impl EthBuiltPayload {
|
|||||||
pub fn extend_sidecars(&mut self, sidecars: Vec<BlobTransactionSidecar>) {
|
pub fn extend_sidecars(&mut self, sidecars: Vec<BlobTransactionSidecar>) {
|
||||||
self.sidecars.extend(sidecars)
|
self.sidecars.extend(sidecars)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the type into the response expected by `engine_getPayloadV1`
|
|
||||||
pub fn into_v1_payload(self) -> ExecutionPayloadV1 {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts the type into the response expected by `engine_getPayloadV2`
|
|
||||||
pub fn into_v2_payload(self) -> ExecutionPayloadEnvelopeV2 {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts the type into the response expected by `engine_getPayloadV3`
|
|
||||||
pub fn into_v3_payload(self) -> ExecutionPayloadEnvelopeV3 {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuiltPayload for EthBuiltPayload {
|
impl BuiltPayload for EthBuiltPayload {
|
||||||
@ -87,17 +72,15 @@ impl BuiltPayload for EthBuiltPayload {
|
|||||||
fn fees(&self) -> U256 {
|
fn fees(&self) -> U256 {
|
||||||
self.fees
|
self.fees
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn into_v1_payload(self) -> ExecutionPayloadV1 {
|
impl<'a> BuiltPayload for &'a EthBuiltPayload {
|
||||||
self.into()
|
fn block(&self) -> &SealedBlock {
|
||||||
|
(**self).block()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_v2_payload(self) -> ExecutionPayloadEnvelopeV2 {
|
fn fees(&self) -> U256 {
|
||||||
self.into()
|
(**self).fees()
|
||||||
}
|
|
||||||
|
|
||||||
fn into_v3_payload(self) -> ExecutionPayloadEnvelopeV3 {
|
|
||||||
self.into()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,10 +120,6 @@ impl From<EthBuiltPayload> for ExecutionPayloadEnvelopeV3 {
|
|||||||
// <https://github.com/ethereum/execution-apis/blob/fe8e13c288c592ec154ce25c534e26cb7ce0530d/src/engine/cancun.md#specification-2>
|
// <https://github.com/ethereum/execution-apis/blob/fe8e13c288c592ec154ce25c534e26cb7ce0530d/src/engine/cancun.md#specification-2>
|
||||||
should_override_builder: false,
|
should_override_builder: false,
|
||||||
blobs_bundle: sidecars.into_iter().map(Into::into).collect::<Vec<_>>().into(),
|
blobs_bundle: sidecars.into_iter().map(Into::into).collect::<Vec<_>>().into(),
|
||||||
// Optimism-specific: Post-cancun, the parent beacon block root is included in the
|
|
||||||
// enveloped payload. We set this as `None` here so that optimism-specific
|
|
||||||
// handling can fill the value.
|
|
||||||
parent_beacon_block_root: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,14 +18,14 @@ mod builder {
|
|||||||
use crate::error::OptimismPayloadBuilderError;
|
use crate::error::OptimismPayloadBuilderError;
|
||||||
use reth_basic_payload_builder::*;
|
use reth_basic_payload_builder::*;
|
||||||
use reth_payload_builder::{
|
use reth_payload_builder::{
|
||||||
error::PayloadBuilderError, EthBuiltPayload, OptimismPayloadBuilderAttributes,
|
error::PayloadBuilderError, OptimismBuiltPayload, OptimismPayloadBuilderAttributes,
|
||||||
};
|
};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
constants::{BEACON_NONCE, EMPTY_RECEIPTS, EMPTY_TRANSACTIONS},
|
constants::{BEACON_NONCE, EMPTY_RECEIPTS, EMPTY_TRANSACTIONS},
|
||||||
eip4844::calculate_excess_blob_gas,
|
eip4844::calculate_excess_blob_gas,
|
||||||
proofs,
|
proofs,
|
||||||
revm::env::tx_env_with_recovered,
|
revm::env::tx_env_with_recovered,
|
||||||
Block, Hardfork, Header, IntoRecoveredTransaction, Receipt, Receipts, TxType,
|
Block, ChainSpec, Hardfork, Header, IntoRecoveredTransaction, Receipt, Receipts, TxType,
|
||||||
EMPTY_OMMER_ROOT_HASH, U256,
|
EMPTY_OMMER_ROOT_HASH, U256,
|
||||||
};
|
};
|
||||||
use reth_provider::{BundleStateWithReceipts, StateProviderFactory};
|
use reth_provider::{BundleStateWithReceipts, StateProviderFactory};
|
||||||
@ -36,18 +36,25 @@ mod builder {
|
|||||||
primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState},
|
primitives::{EVMError, EnvWithHandlerCfg, InvalidTransaction, ResultAndState},
|
||||||
DatabaseCommit, State,
|
DatabaseCommit, State,
|
||||||
};
|
};
|
||||||
|
use std::sync::Arc;
|
||||||
use tracing::{debug, trace, warn};
|
use tracing::{debug, trace, warn};
|
||||||
|
|
||||||
/// Optimism's payload builder
|
/// Optimism's payload builder
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
#[non_exhaustive]
|
|
||||||
pub struct OptimismPayloadBuilder {
|
pub struct OptimismPayloadBuilder {
|
||||||
/// The rollup's compute pending block configuration option.
|
/// The rollup's compute pending block configuration option.
|
||||||
// TODO(clabby): Implement this feature.
|
// TODO(clabby): Implement this feature.
|
||||||
compute_pending_block: bool,
|
compute_pending_block: bool,
|
||||||
|
/// The rollup's chain spec.
|
||||||
|
chain_spec: Arc<ChainSpec>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OptimismPayloadBuilder {
|
impl OptimismPayloadBuilder {
|
||||||
|
/// OptimismPayloadBuilder constructor.
|
||||||
|
pub fn new(chain_spec: Arc<ChainSpec>) -> Self {
|
||||||
|
Self { compute_pending_block: true, chain_spec }
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the rollup's compute pending block configuration option.
|
/// Sets the rollup's compute pending block configuration option.
|
||||||
pub fn set_compute_pending_block(mut self, compute_pending_block: bool) -> Self {
|
pub fn set_compute_pending_block(mut self, compute_pending_block: bool) -> Self {
|
||||||
self.compute_pending_block = compute_pending_block;
|
self.compute_pending_block = compute_pending_block;
|
||||||
@ -63,6 +70,12 @@ mod builder {
|
|||||||
pub fn is_compute_pending_block(&self) -> bool {
|
pub fn is_compute_pending_block(&self) -> bool {
|
||||||
self.compute_pending_block
|
self.compute_pending_block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the rollup's chainspec.
|
||||||
|
pub fn set_chain_spec(mut self, chain_spec: Arc<ChainSpec>) -> Self {
|
||||||
|
self.chain_spec = chain_spec;
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of the [PayloadBuilder] trait for [OptimismPayloadBuilder].
|
/// Implementation of the [PayloadBuilder] trait for [OptimismPayloadBuilder].
|
||||||
@ -72,19 +85,29 @@ mod builder {
|
|||||||
Pool: TransactionPool,
|
Pool: TransactionPool,
|
||||||
{
|
{
|
||||||
type Attributes = OptimismPayloadBuilderAttributes;
|
type Attributes = OptimismPayloadBuilderAttributes;
|
||||||
type BuiltPayload = EthBuiltPayload;
|
type BuiltPayload = OptimismBuiltPayload;
|
||||||
|
|
||||||
fn try_build(
|
fn try_build(
|
||||||
&self,
|
&self,
|
||||||
args: BuildArguments<Pool, Client, OptimismPayloadBuilderAttributes, EthBuiltPayload>,
|
args: BuildArguments<
|
||||||
) -> Result<BuildOutcome<EthBuiltPayload>, PayloadBuilderError> {
|
Pool,
|
||||||
|
Client,
|
||||||
|
OptimismPayloadBuilderAttributes,
|
||||||
|
OptimismBuiltPayload,
|
||||||
|
>,
|
||||||
|
) -> Result<BuildOutcome<OptimismBuiltPayload>, PayloadBuilderError> {
|
||||||
optimism_payload_builder(args, self.compute_pending_block)
|
optimism_payload_builder(args, self.compute_pending_block)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_missing_payload(
|
fn on_missing_payload(
|
||||||
&self,
|
&self,
|
||||||
args: BuildArguments<Pool, Client, OptimismPayloadBuilderAttributes, EthBuiltPayload>,
|
args: BuildArguments<
|
||||||
) -> Option<EthBuiltPayload> {
|
Pool,
|
||||||
|
Client,
|
||||||
|
OptimismPayloadBuilderAttributes,
|
||||||
|
OptimismBuiltPayload,
|
||||||
|
>,
|
||||||
|
) -> Option<OptimismBuiltPayload> {
|
||||||
// In Optimism, the PayloadAttributes can specify a `no_tx_pool` option that implies we
|
// In Optimism, the PayloadAttributes can specify a `no_tx_pool` option that implies we
|
||||||
// should not pull transactions from the tx pool. In this case, we build the payload
|
// should not pull transactions from the tx pool. In this case, we build the payload
|
||||||
// upfront with the list of transactions sent in the attributes without caring about
|
// upfront with the list of transactions sent in the attributes without caring about
|
||||||
@ -102,7 +125,7 @@ mod builder {
|
|||||||
fn build_empty_payload(
|
fn build_empty_payload(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
config: PayloadConfig<Self::Attributes>,
|
config: PayloadConfig<Self::Attributes>,
|
||||||
) -> Result<EthBuiltPayload, PayloadBuilderError> {
|
) -> Result<OptimismBuiltPayload, PayloadBuilderError> {
|
||||||
let extra_data = config.extra_data();
|
let extra_data = config.extra_data();
|
||||||
let PayloadConfig {
|
let PayloadConfig {
|
||||||
initialized_block_env,
|
initialized_block_env,
|
||||||
@ -205,10 +228,12 @@ mod builder {
|
|||||||
let block = Block { header, body: vec![], ommers: vec![], withdrawals };
|
let block = Block { header, body: vec![], ommers: vec![], withdrawals };
|
||||||
let sealed_block = block.seal_slow();
|
let sealed_block = block.seal_slow();
|
||||||
|
|
||||||
Ok(EthBuiltPayload::new(
|
Ok(OptimismBuiltPayload::new(
|
||||||
attributes.payload_attributes.payload_id(),
|
attributes.payload_attributes.payload_id(),
|
||||||
sealed_block,
|
sealed_block,
|
||||||
U256::ZERO,
|
U256::ZERO,
|
||||||
|
chain_spec,
|
||||||
|
attributes,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,9 +248,9 @@ mod builder {
|
|||||||
/// a result indicating success with the payload or an error in case of failure.
|
/// a result indicating success with the payload or an error in case of failure.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn optimism_payload_builder<Pool, Client>(
|
pub(crate) fn optimism_payload_builder<Pool, Client>(
|
||||||
args: BuildArguments<Pool, Client, OptimismPayloadBuilderAttributes, EthBuiltPayload>,
|
args: BuildArguments<Pool, Client, OptimismPayloadBuilderAttributes, OptimismBuiltPayload>,
|
||||||
_compute_pending_block: bool,
|
_compute_pending_block: bool,
|
||||||
) -> Result<BuildOutcome<EthBuiltPayload>, PayloadBuilderError>
|
) -> Result<BuildOutcome<OptimismBuiltPayload>, PayloadBuilderError>
|
||||||
where
|
where
|
||||||
Client: StateProviderFactory,
|
Client: StateProviderFactory,
|
||||||
Pool: TransactionPool,
|
Pool: TransactionPool,
|
||||||
@ -491,7 +516,7 @@ mod builder {
|
|||||||
&mut db,
|
&mut db,
|
||||||
&chain_spec,
|
&chain_spec,
|
||||||
attributes.payload_attributes.timestamp,
|
attributes.payload_attributes.timestamp,
|
||||||
attributes.payload_attributes.withdrawals,
|
attributes.clone().payload_attributes.withdrawals,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// merge all transitions into bundle state, this would apply the withdrawal balance changes
|
// merge all transitions into bundle state, this would apply the withdrawal balance changes
|
||||||
@ -567,8 +592,13 @@ mod builder {
|
|||||||
let sealed_block = block.seal_slow();
|
let sealed_block = block.seal_slow();
|
||||||
debug!(target: "payload_builder", ?sealed_block, "sealed built block");
|
debug!(target: "payload_builder", ?sealed_block, "sealed built block");
|
||||||
|
|
||||||
let mut payload =
|
let mut payload = OptimismBuiltPayload::new(
|
||||||
EthBuiltPayload::new(attributes.payload_attributes.id, sealed_block, total_fees);
|
attributes.payload_attributes.id,
|
||||||
|
sealed_block,
|
||||||
|
total_fees,
|
||||||
|
chain_spec,
|
||||||
|
attributes,
|
||||||
|
);
|
||||||
|
|
||||||
// extend the payload with the blob sidecars from the executed txs
|
// extend the payload with the blob sidecars from the executed txs
|
||||||
payload.extend_sidecars(blob_sidecars);
|
payload.extend_sidecars(blob_sidecars);
|
||||||
|
|||||||
@ -353,7 +353,7 @@ pub static BASE_MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
|||||||
|
|
||||||
/// A wrapper around [BaseFeeParams] that allows for specifying constant or dynamic EIP-1559
|
/// A wrapper around [BaseFeeParams] that allows for specifying constant or dynamic EIP-1559
|
||||||
/// parameters based on the active [Hardfork].
|
/// parameters based on the active [Hardfork].
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum BaseFeeParamsKind {
|
pub enum BaseFeeParamsKind {
|
||||||
/// Constant [BaseFeeParams]; used for chains that don't have dynamic EIP-1559 parameters
|
/// Constant [BaseFeeParams]; used for chains that don't have dynamic EIP-1559 parameters
|
||||||
@ -377,7 +377,7 @@ impl From<ForkBaseFeeParams> for BaseFeeParamsKind {
|
|||||||
|
|
||||||
/// A type alias to a vector of tuples of [Hardfork] and [BaseFeeParams], sorted by [Hardfork]
|
/// A type alias to a vector of tuples of [Hardfork] and [BaseFeeParams], sorted by [Hardfork]
|
||||||
/// activation order. This is used to specify dynamic EIP-1559 parameters for chains like Optimism.
|
/// activation order. This is used to specify dynamic EIP-1559 parameters for chains like Optimism.
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub struct ForkBaseFeeParams(Vec<(Hardfork, BaseFeeParams)>);
|
pub struct ForkBaseFeeParams(Vec<(Hardfork, BaseFeeParams)>);
|
||||||
|
|
||||||
impl From<Vec<(Hardfork, BaseFeeParams)>> for ForkBaseFeeParams {
|
impl From<Vec<(Hardfork, BaseFeeParams)>> for ForkBaseFeeParams {
|
||||||
@ -456,7 +456,7 @@ impl BaseFeeParams {
|
|||||||
/// - Meta-information about the chain (the chain ID)
|
/// - Meta-information about the chain (the chain ID)
|
||||||
/// - The genesis block of the chain ([`Genesis`])
|
/// - The genesis block of the chain ([`Genesis`])
|
||||||
/// - What hardforks are activated, and under which conditions
|
/// - What hardforks are activated, and under which conditions
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ChainSpec {
|
pub struct ChainSpec {
|
||||||
/// The chain ID
|
/// The chain ID
|
||||||
pub chain: Chain,
|
pub chain: Chain,
|
||||||
|
|||||||
@ -8,9 +8,8 @@ use reth_node_api::EngineTypes;
|
|||||||
use reth_primitives::{Address, BlockHash, BlockId, BlockNumberOrTag, Bytes, B256, U256, U64};
|
use reth_primitives::{Address, BlockHash, BlockId, BlockNumberOrTag, Bytes, B256, U256, U64};
|
||||||
use reth_rpc_types::{
|
use reth_rpc_types::{
|
||||||
engine::{
|
engine::{
|
||||||
ExecutionPayloadBodiesV1, ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3,
|
ExecutionPayloadBodiesV1, ExecutionPayloadInputV2, ExecutionPayloadV1, ExecutionPayloadV3,
|
||||||
ExecutionPayloadInputV2, ExecutionPayloadV1, ExecutionPayloadV3, ForkchoiceState,
|
ForkchoiceState, ForkchoiceUpdated, PayloadId, PayloadStatus, TransitionConfiguration,
|
||||||
ForkchoiceUpdated, PayloadId, PayloadStatus, TransitionConfiguration,
|
|
||||||
},
|
},
|
||||||
state::StateOverride,
|
state::StateOverride,
|
||||||
BlockOverrides, Filter, Log, RichBlock, SyncStatus, TransactionRequest,
|
BlockOverrides, Filter, Log, RichBlock, SyncStatus, TransactionRequest,
|
||||||
@ -96,7 +95,7 @@ pub trait EngineApi<Engine: EngineTypes> {
|
|||||||
/// Note:
|
/// Note:
|
||||||
/// > Provider software MAY stop the corresponding build process after serving this call.
|
/// > Provider software MAY stop the corresponding build process after serving this call.
|
||||||
#[method(name = "getPayloadV1")]
|
#[method(name = "getPayloadV1")]
|
||||||
async fn get_payload_v1(&self, payload_id: PayloadId) -> RpcResult<ExecutionPayloadV1>;
|
async fn get_payload_v1(&self, payload_id: PayloadId) -> RpcResult<Engine::ExecutionPayloadV1>;
|
||||||
|
|
||||||
/// See also <https://github.com/ethereum/execution-apis/blob/6709c2a795b707202e93c4f2867fa0bf2640a84f/src/engine/shanghai.md#engine_getpayloadv2>
|
/// See also <https://github.com/ethereum/execution-apis/blob/6709c2a795b707202e93c4f2867fa0bf2640a84f/src/engine/shanghai.md#engine_getpayloadv2>
|
||||||
///
|
///
|
||||||
@ -104,7 +103,7 @@ pub trait EngineApi<Engine: EngineTypes> {
|
|||||||
/// payload build process at the time of receiving this call. Note:
|
/// payload build process at the time of receiving this call. Note:
|
||||||
/// > Provider software MAY stop the corresponding build process after serving this call.
|
/// > Provider software MAY stop the corresponding build process after serving this call.
|
||||||
#[method(name = "getPayloadV2")]
|
#[method(name = "getPayloadV2")]
|
||||||
async fn get_payload_v2(&self, payload_id: PayloadId) -> RpcResult<ExecutionPayloadEnvelopeV2>;
|
async fn get_payload_v2(&self, payload_id: PayloadId) -> RpcResult<Engine::ExecutionPayloadV2>;
|
||||||
|
|
||||||
/// Post Cancun payload handler which also returns a blobs bundle.
|
/// Post Cancun payload handler which also returns a blobs bundle.
|
||||||
///
|
///
|
||||||
@ -114,7 +113,7 @@ pub trait EngineApi<Engine: EngineTypes> {
|
|||||||
/// payload build process at the time of receiving this call. Note:
|
/// payload build process at the time of receiving this call. Note:
|
||||||
/// > Provider software MAY stop the corresponding build process after serving this call.
|
/// > Provider software MAY stop the corresponding build process after serving this call.
|
||||||
#[method(name = "getPayloadV3")]
|
#[method(name = "getPayloadV3")]
|
||||||
async fn get_payload_v3(&self, payload_id: PayloadId) -> RpcResult<ExecutionPayloadEnvelopeV3>;
|
async fn get_payload_v3(&self, payload_id: PayloadId) -> RpcResult<Engine::ExecutionPayloadV3>;
|
||||||
|
|
||||||
/// See also <https://github.com/ethereum/execution-apis/blob/6452a6b194d7db269bf1dbd087a267251d3cc7f8/src/engine/shanghai.md#engine_getpayloadbodiesbyhashv1>
|
/// See also <https://github.com/ethereum/execution-apis/blob/6452a6b194d7db269bf1dbd087a267251d3cc7f8/src/engine/shanghai.md#engine_getpayloadbodiesbyhashv1>
|
||||||
#[method(name = "getPayloadBodiesByHashV1")]
|
#[method(name = "getPayloadBodiesByHashV1")]
|
||||||
|
|||||||
@ -4,17 +4,17 @@ 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, BuiltPayload, EngineApiMessageVersion, EngineTypes,
|
validate_payload_timestamp, EngineApiMessageVersion, EngineTypes, PayloadAttributes,
|
||||||
PayloadAttributes, PayloadBuilderAttributes, PayloadOrAttributes,
|
PayloadBuilderAttributes, 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};
|
||||||
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::{
|
||||||
CancunPayloadFields, ExecutionPayload, ExecutionPayloadBodiesV1, ExecutionPayloadEnvelopeV2,
|
CancunPayloadFields, ExecutionPayload, ExecutionPayloadBodiesV1, ExecutionPayloadInputV2,
|
||||||
ExecutionPayloadEnvelopeV3, ExecutionPayloadInputV2, ExecutionPayloadV1, ExecutionPayloadV3,
|
ExecutionPayloadV1, ExecutionPayloadV3, ForkchoiceUpdated, PayloadId, PayloadStatus,
|
||||||
ForkchoiceUpdated, PayloadId, PayloadStatus, TransitionConfiguration, CAPABILITIES,
|
TransitionConfiguration, CAPABILITIES,
|
||||||
};
|
};
|
||||||
use reth_rpc_types_compat::engine::payload::{
|
use reth_rpc_types_compat::engine::payload::{
|
||||||
convert_payload_input_v2_to_payload, convert_to_payload_body_v1,
|
convert_payload_input_v2_to_payload, convert_to_payload_body_v1,
|
||||||
@ -22,7 +22,7 @@ use reth_rpc_types_compat::engine::payload::{
|
|||||||
use reth_tasks::TaskSpawner;
|
use reth_tasks::TaskSpawner;
|
||||||
use std::{sync::Arc, time::Instant};
|
use std::{sync::Arc, time::Instant};
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use tracing::trace;
|
use tracing::{trace, warn};
|
||||||
|
|
||||||
/// The Engine API response sender.
|
/// The Engine API response sender.
|
||||||
pub type EngineApiSender<Ok> = oneshot::Sender<EngineApiResult<Ok>>;
|
pub type EngineApiSender<Ok> = oneshot::Sender<EngineApiResult<Ok>>;
|
||||||
@ -202,14 +202,18 @@ where
|
|||||||
pub async fn get_payload_v1(
|
pub async fn get_payload_v1(
|
||||||
&self,
|
&self,
|
||||||
payload_id: PayloadId,
|
payload_id: PayloadId,
|
||||||
) -> EngineApiResult<ExecutionPayloadV1> {
|
) -> EngineApiResult<EngineT::ExecutionPayloadV1> {
|
||||||
Ok(self
|
self.inner
|
||||||
.inner
|
|
||||||
.payload_store
|
.payload_store
|
||||||
.resolve(payload_id)
|
.resolve(payload_id)
|
||||||
.await
|
.await
|
||||||
.ok_or(EngineApiError::UnknownPayload)?
|
.ok_or(EngineApiError::UnknownPayload)?
|
||||||
.map(|payload| payload.into_v1_payload())?)
|
.map_err(|_| EngineApiError::UnknownPayload)?
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| {
|
||||||
|
warn!("could not transform built payload into ExecutionPayloadV1");
|
||||||
|
EngineApiError::UnknownPayload
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the most recent version of the payload that is available in the corresponding
|
/// Returns the most recent version of the payload that is available in the corresponding
|
||||||
@ -222,7 +226,7 @@ where
|
|||||||
pub async fn get_payload_v2(
|
pub async fn get_payload_v2(
|
||||||
&self,
|
&self,
|
||||||
payload_id: PayloadId,
|
payload_id: PayloadId,
|
||||||
) -> EngineApiResult<ExecutionPayloadEnvelopeV2> {
|
) -> EngineApiResult<EngineT::ExecutionPayloadV2> {
|
||||||
// First we fetch the payload attributes to check the timestamp
|
// First we fetch the payload attributes to check the timestamp
|
||||||
let attributes = self.get_payload_attributes(payload_id).await?;
|
let attributes = self.get_payload_attributes(payload_id).await?;
|
||||||
|
|
||||||
@ -234,13 +238,17 @@ where
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Now resolve the payload
|
// Now resolve the payload
|
||||||
Ok(self
|
self.inner
|
||||||
.inner
|
|
||||||
.payload_store
|
.payload_store
|
||||||
.resolve(payload_id)
|
.resolve(payload_id)
|
||||||
.await
|
.await
|
||||||
.ok_or(EngineApiError::UnknownPayload)?
|
.ok_or(EngineApiError::UnknownPayload)?
|
||||||
.map(|payload| payload.into_v2_payload())?)
|
.map_err(|_| EngineApiError::UnknownPayload)?
|
||||||
|
.try_into()
|
||||||
|
.map_err(|_| {
|
||||||
|
warn!("could not transform built payload into ExecutionPayloadV2");
|
||||||
|
EngineApiError::UnknownPayload
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the most recent version of the payload that is available in the corresponding
|
/// Returns the most recent version of the payload that is available in the corresponding
|
||||||
@ -253,7 +261,7 @@ where
|
|||||||
pub async fn get_payload_v3(
|
pub async fn get_payload_v3(
|
||||||
&self,
|
&self,
|
||||||
payload_id: PayloadId,
|
payload_id: PayloadId,
|
||||||
) -> EngineApiResult<ExecutionPayloadEnvelopeV3> {
|
) -> EngineApiResult<EngineT::ExecutionPayloadV3> {
|
||||||
// First we fetch the payload attributes to check the timestamp
|
// First we fetch the payload attributes to check the timestamp
|
||||||
let attributes = self.get_payload_attributes(payload_id).await?;
|
let attributes = self.get_payload_attributes(payload_id).await?;
|
||||||
|
|
||||||
@ -265,25 +273,17 @@ where
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Now resolve the payload
|
// Now resolve the payload
|
||||||
let mut resolved_payload = self
|
self.inner
|
||||||
.inner
|
|
||||||
.payload_store
|
.payload_store
|
||||||
.resolve(payload_id)
|
.resolve(payload_id)
|
||||||
.await
|
.await
|
||||||
.ok_or(EngineApiError::UnknownPayload)?
|
.ok_or(EngineApiError::UnknownPayload)?
|
||||||
.map(|payload| payload.into_v3_payload())?;
|
.map_err(|_| EngineApiError::UnknownPayload)?
|
||||||
|
.try_into()
|
||||||
// After `Cancun` is enabled on optimism, an extra field `parent_beacon_block_root` is
|
.map_err(|_| {
|
||||||
// included in the enveloped V3 payload. On ethereum, this field is not included.
|
warn!("could not transform built payload into ExecutionPayloadV2");
|
||||||
if self.inner.chain_spec.is_optimism() &&
|
EngineApiError::UnknownPayload
|
||||||
self.inner
|
})
|
||||||
.chain_spec
|
|
||||||
.is_fork_active_at_timestamp(Hardfork::Cancun, attributes.timestamp())
|
|
||||||
{
|
|
||||||
resolved_payload.parent_beacon_block_root = attributes.parent_beacon_block_root();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(resolved_payload)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the execution payload bodies by the range starting at `start`, containing `count`
|
/// Returns the execution payload bodies by the range starting at `start`, containing `count`
|
||||||
@ -581,7 +581,10 @@ where
|
|||||||
///
|
///
|
||||||
/// Note:
|
/// Note:
|
||||||
/// > Provider software MAY stop the corresponding build process after serving this call.
|
/// > Provider software MAY stop the corresponding build process after serving this call.
|
||||||
async fn get_payload_v1(&self, payload_id: PayloadId) -> RpcResult<ExecutionPayloadV1> {
|
async fn get_payload_v1(
|
||||||
|
&self,
|
||||||
|
payload_id: PayloadId,
|
||||||
|
) -> RpcResult<EngineT::ExecutionPayloadV1> {
|
||||||
trace!(target: "rpc::engine", "Serving engine_getPayloadV1");
|
trace!(target: "rpc::engine", "Serving engine_getPayloadV1");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let res = EngineApi::get_payload_v1(self, payload_id).await;
|
let res = EngineApi::get_payload_v1(self, payload_id).await;
|
||||||
@ -598,7 +601,10 @@ where
|
|||||||
///
|
///
|
||||||
/// Note:
|
/// Note:
|
||||||
/// > Provider software MAY stop the corresponding build process after serving this call.
|
/// > Provider software MAY stop the corresponding build process after serving this call.
|
||||||
async fn get_payload_v2(&self, payload_id: PayloadId) -> RpcResult<ExecutionPayloadEnvelopeV2> {
|
async fn get_payload_v2(
|
||||||
|
&self,
|
||||||
|
payload_id: PayloadId,
|
||||||
|
) -> RpcResult<EngineT::ExecutionPayloadV2> {
|
||||||
trace!(target: "rpc::engine", "Serving engine_getPayloadV2");
|
trace!(target: "rpc::engine", "Serving engine_getPayloadV2");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let res = EngineApi::get_payload_v2(self, payload_id).await;
|
let res = EngineApi::get_payload_v2(self, payload_id).await;
|
||||||
@ -615,7 +621,10 @@ where
|
|||||||
///
|
///
|
||||||
/// Note:
|
/// Note:
|
||||||
/// > Provider software MAY stop the corresponding build process after serving this call.
|
/// > Provider software MAY stop the corresponding build process after serving this call.
|
||||||
async fn get_payload_v3(&self, payload_id: PayloadId) -> RpcResult<ExecutionPayloadEnvelopeV3> {
|
async fn get_payload_v3(
|
||||||
|
&self,
|
||||||
|
payload_id: PayloadId,
|
||||||
|
) -> RpcResult<EngineT::ExecutionPayloadV3> {
|
||||||
trace!(target: "rpc::engine", "Serving engine_getPayloadV3");
|
trace!(target: "rpc::engine", "Serving engine_getPayloadV3");
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let res = EngineApi::get_payload_v3(self, payload_id).await;
|
let res = EngineApi::get_payload_v3(self, payload_id).await;
|
||||||
|
|||||||
@ -45,6 +45,7 @@ allow = [
|
|||||||
"ISC",
|
"ISC",
|
||||||
"Unicode-DFS-2016",
|
"Unicode-DFS-2016",
|
||||||
"Unlicense",
|
"Unlicense",
|
||||||
|
"Unicode-3.0",
|
||||||
# https://github.com/briansmith/ring/issues/902
|
# https://github.com/briansmith/ring/issues/902
|
||||||
"LicenseRef-ring",
|
"LicenseRef-ring",
|
||||||
# https://github.com/briansmith/webpki/issues/148
|
# https://github.com/briansmith/webpki/issues/148
|
||||||
|
|||||||
@ -48,8 +48,12 @@ use reth_payload_builder::{
|
|||||||
};
|
};
|
||||||
use reth_primitives::{Address, ChainSpec, Genesis, Header, Withdrawals, B256};
|
use reth_primitives::{Address, ChainSpec, Genesis, Header, Withdrawals, B256};
|
||||||
use reth_rpc_types::{
|
use reth_rpc_types::{
|
||||||
engine::{PayloadAttributes as EthPayloadAttributes, PayloadId},
|
engine::{
|
||||||
|
ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3,
|
||||||
|
PayloadAttributes as EthPayloadAttributes, PayloadId,
|
||||||
|
},
|
||||||
withdrawal::Withdrawal,
|
withdrawal::Withdrawal,
|
||||||
|
ExecutionPayloadV1,
|
||||||
};
|
};
|
||||||
use reth_tracing::{RethTracer, Tracer};
|
use reth_tracing::{RethTracer, Tracer};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -95,7 +99,9 @@ impl PayloadAttributes for CustomPayloadAttributes {
|
|||||||
|
|
||||||
// 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 {
|
||||||
return Err(AttributesValidationError::invalid_params(CustomError::CustomFieldIsNotZero))
|
return Err(AttributesValidationError::invalid_params(
|
||||||
|
CustomError::CustomFieldIsNotZero,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -153,7 +159,7 @@ impl PayloadBuilderAttributes for CustomPayloadBuilderAttributes {
|
|||||||
|
|
||||||
/// Custom engine types - uses a custom payload attributes RPC type, but uses the default
|
/// Custom engine types - uses a custom payload attributes RPC type, but uses the default
|
||||||
/// payload builder attributes type.
|
/// payload builder attributes type.
|
||||||
#[derive(Clone, Debug, Default, Deserialize)]
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct CustomEngineTypes;
|
pub struct CustomEngineTypes;
|
||||||
|
|
||||||
@ -161,6 +167,9 @@ impl EngineTypes for CustomEngineTypes {
|
|||||||
type PayloadAttributes = CustomPayloadAttributes;
|
type PayloadAttributes = CustomPayloadAttributes;
|
||||||
type PayloadBuilderAttributes = CustomPayloadBuilderAttributes;
|
type PayloadBuilderAttributes = CustomPayloadBuilderAttributes;
|
||||||
type BuiltPayload = EthBuiltPayload;
|
type BuiltPayload = EthBuiltPayload;
|
||||||
|
type ExecutionPayloadV1 = ExecutionPayloadV1;
|
||||||
|
type ExecutionPayloadV2 = ExecutionPayloadEnvelopeV2;
|
||||||
|
type ExecutionPayloadV3 = ExecutionPayloadEnvelopeV3;
|
||||||
|
|
||||||
fn validate_version_specific_fields(
|
fn validate_version_specific_fields(
|
||||||
chain_spec: &ChainSpec,
|
chain_spec: &ChainSpec,
|
||||||
|
|||||||
Reference in New Issue
Block a user