Skip to content

Commit

Permalink
feat(api,rpc): improve engine API abstraction (#6871)
Browse files Browse the repository at this point in the history
Co-authored-by: Matthias Seitz <[email protected]>
  • Loading branch information
2 people authored and rkrasiuk committed Mar 9, 2024
1 parent 7bee4a0 commit e320968
Show file tree
Hide file tree
Showing 20 changed files with 334 additions and 141 deletions.
14 changes: 7 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ reth-trie = { path = "crates/trie" }
# revm
revm = { version = "6.1.0", features = ["std", "secp256k1"], 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
alloy-chains = { version = "0.1", feature = ["serde", "rlp", "arbitrary"] }
Expand All @@ -181,12 +181,12 @@ alloy-dyn-abi = "0.6"
alloy-sol-types = "0.6"
alloy-rlp = "0.3"
alloy-trie = "0.3"
alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-rpc-trace-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-rpc-engine-types = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "76c70fb" }
alloy-eips = { 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 = "785c667" }
alloy-rpc-engine-types = { git = "https://github.com/alloy-rs/alloy", rev = "785c667" }
alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "785c667" }
alloy-node-bindings = { git = "https://github.com/alloy-rs/alloy", rev = "785c667" }
alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "785c667" }
ethers-core = { version = "2.0", default-features = false }
ethers-providers = { version = "2.0", default-features = false }
ethers-signers = { version = "2.0", default-features = false }
Expand Down
5 changes: 3 additions & 2 deletions bin/reth/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,9 @@ impl<DB: Database + DatabaseMetrics + DatabaseMetadata + 'static> NodeBuilderWit
// TODO: stateful node builder should handle this in with_payload_builder
// Optimism's payload builder is implemented on the OptimismPayloadBuilder type.
#[cfg(feature = "optimism")]
let payload_builder = reth_optimism_payload_builder::OptimismPayloadBuilder::default()
.set_compute_pending_block(self.config.builder.compute_pending_block);
let payload_builder =
reth_optimism_payload_builder::OptimismPayloadBuilder::new(self.config.chain.clone())
.set_compute_pending_block(self.config.builder.compute_pending_block);

#[cfg(feature = "optimism")]
let payload_builder: PayloadBuilderHandle<OptimismEngineTypes> =
Expand Down
5 changes: 3 additions & 2 deletions bin/reth/src/commands/debug_cmd/build_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,9 @@ impl Command {
);

#[cfg(feature = "optimism")]
let payload_builder = reth_optimism_payload_builder::OptimismPayloadBuilder::default()
.compute_pending_block();
let payload_builder =
reth_optimism_payload_builder::OptimismPayloadBuilder::new(self.chain.clone())
.compute_pending_block();

#[cfg(not(feature = "optimism"))]
let payload_builder = reth_ethereum_payload_builder::EthereumPayloadBuilder::default();
Expand Down
3 changes: 2 additions & 1 deletion bin/reth/src/commands/debug_cmd/replay_engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ impl Command {

// Optimism's payload builder is implemented on the OptimismPayloadBuilder type.
#[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(
blockchain_db.clone(),
Expand Down
17 changes: 15 additions & 2 deletions crates/node-api/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use reth_primitives::{ChainSpec, Hardfork};
/// Contains traits to abstract over payload attributes types and default implementations of the
/// [PayloadAttributes] trait for ethereum mainnet and optimism types.
pub mod traits;
use serde::{de::DeserializeOwned, ser::Serialize};
pub use traits::{BuiltPayload, PayloadAttributes, PayloadBuilderAttributes};

/// Contains error types used in the traits defined in this crate.
Expand All @@ -18,7 +19,7 @@ pub use payload::PayloadOrAttributes;

/// The types that are used by the engine API.
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.
type PayloadAttributes: PayloadAttributes + Unpin;
Expand All @@ -29,7 +30,19 @@ pub trait EngineTypes:
+ Unpin;

/// 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
/// and the message version.
Expand Down
15 changes: 1 addition & 14 deletions crates/node-api/src/engine/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@ use reth_primitives::{
Address, ChainSpec, Header, SealedBlock, Withdrawals, B256, U256,
};
use reth_rpc_types::{
engine::{
ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, OptimismPayloadAttributes,
PayloadAttributes as EthPayloadAttributes, PayloadId,
},
engine::{OptimismPayloadAttributes, PayloadAttributes as EthPayloadAttributes, PayloadId},
withdrawal::Withdrawal,
ExecutionPayloadV1,
};

/// Represents a built payload type that contains a built [SealedBlock] and can be converted into
Expand All @@ -20,15 +16,6 @@ pub trait BuiltPayload: Send + Sync + std::fmt::Debug {

/// Returns the fees collected for the built block
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.
Expand Down
13 changes: 11 additions & 2 deletions crates/node-ethereum/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@ use reth_node_api::{
};
use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes};
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.
#[derive(Debug, Default, Clone, serde::Deserialize)]
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
#[non_exhaustive]
pub struct EthEngineTypes;

impl EngineTypes for EthEngineTypes {
type PayloadAttributes = EthPayloadAttributes;
type PayloadBuilderAttributes = EthPayloadBuilderAttributes;
type BuiltPayload = EthBuiltPayload;
type ExecutionPayloadV1 = ExecutionPayloadV1;
type ExecutionPayloadV2 = ExecutionPayloadEnvelopeV2;
type ExecutionPayloadV3 = ExecutionPayloadEnvelopeV3;

fn validate_version_specific_fields(
chain_spec: &ChainSpec,
Expand Down
16 changes: 12 additions & 4 deletions crates/node-optimism/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,27 @@ use reth_node_api::{
engine::validate_parent_beacon_block_root_presence, AttributesValidationError,
EngineApiMessageVersion, EngineTypes, PayloadOrAttributes,
};
use reth_payload_builder::{EthBuiltPayload, OptimismPayloadBuilderAttributes};
use reth_payload_builder::{OptimismBuiltPayload, OptimismPayloadBuilderAttributes};
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.
#[derive(Debug, Default, Clone, serde::Deserialize)]
#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)]
#[non_exhaustive]
pub struct OptimismEngineTypes;

impl EngineTypes for OptimismEngineTypes {
type PayloadAttributes = OptimismPayloadAttributes;
type PayloadBuilderAttributes = OptimismPayloadBuilderAttributes;
type BuiltPayload = EthBuiltPayload;
type BuiltPayload = OptimismBuiltPayload;
type ExecutionPayloadV1 = ExecutionPayloadV1;
type ExecutionPayloadV2 = ExecutionPayloadEnvelopeV2;
type ExecutionPayloadV3 = OptimismExecutionPayloadEnvelopeV3;

fn validate_version_specific_fields(
chain_spec: &ChainSpec,
Expand Down
26 changes: 22 additions & 4 deletions crates/node-optimism/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,26 @@ where
}
}

/// A basic optimism payload service.
/// A basic optimism payload service builder
#[derive(Debug, Default, Clone)]
#[non_exhaustive]
pub struct OptimismPayloadBuilder;
pub struct OptimismPayloadBuilder {
/// By default the pending block equals the latest block
/// to save resources and not leak txs from the tx-pool,
/// this flag enables computing of the pending block
/// from the tx-pool instead.
///
/// If `compute_pending_block` is not enabled, the payload builder
/// will use the payload attributes from the latest block. Note
/// that this flag is not yet functional.
pub compute_pending_block: bool,
}

impl OptimismPayloadBuilder {
/// Create a new instance with the given `compute_pending_block` flag.
pub const fn new(compute_pending_block: bool) -> Self {
Self { compute_pending_block }
}
}

impl<Node, Pool> PayloadServiceBuilder<Node, Pool> for OptimismPayloadBuilder
where
Expand All @@ -133,7 +149,9 @@ where
ctx: &BuilderContext<Node>,
pool: Pool,
) -> eyre::Result<PayloadBuilderHandle<Node::Engine>> {
let payload_builder = reth_optimism_payload_builder::OptimismPayloadBuilder::default();
let payload_builder =
reth_optimism_payload_builder::OptimismPayloadBuilder::new(ctx.chain_spec())
.set_compute_pending_block(self.compute_pending_block);
let conf = ctx.payload_builder_config();

let payload_job_config = BasicPayloadJobGeneratorConfig::default()
Expand Down
6 changes: 3 additions & 3 deletions crates/payload/basic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ use futures_util::FutureExt;
use reth_interfaces::RethResult;
use reth_node_api::{BuiltPayload, PayloadBuilderAttributes};
use reth_payload_builder::{
database::CachedReads, error::PayloadBuilderError, EthBuiltPayload, KeepPayloadJobAlive,
PayloadId, PayloadJob, PayloadJobGenerator,
database::CachedReads, error::PayloadBuilderError, KeepPayloadJobAlive, PayloadId, PayloadJob,
PayloadJobGenerator,
};
use reth_primitives::{
bytes::BytesMut,
Expand Down Expand Up @@ -889,7 +889,7 @@ where
///
/// This compares the total fees of the blocks, higher is better.
#[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 {
new_fees > best_payload.fees()
} else {
Expand Down
2 changes: 1 addition & 1 deletion crates/payload/builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub mod noop;
#[cfg(any(test, feature = "test-utils"))]
pub mod test_utils;

pub use optimism::OptimismPayloadBuilderAttributes;
pub use optimism::{OptimismBuiltPayload, OptimismPayloadBuilderAttributes};
pub use payload::{EthBuiltPayload, EthPayloadBuilderAttributes};
pub use reth_rpc_types::engine::PayloadId;
pub use service::{PayloadBuilderHandle, PayloadBuilderService, PayloadStore};
Expand Down
Loading

0 comments on commit e320968

Please sign in to comment.