From 230f7eb9d3a38125c096ba8747e8d5bf3c5e8016 Mon Sep 17 00:00:00 2001 From: Derek Cofausper <256792747+decofe@users.noreply.github.com> Date: Sat, 28 Mar 2026 07:45:13 +0000 Subject: [PATCH 1/8] refactor(reth-bench): remove op-alloy dependencies via PayloadConverter trait Introduces a PayloadConverter trait that abstracts chain-specific block-to-payload and payload-to-engine-params conversions. Provides EthereumPayloadConverter as the default implementation, removing the need for op-alloy-consensus and op-alloy-rpc-types-engine dependencies. Co-authored-by: Matthias Seitz <19890894+mattsse@users.noreply.github.com> Amp-Thread-ID: https://ampcode.com/threads/T-019d32ff-4f3d-761d-a844-5e5be8780a61 --- Cargo.lock | 3 +- bin/reth-bench/Cargo.toml | 3 +- bin/reth-bench/src/bench/context.rs | 10 -- bin/reth-bench/src/bench/mod.rs | 15 ++- bin/reth-bench/src/bench/new_payload_fcu.rs | 10 +- bin/reth-bench/src/bench/new_payload_only.rs | 10 +- .../src/bench/send_invalid_payload/mod.rs | 25 ++--- bin/reth-bench/src/bench/send_payload.rs | 55 ++------- bin/reth-bench/src/main.rs | 6 +- bin/reth-bench/src/payload_converter.rs | 106 ++++++++++++++++++ bin/reth-bench/src/valid_payload.rs | 101 ++--------------- 11 files changed, 167 insertions(+), 177 deletions(-) create mode 100644 bin/reth-bench/src/payload_converter.rs diff --git a/Cargo.lock b/Cargo.lock index d0f0f7e68e9..dfa7294fb1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7638,6 +7638,7 @@ dependencies = [ name = "reth-bench" version = "1.11.3" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-json-rpc", "alloy-primitives", @@ -7656,8 +7657,6 @@ dependencies = [ "eyre", "futures", "humantime", - "op-alloy-consensus", - "op-alloy-rpc-types-engine", "reqwest 0.13.2", "reth-cli-runner", "reth-cli-util", diff --git a/bin/reth-bench/Cargo.toml b/bin/reth-bench/Cargo.toml index abcc47f6259..1d5e2c4dee6 100644 --- a/bin/reth-bench/Cargo.toml +++ b/bin/reth-bench/Cargo.toml @@ -26,6 +26,7 @@ reth-rpc-api.workspace = true reth-tracing.workspace = true # alloy +alloy-consensus.workspace = true alloy-eips.workspace = true alloy-json-rpc.workspace = true @@ -38,8 +39,6 @@ alloy-transport-http.workspace = true alloy-transport-ipc.workspace = true alloy-transport-ws.workspace = true alloy-transport.workspace = true -op-alloy-consensus = { workspace = true, features = ["alloy-compat"] } -op-alloy-rpc-types-engine = { workspace = true, features = ["serde"] } # reqwest reqwest.workspace = true diff --git a/bin/reth-bench/src/bench/context.rs b/bin/reth-bench/src/bench/context.rs index 4f68a5f742d..4ec0e557251 100644 --- a/bin/reth-bench/src/bench/context.rs +++ b/bin/reth-bench/src/bench/context.rs @@ -3,7 +3,6 @@ use crate::{authenticated_transport::AuthenticatedTransportConnect, bench_mode::BenchMode}; use alloy_eips::BlockNumberOrTag; -use alloy_primitives::address; use alloy_provider::{network::AnyNetwork, Provider, RootProvider}; use alloy_rpc_client::ClientBuilder; use alloy_rpc_types_engine::JwtSecret; @@ -27,8 +26,6 @@ pub(crate) struct BenchContext { pub(crate) benchmark_mode: BenchMode, /// The next block to fetch. pub(crate) next_block: u64, - /// Whether the chain is an OP rollup. - pub(crate) is_optimism: bool, /// Whether to use `reth_newPayload` endpoint instead of `engine_newPayload*`. pub(crate) use_reth_namespace: bool, /// Whether to fetch and replay RLP-encoded blocks. @@ -70,12 +67,6 @@ impl BenchContext { .http(rpc_url.parse()?); let block_provider = RootProvider::::new(client); - // Check if this is an OP chain by checking code at a predeploy address. - let is_optimism = !block_provider - .get_code_at(address!("0x420000000000000000000000000000000000000F")) - .await? - .is_empty(); - // construct the authenticated provider let auth_jwt = bench_args .auth_jwtsecret @@ -175,7 +166,6 @@ impl BenchContext { block_provider, benchmark_mode, next_block, - is_optimism, use_reth_namespace, rlp_blocks, wait_for_persistence, diff --git a/bin/reth-bench/src/bench/mod.rs b/bin/reth-bench/src/bench/mod.rs index 1f171d85a68..0b3bf1d066b 100644 --- a/bin/reth-bench/src/bench/mod.rs +++ b/bin/reth-bench/src/bench/mod.rs @@ -1,5 +1,6 @@ //! `reth benchmark` command. Collection of various benchmarking routines. +use crate::payload_converter::PayloadConverter; use clap::{Parser, Subcommand}; use reth_cli_runner::CliContext; use reth_node_core::args::LogArgs; @@ -88,17 +89,21 @@ pub enum Subcommands { impl BenchmarkCommand { /// Execute `benchmark` command - pub async fn execute(self, ctx: CliContext) -> eyre::Result<()> { + pub async fn execute( + self, + ctx: CliContext, + converter: C, + ) -> eyre::Result<()> { // Initialize tracing let _guard = self.init_tracing()?; match self.command { - Subcommands::NewPayloadFcu(command) => command.execute(ctx).await, - Subcommands::NewPayloadOnly(command) => command.execute(ctx).await, - Subcommands::SendPayload(command) => command.execute(ctx).await, + Subcommands::NewPayloadFcu(command) => command.execute(ctx, &converter).await, + Subcommands::NewPayloadOnly(command) => command.execute(ctx, &converter).await, + Subcommands::SendPayload(command) => command.execute(ctx, &converter).await, Subcommands::GenerateBigBlock(command) => command.execute(ctx).await, Subcommands::ReplayPayloads(command) => command.execute(ctx).await, - Subcommands::SendInvalidPayload(command) => (*command).execute(ctx).await, + Subcommands::SendInvalidPayload(command) => (*command).execute(ctx, &converter).await, } } diff --git a/bin/reth-bench/src/bench/new_payload_fcu.rs b/bin/reth-bench/src/bench/new_payload_fcu.rs index d219a128f81..b56a2b81957 100644 --- a/bin/reth-bench/src/bench/new_payload_fcu.rs +++ b/bin/reth-bench/src/bench/new_payload_fcu.rs @@ -10,6 +10,7 @@ use crate::{ write_benchmark_results, CombinedResult, NewPayloadResult, TotalGasOutput, TotalGasRow, }, }, + payload_converter::PayloadConverter, valid_payload::{ block_to_new_payload, call_forkchoice_updated_with_reth, call_new_payload_with_reth, }, @@ -81,7 +82,11 @@ pub struct Command { impl Command { /// Execute `benchmark new-payload-fcu` command - pub async fn execute(self, _ctx: CliContext) -> eyre::Result<()> { + pub async fn execute( + self, + _ctx: CliContext, + converter: &C, + ) -> eyre::Result<()> { // Log mode configuration if let Some(duration) = self.wait_time { info!(target: "reth-bench", "Using wait-time mode with {}ms delay between blocks", duration.as_millis()); @@ -92,7 +97,6 @@ impl Command { block_provider, auth_provider, next_block, - is_optimism, use_reth_namespace, rlp_blocks, wait_for_persistence, @@ -200,8 +204,8 @@ impl Command { }; let (version, params) = block_to_new_payload( + converter, block, - is_optimism, rlp, use_reth_namespace, wait_for_persistence, diff --git a/bin/reth-bench/src/bench/new_payload_only.rs b/bin/reth-bench/src/bench/new_payload_only.rs index 3d55a20bb26..6cca658b4ae 100644 --- a/bin/reth-bench/src/bench/new_payload_only.rs +++ b/bin/reth-bench/src/bench/new_payload_only.rs @@ -9,6 +9,7 @@ use crate::{ NEW_PAYLOAD_OUTPUT_SUFFIX, }, }, + payload_converter::PayloadConverter, valid_payload::{block_to_new_payload, call_new_payload_with_reth}, }; use alloy_provider::{ext::DebugApi, Provider}; @@ -43,13 +44,16 @@ pub struct Command { impl Command { /// Execute `benchmark new-payload-only` command - pub async fn execute(self, _ctx: CliContext) -> eyre::Result<()> { + pub async fn execute( + self, + _ctx: CliContext, + converter: &C, + ) -> eyre::Result<()> { let BenchContext { benchmark_mode, block_provider, auth_provider, mut next_block, - is_optimism, use_reth_namespace, rlp_blocks, wait_for_persistence, @@ -125,8 +129,8 @@ impl Command { debug!(target: "reth-bench", number=?block.header.number, "Sending payload to engine"); let (version, params) = block_to_new_payload( + converter, block, - is_optimism, rlp, use_reth_namespace, wait_for_persistence, diff --git a/bin/reth-bench/src/bench/send_invalid_payload/mod.rs b/bin/reth-bench/src/bench/send_invalid_payload/mod.rs index 0a38c246b23..f0fd09f3fae 100644 --- a/bin/reth-bench/src/bench/send_invalid_payload/mod.rs +++ b/bin/reth-bench/src/bench/send_invalid_payload/mod.rs @@ -4,12 +4,12 @@ mod invalidation; use invalidation::InvalidationConfig; use super::helpers::{load_jwt_secret, read_input}; +use crate::payload_converter::PayloadConverter; use alloy_primitives::{Address, B256}; use alloy_provider::network::AnyRpcBlock; use alloy_rpc_types_engine::ExecutionPayload; use clap::Parser; use eyre::{OptionExt, Result}; -use op_alloy_consensus::OpTxEnvelope; use reth_cli_runner::CliContext; use std::io::Write; @@ -215,26 +215,23 @@ impl Command { } /// Execute the command - pub async fn execute(self, _ctx: CliContext) -> Result<()> { + pub async fn execute(self, _ctx: CliContext, converter: &C) -> Result<()> { let block_json = read_input(self.path.as_deref())?; let jwt_secret = load_jwt_secret(self.jwt_secret.as_deref())?; - let block = serde_json::from_str::(&block_json)? - .into_inner() - .map_header(|header| header.map(|h| h.into_header_with_defaults())) - .try_map_transactions(|tx| tx.try_into_either::())? - .into_consensus(); + let block = serde_json::from_str::(&block_json)?; + + let (mut execution_payload, sidecar) = converter.block_to_payload(block)?; let config = self.build_invalidation_config(); + let cancun = sidecar.cancun(); let parent_beacon_block_root = - self.parent_beacon_block_root.or(block.header.parent_beacon_block_root); - let blob_versioned_hashes = - block.body.blob_versioned_hashes_iter().copied().collect::>(); - let use_v4 = block.header.requests_hash.is_some(); - let requests_hash = self.requests_hash.or(block.header.requests_hash); - - let mut execution_payload = ExecutionPayload::from_block_slow(&block).0; + self.parent_beacon_block_root.or_else(|| cancun.map(|c| c.parent_beacon_block_root)); + let blob_versioned_hashes = cancun.map(|c| c.versioned_hashes.clone()).unwrap_or_default(); + let use_v4 = sidecar.prague().is_some(); + let requests_hash = + self.requests_hash.or_else(|| sidecar.prague().map(|p| p.requests.requests_hash())); let changes = match &mut execution_payload { ExecutionPayload::V1(p) => config.apply_to_payload_v1(p), diff --git a/bin/reth-bench/src/bench/send_payload.rs b/bin/reth-bench/src/bench/send_payload.rs index 67279e54199..1acee9b33b2 100644 --- a/bin/reth-bench/src/bench/send_payload.rs +++ b/bin/reth-bench/src/bench/send_payload.rs @@ -1,9 +1,8 @@ use super::helpers::{load_jwt_secret, read_input}; +use crate::payload_converter::PayloadConverter; use alloy_provider::network::AnyRpcBlock; -use alloy_rpc_types_engine::ExecutionPayload; use clap::Parser; use eyre::{OptionExt, Result}; -use op_alloy_consensus::OpTxEnvelope; use reth_cli_runner::CliContext; use std::io::Write; @@ -53,7 +52,7 @@ enum Mode { impl Command { /// Execute the generate payload command - pub async fn execute(self, _ctx: CliContext) -> Result<()> { + pub async fn execute(self, _ctx: CliContext, converter: &C) -> Result<()> { // Load block let block_json = read_input(self.path.as_deref())?; @@ -61,49 +60,20 @@ impl Command { let jwt_secret = load_jwt_secret(self.jwt_secret.as_deref())?; // Parse the block - let block = serde_json::from_str::(&block_json)? - .into_inner() - .map_header(|header| header.map(|h| h.into_header_with_defaults())) - .try_map_transactions(|tx| { - // try to convert unknowns into op type so that we can also support optimism - tx.try_into_either::() - })? - .into_consensus(); - - // Extract parent beacon block root - let parent_beacon_block_root = block.header.parent_beacon_block_root; - - // Extract blob versioned hashes - let blob_versioned_hashes = - block.body.blob_versioned_hashes_iter().copied().collect::>(); - - // Convert to execution payload - let execution_payload = ExecutionPayload::from_block_slow(&block).0; - - let use_v4 = block.header.requests_hash.is_some(); - - // Create JSON request data - let json_request = if use_v4 { - serde_json::to_string(&( - execution_payload, - blob_versioned_hashes, - parent_beacon_block_root, - block.header.requests_hash.unwrap_or_default(), - ))? - } else { - serde_json::to_string(&( - execution_payload, - blob_versioned_hashes, - parent_beacon_block_root, - ))? - }; + let block = serde_json::from_str::(&block_json)?; + + let (payload, sidecar) = converter.block_to_payload(block)?; + let (version, params, _execution_data) = + converter.payload_to_new_payload(payload, sidecar, None)?; + + let json_request = serde_json::to_string(¶ms)?; + let method = version.method_name(); // Print output or execute command match self.mode { Mode::Execute => { // Create cast command let mut command = std::process::Command::new("cast"); - let method = if use_v4 { "engine_newPayloadV4" } else { "engine_newPayloadV3" }; command.arg("rpc").arg(method).arg("--raw"); if let Some(rpc_url) = self.rpc_url { command.arg("--rpc-url").arg(rpc_url); @@ -126,10 +96,7 @@ impl Command { process.wait()?; } Mode::Cast => { - let mut cmd = format!( - "cast rpc engine_newPayloadV{} --raw '{}'", - self.new_payload_version, json_request - ); + let mut cmd = format!("cast rpc {} --raw '{}'", method, json_request); if let Some(rpc_url) = self.rpc_url { cmd += &format!(" --rpc-url {rpc_url}"); diff --git a/bin/reth-bench/src/main.rs b/bin/reth-bench/src/main.rs index 608007e0867..7f677d44ef8 100644 --- a/bin/reth-bench/src/main.rs +++ b/bin/reth-bench/src/main.rs @@ -20,10 +20,12 @@ use reth_cli_util::allocator::tikv_jemalloc_sys as _; pub mod authenticated_transport; pub mod bench; pub mod bench_mode; +pub mod payload_converter; pub mod valid_payload; use bench::BenchmarkCommand; use clap::Parser; +use payload_converter::EthereumPayloadConverter; use reth_cli_runner::CliRunner; fn main() -> eyre::Result<()> { @@ -38,7 +40,9 @@ fn main() -> eyre::Result<()> { // Run until either exit or sigint or sigterm let runner = CliRunner::try_default_runtime()?; - runner.run_command_until_exit(|ctx| BenchmarkCommand::parse().execute(ctx))?; + runner.run_command_until_exit(|ctx| { + BenchmarkCommand::parse().execute(ctx, EthereumPayloadConverter) + })?; Ok(()) } diff --git a/bin/reth-bench/src/payload_converter.rs b/bin/reth-bench/src/payload_converter.rs new file mode 100644 index 00000000000..5a6d17b88aa --- /dev/null +++ b/bin/reth-bench/src/payload_converter.rs @@ -0,0 +1,106 @@ +//! Trait abstraction for chain-specific payload conversions in benchmarks. + +use alloy_consensus::TxEnvelope; +use alloy_provider::network::AnyRpcBlock; +use alloy_rpc_types_engine::{ + ExecutionData, ExecutionPayload, ExecutionPayloadInputV2, ExecutionPayloadSidecar, +}; +use reth_node_api::EngineApiMessageVersion; + +/// Converts RPC blocks into engine API payloads. +/// +/// Different chains (Ethereum, Optimism, …) need different transaction/payload +/// encoding when talking to `engine_newPayload*`. Implement this trait once per +/// chain and pass it into the benchmark commands. +pub trait PayloadConverter: Send + Sync + 'static { + /// Convert an [`AnyRpcBlock`] into an [`ExecutionPayload`] and its + /// [`ExecutionPayloadSidecar`]. + fn block_to_payload( + &self, + block: AnyRpcBlock, + ) -> eyre::Result<(ExecutionPayload, ExecutionPayloadSidecar)>; + + /// Serialize an [`ExecutionPayload`] + [`ExecutionPayloadSidecar`] into the + /// versioned JSON params expected by the corresponding `engine_newPayload*` + /// method, together with the assembled [`ExecutionData`]. + fn payload_to_new_payload( + &self, + payload: ExecutionPayload, + sidecar: ExecutionPayloadSidecar, + target_version: Option, + ) -> eyre::Result<(EngineApiMessageVersion, serde_json::Value, ExecutionData)>; +} + +/// Ethereum-specific [`PayloadConverter`]. +#[derive(Debug, Default, Clone, Copy)] +pub struct EthereumPayloadConverter; + +impl PayloadConverter for EthereumPayloadConverter { + fn block_to_payload( + &self, + block: AnyRpcBlock, + ) -> eyre::Result<(ExecutionPayload, ExecutionPayloadSidecar)> { + let block = block + .into_inner() + .map_header(|header| header.map(|h| h.into_header_with_defaults())) + .try_map_transactions(|tx| -> eyre::Result { + tx.try_into().map_err(|_| eyre::eyre!("unsupported tx type")) + })? + .into_consensus(); + + Ok(ExecutionPayload::from_block_slow(&block)) + } + + fn payload_to_new_payload( + &self, + payload: ExecutionPayload, + sidecar: ExecutionPayloadSidecar, + target_version: Option, + ) -> eyre::Result<(EngineApiMessageVersion, serde_json::Value, ExecutionData)> { + let execution_data = ExecutionData { payload: payload.clone(), sidecar: sidecar.clone() }; + + let (version, params) = match payload { + ExecutionPayload::V3(payload) => { + let cancun = sidecar + .cancun() + .ok_or_else(|| eyre::eyre!("missing cancun sidecar for V3 payload"))?; + + if let Some(prague) = sidecar.prague() { + let version = target_version.unwrap_or(EngineApiMessageVersion::V4); + let requests = prague.requests.clone(); + ( + version, + serde_json::to_value(( + payload, + cancun.versioned_hashes.clone(), + cancun.parent_beacon_block_root, + requests, + ))?, + ) + } else { + ( + EngineApiMessageVersion::V3, + serde_json::to_value(( + payload, + cancun.versioned_hashes.clone(), + cancun.parent_beacon_block_root, + ))?, + ) + } + } + ExecutionPayload::V2(payload) => { + let input = ExecutionPayloadInputV2 { + execution_payload: payload.payload_inner, + withdrawals: Some(payload.withdrawals), + }; + + (EngineApiMessageVersion::V2, serde_json::to_value((input,))?) + } + ExecutionPayload::V1(payload) => { + (EngineApiMessageVersion::V1, serde_json::to_value((payload,))?) + } + }; + + Ok((version, params, execution_data)) + } +} diff --git a/bin/reth-bench/src/valid_payload.rs b/bin/reth-bench/src/valid_payload.rs index 038c4e25746..7eb64db839c 100644 --- a/bin/reth-bench/src/valid_payload.rs +++ b/bin/reth-bench/src/valid_payload.rs @@ -2,15 +2,13 @@ //! response. This is useful for benchmarking, as it allows us to wait for a payload to be valid //! before sending additional calls. -use alloy_eips::eip7685::Requests; -use alloy_primitives::{Bytes, B256}; +use crate::payload_converter::PayloadConverter; +use alloy_primitives::Bytes; use alloy_provider::{ext::EngineApi, network::AnyRpcBlock, Network, Provider}; use alloy_rpc_types_engine::{ - ExecutionData, ExecutionPayload, ExecutionPayloadInputV2, ExecutionPayloadSidecar, - ForkchoiceState, ForkchoiceUpdated, PayloadAttributes, PayloadStatus, + ExecutionData, ForkchoiceState, ForkchoiceUpdated, PayloadAttributes, PayloadStatus, }; use alloy_transport::TransportResult; -use op_alloy_rpc_types_engine::OpExecutionPayloadV4; use reth_node_api::EngineApiMessageVersion; use reth_node_core::args::WaitForPersistence; use reth_rpc_api::RethNewPayloadInput; @@ -171,9 +169,9 @@ where /// /// `wait_for_persistence` controls how `wait_for_persistence` is passed to /// `reth_newPayload` on a per-block basis. -pub(crate) fn block_to_new_payload( +pub(crate) fn block_to_new_payload( + converter: &C, block: AnyRpcBlock, - is_optimism: bool, rlp: Option, reth_new_payload: bool, wait_for_persistence: WaitForPersistence, @@ -192,19 +190,10 @@ pub(crate) fn block_to_new_payload( ))?, )); } - let block = block - .into_inner() - .map_header(|header| header.map(|h| h.into_header_with_defaults())) - .try_map_transactions(|tx| { - // try to convert unknowns into op type so that we can also support optimism - tx.try_into_either::() - })? - .into_consensus(); - - // Convert to execution payload - let (payload, sidecar) = ExecutionPayload::from_block_slow(&block); + + let (payload, sidecar) = converter.block_to_payload(block)?; let (version, params, execution_data) = - payload_to_new_payload(payload, sidecar, is_optimism, block.withdrawals_root, None)?; + converter.payload_to_new_payload(payload, sidecar, None)?; if reth_new_payload { Ok(( @@ -220,80 +209,6 @@ pub(crate) fn block_to_new_payload( } } -/// Converts an execution payload and sidecar into versioned engine API params and an -/// [`ExecutionData`]. -/// -/// Returns `(version, versioned_params, execution_data)`. -pub(crate) fn payload_to_new_payload( - payload: ExecutionPayload, - sidecar: ExecutionPayloadSidecar, - is_optimism: bool, - withdrawals_root: Option, - target_version: Option, -) -> eyre::Result<(EngineApiMessageVersion, serde_json::Value, ExecutionData)> { - let execution_data = ExecutionData { payload: payload.clone(), sidecar: sidecar.clone() }; - - let (version, params) = match payload { - ExecutionPayload::V3(payload) => { - let cancun = sidecar.cancun().unwrap(); - - if let Some(prague) = sidecar.prague() { - // Use target version if provided (for Osaka), otherwise default to V4 - let version = target_version.unwrap_or(EngineApiMessageVersion::V4); - - if is_optimism { - let withdrawals_root = withdrawals_root.ok_or_else(|| { - eyre::eyre!("Missing withdrawals root for Optimism payload") - })?; - ( - version, - serde_json::to_value(( - OpExecutionPayloadV4 { payload_inner: payload, withdrawals_root }, - cancun.versioned_hashes.clone(), - cancun.parent_beacon_block_root, - Requests::default(), - ))?, - ) - } else { - // Preserve the original RequestsOrHash payload for engine_newPayloadV4. - let requests = prague.requests.clone(); - ( - version, - serde_json::to_value(( - payload, - cancun.versioned_hashes.clone(), - cancun.parent_beacon_block_root, - requests, - ))?, - ) - } - } else { - ( - EngineApiMessageVersion::V3, - serde_json::to_value(( - payload, - cancun.versioned_hashes.clone(), - cancun.parent_beacon_block_root, - ))?, - ) - } - } - ExecutionPayload::V2(payload) => { - let input = ExecutionPayloadInputV2 { - execution_payload: payload.payload_inner, - withdrawals: Some(payload.withdrawals), - }; - - (EngineApiMessageVersion::V2, serde_json::to_value((input,))?) - } - ExecutionPayload::V1(payload) => { - (EngineApiMessageVersion::V1, serde_json::to_value((payload,))?) - } - }; - - Ok((version, params, execution_data)) -} - /// Calls the correct `engine_newPayload` method depending on the given [`ExecutionPayload`] and its /// versioned variant. Returns the [`EngineApiMessageVersion`] depending on the payload's version. /// From ea07fe504d10df6759e9f706f87cd3cf7b939724 Mon Sep 17 00:00:00 2001 From: Derek Cofausper <256792747+decofe@users.noreply.github.com> Date: Mon, 30 Mar 2026 11:00:18 +0000 Subject: [PATCH 2/8] docs: fix broken ExecutionPayload doc link in reth-bench Co-Authored-By: Matthias Seitz <19890894+mattsse@users.noreply.github.com> --- bin/reth-bench/src/valid_payload.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/reth-bench/src/valid_payload.rs b/bin/reth-bench/src/valid_payload.rs index 7eb64db839c..7a75b30a896 100644 --- a/bin/reth-bench/src/valid_payload.rs +++ b/bin/reth-bench/src/valid_payload.rs @@ -209,7 +209,7 @@ pub(crate) fn block_to_new_payload( } } -/// Calls the correct `engine_newPayload` method depending on the given [`ExecutionPayload`] and its +/// Calls the correct `engine_newPayload` method depending on the given execution payload and its /// versioned variant. Returns the [`EngineApiMessageVersion`] depending on the payload's version. /// /// # Panics From 3e02a13776b2aa4d692eb6c1d57da7179e4858ea Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 1 Apr 2026 12:57:57 +0200 Subject: [PATCH 3/8] refactor(reth-bench): remove temporary opstack support --- .changelog/zesty-hens-wave.md | 5 + Cargo.lock | 2 + bin/reth-bench/Cargo.toml | 2 + bin/reth-bench/src/bench/mod.rs | 15 +- bin/reth-bench/src/bench/new_payload_fcu.rs | 8 +- bin/reth-bench/src/bench/new_payload_only.rs | 8 +- .../src/bench/send_invalid_payload/mod.rs | 27 ++- bin/reth-bench/src/bench/send_payload.rs | 54 ++++- bin/reth-bench/src/main.rs | 6 +- bin/reth-bench/src/payload_converter.rs | 106 --------- bin/reth-bench/src/valid_payload.rs | 215 +++++++++++++++++- 11 files changed, 284 insertions(+), 164 deletions(-) create mode 100644 .changelog/zesty-hens-wave.md delete mode 100644 bin/reth-bench/src/payload_converter.rs diff --git a/.changelog/zesty-hens-wave.md b/.changelog/zesty-hens-wave.md new file mode 100644 index 00000000000..a432ee1e3f9 --- /dev/null +++ b/.changelog/zesty-hens-wave.md @@ -0,0 +1,5 @@ +--- +reth-bench: minor +--- + +Removed temporary OP-stack transaction and payload handling from `reth-bench`, making the replay and standalone payload tooling Ethereum-only again. This drops the new abstraction from PR #23262 and keeps the existing CLI behavior while unsupported OP-style blocks now fail during conversion. diff --git a/Cargo.lock b/Cargo.lock index dfa7294fb1a..a0c48439ed4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7641,11 +7641,13 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-json-rpc", + "alloy-network", "alloy-primitives", "alloy-provider", "alloy-pubsub", "alloy-rpc-client", "alloy-rpc-types-engine", + "alloy-rpc-types-eth", "alloy-transport", "alloy-transport-http", "alloy-transport-ipc", diff --git a/bin/reth-bench/Cargo.toml b/bin/reth-bench/Cargo.toml index 1d5e2c4dee6..ba1593e1067 100644 --- a/bin/reth-bench/Cargo.toml +++ b/bin/reth-bench/Cargo.toml @@ -72,6 +72,8 @@ humantime.workspace = true csv.workspace = true [dev-dependencies] +alloy-network.workspace = true +alloy-rpc-types-eth.workspace = true [features] default = ["jemalloc"] diff --git a/bin/reth-bench/src/bench/mod.rs b/bin/reth-bench/src/bench/mod.rs index 0b3bf1d066b..1f171d85a68 100644 --- a/bin/reth-bench/src/bench/mod.rs +++ b/bin/reth-bench/src/bench/mod.rs @@ -1,6 +1,5 @@ //! `reth benchmark` command. Collection of various benchmarking routines. -use crate::payload_converter::PayloadConverter; use clap::{Parser, Subcommand}; use reth_cli_runner::CliContext; use reth_node_core::args::LogArgs; @@ -89,21 +88,17 @@ pub enum Subcommands { impl BenchmarkCommand { /// Execute `benchmark` command - pub async fn execute( - self, - ctx: CliContext, - converter: C, - ) -> eyre::Result<()> { + pub async fn execute(self, ctx: CliContext) -> eyre::Result<()> { // Initialize tracing let _guard = self.init_tracing()?; match self.command { - Subcommands::NewPayloadFcu(command) => command.execute(ctx, &converter).await, - Subcommands::NewPayloadOnly(command) => command.execute(ctx, &converter).await, - Subcommands::SendPayload(command) => command.execute(ctx, &converter).await, + Subcommands::NewPayloadFcu(command) => command.execute(ctx).await, + Subcommands::NewPayloadOnly(command) => command.execute(ctx).await, + Subcommands::SendPayload(command) => command.execute(ctx).await, Subcommands::GenerateBigBlock(command) => command.execute(ctx).await, Subcommands::ReplayPayloads(command) => command.execute(ctx).await, - Subcommands::SendInvalidPayload(command) => (*command).execute(ctx, &converter).await, + Subcommands::SendInvalidPayload(command) => (*command).execute(ctx).await, } } diff --git a/bin/reth-bench/src/bench/new_payload_fcu.rs b/bin/reth-bench/src/bench/new_payload_fcu.rs index b56a2b81957..ddabaab293e 100644 --- a/bin/reth-bench/src/bench/new_payload_fcu.rs +++ b/bin/reth-bench/src/bench/new_payload_fcu.rs @@ -10,7 +10,6 @@ use crate::{ write_benchmark_results, CombinedResult, NewPayloadResult, TotalGasOutput, TotalGasRow, }, }, - payload_converter::PayloadConverter, valid_payload::{ block_to_new_payload, call_forkchoice_updated_with_reth, call_new_payload_with_reth, }, @@ -82,11 +81,7 @@ pub struct Command { impl Command { /// Execute `benchmark new-payload-fcu` command - pub async fn execute( - self, - _ctx: CliContext, - converter: &C, - ) -> eyre::Result<()> { + pub async fn execute(self, _ctx: CliContext) -> eyre::Result<()> { // Log mode configuration if let Some(duration) = self.wait_time { info!(target: "reth-bench", "Using wait-time mode with {}ms delay between blocks", duration.as_millis()); @@ -204,7 +199,6 @@ impl Command { }; let (version, params) = block_to_new_payload( - converter, block, rlp, use_reth_namespace, diff --git a/bin/reth-bench/src/bench/new_payload_only.rs b/bin/reth-bench/src/bench/new_payload_only.rs index 6cca658b4ae..b024b9e7185 100644 --- a/bin/reth-bench/src/bench/new_payload_only.rs +++ b/bin/reth-bench/src/bench/new_payload_only.rs @@ -9,7 +9,6 @@ use crate::{ NEW_PAYLOAD_OUTPUT_SUFFIX, }, }, - payload_converter::PayloadConverter, valid_payload::{block_to_new_payload, call_new_payload_with_reth}, }; use alloy_provider::{ext::DebugApi, Provider}; @@ -44,11 +43,7 @@ pub struct Command { impl Command { /// Execute `benchmark new-payload-only` command - pub async fn execute( - self, - _ctx: CliContext, - converter: &C, - ) -> eyre::Result<()> { + pub async fn execute(self, _ctx: CliContext) -> eyre::Result<()> { let BenchContext { benchmark_mode, block_provider, @@ -129,7 +124,6 @@ impl Command { debug!(target: "reth-bench", number=?block.header.number, "Sending payload to engine"); let (version, params) = block_to_new_payload( - converter, block, rlp, use_reth_namespace, diff --git a/bin/reth-bench/src/bench/send_invalid_payload/mod.rs b/bin/reth-bench/src/bench/send_invalid_payload/mod.rs index f0fd09f3fae..40c02b92a83 100644 --- a/bin/reth-bench/src/bench/send_invalid_payload/mod.rs +++ b/bin/reth-bench/src/bench/send_invalid_payload/mod.rs @@ -4,7 +4,7 @@ mod invalidation; use invalidation::InvalidationConfig; use super::helpers::{load_jwt_secret, read_input}; -use crate::payload_converter::PayloadConverter; +use alloy_consensus::TxEnvelope; use alloy_primitives::{Address, B256}; use alloy_provider::network::AnyRpcBlock; use alloy_rpc_types_engine::ExecutionPayload; @@ -215,23 +215,28 @@ impl Command { } /// Execute the command - pub async fn execute(self, _ctx: CliContext, converter: &C) -> Result<()> { + pub async fn execute(self, _ctx: CliContext) -> Result<()> { let block_json = read_input(self.path.as_deref())?; let jwt_secret = load_jwt_secret(self.jwt_secret.as_deref())?; - let block = serde_json::from_str::(&block_json)?; - - let (mut execution_payload, sidecar) = converter.block_to_payload(block)?; + let block = serde_json::from_str::(&block_json)? + .into_inner() + .map_header(|header| header.map(|h| h.into_header_with_defaults())) + .try_map_transactions(|tx| -> eyre::Result { + tx.try_into().map_err(|_| eyre::eyre!("unsupported tx type")) + })? + .into_consensus(); let config = self.build_invalidation_config(); - let cancun = sidecar.cancun(); let parent_beacon_block_root = - self.parent_beacon_block_root.or_else(|| cancun.map(|c| c.parent_beacon_block_root)); - let blob_versioned_hashes = cancun.map(|c| c.versioned_hashes.clone()).unwrap_or_default(); - let use_v4 = sidecar.prague().is_some(); - let requests_hash = - self.requests_hash.or_else(|| sidecar.prague().map(|p| p.requests.requests_hash())); + self.parent_beacon_block_root.or(block.header.parent_beacon_block_root); + let blob_versioned_hashes = + block.body.blob_versioned_hashes_iter().copied().collect::>(); + let use_v4 = block.header.requests_hash.is_some(); + let requests_hash = self.requests_hash.or(block.header.requests_hash); + + let mut execution_payload = ExecutionPayload::from_block_slow(&block).0; let changes = match &mut execution_payload { ExecutionPayload::V1(p) => config.apply_to_payload_v1(p), diff --git a/bin/reth-bench/src/bench/send_payload.rs b/bin/reth-bench/src/bench/send_payload.rs index 1acee9b33b2..0b9269278dc 100644 --- a/bin/reth-bench/src/bench/send_payload.rs +++ b/bin/reth-bench/src/bench/send_payload.rs @@ -1,6 +1,7 @@ use super::helpers::{load_jwt_secret, read_input}; -use crate::payload_converter::PayloadConverter; +use alloy_consensus::TxEnvelope; use alloy_provider::network::AnyRpcBlock; +use alloy_rpc_types_engine::ExecutionPayload; use clap::Parser; use eyre::{OptionExt, Result}; use reth_cli_runner::CliContext; @@ -52,7 +53,7 @@ enum Mode { impl Command { /// Execute the generate payload command - pub async fn execute(self, _ctx: CliContext, converter: &C) -> Result<()> { + pub async fn execute(self, _ctx: CliContext) -> Result<()> { // Load block let block_json = read_input(self.path.as_deref())?; @@ -60,20 +61,48 @@ impl Command { let jwt_secret = load_jwt_secret(self.jwt_secret.as_deref())?; // Parse the block - let block = serde_json::from_str::(&block_json)?; - - let (payload, sidecar) = converter.block_to_payload(block)?; - let (version, params, _execution_data) = - converter.payload_to_new_payload(payload, sidecar, None)?; - - let json_request = serde_json::to_string(¶ms)?; - let method = version.method_name(); + let block = serde_json::from_str::(&block_json)? + .into_inner() + .map_header(|header| header.map(|h| h.into_header_with_defaults())) + .try_map_transactions(|tx| -> eyre::Result { + tx.try_into().map_err(|_| eyre::eyre!("unsupported tx type")) + })? + .into_consensus(); + + // Extract parent beacon block root + let parent_beacon_block_root = block.header.parent_beacon_block_root; + + // Extract blob versioned hashes + let blob_versioned_hashes = + block.body.blob_versioned_hashes_iter().copied().collect::>(); + + // Convert to execution payload + let execution_payload = ExecutionPayload::from_block_slow(&block).0; + + let use_v4 = block.header.requests_hash.is_some(); + + // Create JSON request data + let json_request = if use_v4 { + serde_json::to_string(&( + execution_payload, + blob_versioned_hashes, + parent_beacon_block_root, + block.header.requests_hash.unwrap_or_default(), + ))? + } else { + serde_json::to_string(&( + execution_payload, + blob_versioned_hashes, + parent_beacon_block_root, + ))? + }; // Print output or execute command match self.mode { Mode::Execute => { // Create cast command let mut command = std::process::Command::new("cast"); + let method = if use_v4 { "engine_newPayloadV4" } else { "engine_newPayloadV3" }; command.arg("rpc").arg(method).arg("--raw"); if let Some(rpc_url) = self.rpc_url { command.arg("--rpc-url").arg(rpc_url); @@ -96,7 +125,10 @@ impl Command { process.wait()?; } Mode::Cast => { - let mut cmd = format!("cast rpc {} --raw '{}'", method, json_request); + let mut cmd = format!( + "cast rpc engine_newPayloadV{} --raw '{}'", + self.new_payload_version, json_request + ); if let Some(rpc_url) = self.rpc_url { cmd += &format!(" --rpc-url {rpc_url}"); diff --git a/bin/reth-bench/src/main.rs b/bin/reth-bench/src/main.rs index 7f677d44ef8..608007e0867 100644 --- a/bin/reth-bench/src/main.rs +++ b/bin/reth-bench/src/main.rs @@ -20,12 +20,10 @@ use reth_cli_util::allocator::tikv_jemalloc_sys as _; pub mod authenticated_transport; pub mod bench; pub mod bench_mode; -pub mod payload_converter; pub mod valid_payload; use bench::BenchmarkCommand; use clap::Parser; -use payload_converter::EthereumPayloadConverter; use reth_cli_runner::CliRunner; fn main() -> eyre::Result<()> { @@ -40,9 +38,7 @@ fn main() -> eyre::Result<()> { // Run until either exit or sigint or sigterm let runner = CliRunner::try_default_runtime()?; - runner.run_command_until_exit(|ctx| { - BenchmarkCommand::parse().execute(ctx, EthereumPayloadConverter) - })?; + runner.run_command_until_exit(|ctx| BenchmarkCommand::parse().execute(ctx))?; Ok(()) } diff --git a/bin/reth-bench/src/payload_converter.rs b/bin/reth-bench/src/payload_converter.rs deleted file mode 100644 index 5a6d17b88aa..00000000000 --- a/bin/reth-bench/src/payload_converter.rs +++ /dev/null @@ -1,106 +0,0 @@ -//! Trait abstraction for chain-specific payload conversions in benchmarks. - -use alloy_consensus::TxEnvelope; -use alloy_provider::network::AnyRpcBlock; -use alloy_rpc_types_engine::{ - ExecutionData, ExecutionPayload, ExecutionPayloadInputV2, ExecutionPayloadSidecar, -}; -use reth_node_api::EngineApiMessageVersion; - -/// Converts RPC blocks into engine API payloads. -/// -/// Different chains (Ethereum, Optimism, …) need different transaction/payload -/// encoding when talking to `engine_newPayload*`. Implement this trait once per -/// chain and pass it into the benchmark commands. -pub trait PayloadConverter: Send + Sync + 'static { - /// Convert an [`AnyRpcBlock`] into an [`ExecutionPayload`] and its - /// [`ExecutionPayloadSidecar`]. - fn block_to_payload( - &self, - block: AnyRpcBlock, - ) -> eyre::Result<(ExecutionPayload, ExecutionPayloadSidecar)>; - - /// Serialize an [`ExecutionPayload`] + [`ExecutionPayloadSidecar`] into the - /// versioned JSON params expected by the corresponding `engine_newPayload*` - /// method, together with the assembled [`ExecutionData`]. - fn payload_to_new_payload( - &self, - payload: ExecutionPayload, - sidecar: ExecutionPayloadSidecar, - target_version: Option, - ) -> eyre::Result<(EngineApiMessageVersion, serde_json::Value, ExecutionData)>; -} - -/// Ethereum-specific [`PayloadConverter`]. -#[derive(Debug, Default, Clone, Copy)] -pub struct EthereumPayloadConverter; - -impl PayloadConverter for EthereumPayloadConverter { - fn block_to_payload( - &self, - block: AnyRpcBlock, - ) -> eyre::Result<(ExecutionPayload, ExecutionPayloadSidecar)> { - let block = block - .into_inner() - .map_header(|header| header.map(|h| h.into_header_with_defaults())) - .try_map_transactions(|tx| -> eyre::Result { - tx.try_into().map_err(|_| eyre::eyre!("unsupported tx type")) - })? - .into_consensus(); - - Ok(ExecutionPayload::from_block_slow(&block)) - } - - fn payload_to_new_payload( - &self, - payload: ExecutionPayload, - sidecar: ExecutionPayloadSidecar, - target_version: Option, - ) -> eyre::Result<(EngineApiMessageVersion, serde_json::Value, ExecutionData)> { - let execution_data = ExecutionData { payload: payload.clone(), sidecar: sidecar.clone() }; - - let (version, params) = match payload { - ExecutionPayload::V3(payload) => { - let cancun = sidecar - .cancun() - .ok_or_else(|| eyre::eyre!("missing cancun sidecar for V3 payload"))?; - - if let Some(prague) = sidecar.prague() { - let version = target_version.unwrap_or(EngineApiMessageVersion::V4); - let requests = prague.requests.clone(); - ( - version, - serde_json::to_value(( - payload, - cancun.versioned_hashes.clone(), - cancun.parent_beacon_block_root, - requests, - ))?, - ) - } else { - ( - EngineApiMessageVersion::V3, - serde_json::to_value(( - payload, - cancun.versioned_hashes.clone(), - cancun.parent_beacon_block_root, - ))?, - ) - } - } - ExecutionPayload::V2(payload) => { - let input = ExecutionPayloadInputV2 { - execution_payload: payload.payload_inner, - withdrawals: Some(payload.withdrawals), - }; - - (EngineApiMessageVersion::V2, serde_json::to_value((input,))?) - } - ExecutionPayload::V1(payload) => { - (EngineApiMessageVersion::V1, serde_json::to_value((payload,))?) - } - }; - - Ok((version, params, execution_data)) - } -} diff --git a/bin/reth-bench/src/valid_payload.rs b/bin/reth-bench/src/valid_payload.rs index 7a75b30a896..d24e2fcf2e0 100644 --- a/bin/reth-bench/src/valid_payload.rs +++ b/bin/reth-bench/src/valid_payload.rs @@ -2,11 +2,12 @@ //! response. This is useful for benchmarking, as it allows us to wait for a payload to be valid //! before sending additional calls. -use crate::payload_converter::PayloadConverter; +use alloy_consensus::TxEnvelope; use alloy_primitives::Bytes; use alloy_provider::{ext::EngineApi, network::AnyRpcBlock, Network, Provider}; use alloy_rpc_types_engine::{ - ExecutionData, ForkchoiceState, ForkchoiceUpdated, PayloadAttributes, PayloadStatus, + ExecutionData, ExecutionPayload, ExecutionPayloadInputV2, ExecutionPayloadSidecar, + ForkchoiceState, ForkchoiceUpdated, PayloadAttributes, PayloadStatus, }; use alloy_transport::TransportResult; use reth_node_api::EngineApiMessageVersion; @@ -169,8 +170,7 @@ where /// /// `wait_for_persistence` controls how `wait_for_persistence` is passed to /// `reth_newPayload` on a per-block basis. -pub(crate) fn block_to_new_payload( - converter: &C, +pub(crate) fn block_to_new_payload( block: AnyRpcBlock, rlp: Option, reth_new_payload: bool, @@ -191,9 +191,8 @@ pub(crate) fn block_to_new_payload( )); } - let (payload, sidecar) = converter.block_to_payload(block)?; - let (version, params, execution_data) = - converter.payload_to_new_payload(payload, sidecar, None)?; + let (payload, sidecar) = ethereum_block_to_payload(block)?; + let (version, params, execution_data) = payload_to_new_payload(payload, sidecar, None)?; if reth_new_payload { Ok(( @@ -209,6 +208,76 @@ pub(crate) fn block_to_new_payload( } } +fn ethereum_block_to_payload( + block: AnyRpcBlock, +) -> eyre::Result<(ExecutionPayload, ExecutionPayloadSidecar)> { + let block = block + .into_inner() + .map_header(|header| header.map(|h| h.into_header_with_defaults())) + .try_map_transactions(|tx| -> eyre::Result { + tx.try_into().map_err(|_| eyre::eyre!("unsupported tx type")) + })? + .into_consensus(); + + Ok(ExecutionPayload::from_block_slow(&block)) +} + +/// Converts an execution payload and sidecar into versioned engine API params and an +/// [`ExecutionData`]. +/// +/// Returns `(version, versioned_params, execution_data)`. +pub(crate) fn payload_to_new_payload( + payload: ExecutionPayload, + sidecar: ExecutionPayloadSidecar, + target_version: Option, +) -> eyre::Result<(EngineApiMessageVersion, serde_json::Value, ExecutionData)> { + let execution_data = ExecutionData { payload: payload.clone(), sidecar: sidecar.clone() }; + + let (version, params) = match payload { + ExecutionPayload::V3(payload) => { + let cancun = sidecar + .cancun() + .ok_or_else(|| eyre::eyre!("missing cancun sidecar for V3 payload"))?; + + if let Some(prague) = sidecar.prague() { + let version = target_version.unwrap_or(EngineApiMessageVersion::V4); + let requests = prague.requests.clone(); + ( + version, + serde_json::to_value(( + payload, + cancun.versioned_hashes.clone(), + cancun.parent_beacon_block_root, + requests, + ))?, + ) + } else { + ( + EngineApiMessageVersion::V3, + serde_json::to_value(( + payload, + cancun.versioned_hashes.clone(), + cancun.parent_beacon_block_root, + ))?, + ) + } + } + ExecutionPayload::V2(payload) => { + let input = ExecutionPayloadInputV2 { + execution_payload: payload.payload_inner, + withdrawals: Some(payload.withdrawals), + }; + + (EngineApiMessageVersion::V2, serde_json::to_value((input,))?) + } + ExecutionPayload::V1(payload) => { + (EngineApiMessageVersion::V1, serde_json::to_value((payload,))?) + } + }; + + Ok((version, params, execution_data)) +} + /// Calls the correct `engine_newPayload` method depending on the given execution payload and its /// versioned variant. Returns the [`EngineApiMessageVersion`] depending on the payload's version. /// @@ -363,3 +432,135 @@ pub(crate) async fn call_forkchoice_updated_with_reth< } } } + +#[cfg(test)] +mod tests { + use super::*; + use alloy_eips::eip7685::RequestsOrHash; + use alloy_network::{AnyHeader, AnyRpcBlock, AnyRpcHeader, AnyRpcTransaction}; + use alloy_primitives::{Address, Bloom, B256, B64, U256}; + use alloy_rpc_types_engine::{ + CancunPayloadFields, ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3, + PraguePayloadFields, + }; + use alloy_rpc_types_eth::{Block, BlockTransactions}; + + #[test] + fn payload_to_new_payload_v3_uses_standard_ethereum_params() { + let payload = sample_execution_payload_v3(); + let execution_payload = ExecutionPayload::V3(payload.clone()); + let parent_beacon_block_root = B256::from([0x11; 32]); + let versioned_hash = B256::from([0x22; 32]); + let sidecar = ExecutionPayloadSidecar::v3(CancunPayloadFields::new( + parent_beacon_block_root, + vec![versioned_hash], + )); + + let (version, params, _) = + payload_to_new_payload(execution_payload, sidecar, None).expect("payload encodes"); + + assert_eq!(version, EngineApiMessageVersion::V3); + assert_eq!( + params, + serde_json::to_value((payload, vec![versioned_hash], parent_beacon_block_root)) + .expect("params serialize"), + ); + } + + #[test] + fn payload_to_new_payload_v4_preserves_requests_hash() { + let payload = sample_execution_payload_v3(); + let execution_payload = ExecutionPayload::V3(payload.clone()); + let parent_beacon_block_root = B256::from([0x33; 32]); + let versioned_hash = B256::from([0x44; 32]); + let requests_hash = B256::from([0x55; 32]); + let requests = RequestsOrHash::Hash(requests_hash); + let sidecar = ExecutionPayloadSidecar::v4( + CancunPayloadFields::new(parent_beacon_block_root, vec![versioned_hash]), + PraguePayloadFields::new(requests.clone()), + ); + + let (version, params, _) = + payload_to_new_payload(execution_payload, sidecar, None).expect("payload encodes"); + + assert_eq!(version, EngineApiMessageVersion::V4); + assert_eq!( + params, + serde_json::to_value(( + payload, + vec![versioned_hash], + parent_beacon_block_root, + requests, + )) + .expect("params serialize"), + ); + } + + #[test] + fn ethereum_block_to_payload_rejects_unsupported_transaction_types() { + let tx: AnyRpcTransaction = serde_json::from_value(serde_json::json!({ + "blockHash": "0xef664d656f841b5ad6a2b527b963f1eb48b97d7889d742f6cbff6950388e24cd", + "blockNumber": "0x1", + "depositReceiptVersion": "0x1", + "from": "0x36bde71c97b33cc4729cf772ae268934f7ab70b2", + "gas": "0x5208", + "gasPrice": "0x1", + "hash": "0x0bf1845c5d7a82ec92365d5027f7310793d53004f3c86aa80965c67bf7e7dc80", + "input": "0x", + "mint": "0x0", + "nonce": "0x0", + "r": "0x0", + "s": "0x0", + "sourceHash": "0x074adb22f2e6ed9bdd31c52eefc1f050e5db56eb85056450bccd79a6649520b3", + "to": "0x4200000000000000000000000000000000000007", + "transactionIndex": "0x0", + "type": "0x7e", + "v": "0x0", + "value": "0x0" + })) + .expect("transaction deserializes"); + let block = AnyRpcBlock::new( + Block::new( + AnyRpcHeader::from_sealed( + AnyHeader { + nonce: Some(B64::ZERO), + mix_hash: Some(B256::ZERO), + ..Default::default() + } + .seal(B256::ZERO), + ), + BlockTransactions::Full(vec![tx]), + ) + .into(), + ); + + let err = ethereum_block_to_payload(block).expect_err("unsupported tx fails"); + assert!(err.to_string().contains("unsupported tx type")); + } + + fn sample_execution_payload_v3() -> ExecutionPayloadV3 { + ExecutionPayloadV3 { + payload_inner: ExecutionPayloadV2 { + payload_inner: ExecutionPayloadV1 { + parent_hash: B256::from([0x01; 32]), + fee_recipient: Address::from([0x02; 20]), + state_root: B256::from([0x03; 32]), + receipts_root: B256::from([0x04; 32]), + logs_bloom: Bloom::default(), + prev_randao: B256::from([0x05; 32]), + block_number: 42, + gas_limit: 30_000_000, + gas_used: 21_000, + timestamp: 1_715_555_555, + extra_data: Bytes::default(), + base_fee_per_gas: U256::from(7), + block_hash: B256::from([0x06; 32]), + transactions: vec![], + }, + withdrawals: vec![], + }, + blob_gas_used: 10, + excess_blob_gas: 20, + } + } +} From cd7d4c27efbd9b69b7876d6c673ad0d5990096b8 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 1 Apr 2026 13:03:22 +0200 Subject: [PATCH 4/8] chore(reth-bench): update lockfile --- Cargo.lock | 2 - bin/reth-bench/Cargo.toml | 2 - bin/reth-bench/src/valid_payload.rs | 78 +++++++++++++++-------------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a0c48439ed4..dfa7294fb1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7641,13 +7641,11 @@ dependencies = [ "alloy-consensus", "alloy-eips", "alloy-json-rpc", - "alloy-network", "alloy-primitives", "alloy-provider", "alloy-pubsub", "alloy-rpc-client", "alloy-rpc-types-engine", - "alloy-rpc-types-eth", "alloy-transport", "alloy-transport-http", "alloy-transport-ipc", diff --git a/bin/reth-bench/Cargo.toml b/bin/reth-bench/Cargo.toml index ba1593e1067..1d5e2c4dee6 100644 --- a/bin/reth-bench/Cargo.toml +++ b/bin/reth-bench/Cargo.toml @@ -72,8 +72,6 @@ humantime.workspace = true csv.workspace = true [dev-dependencies] -alloy-network.workspace = true -alloy-rpc-types-eth.workspace = true [features] default = ["jemalloc"] diff --git a/bin/reth-bench/src/valid_payload.rs b/bin/reth-bench/src/valid_payload.rs index d24e2fcf2e0..f7a58b976b8 100644 --- a/bin/reth-bench/src/valid_payload.rs +++ b/bin/reth-bench/src/valid_payload.rs @@ -437,13 +437,11 @@ pub(crate) async fn call_forkchoice_updated_with_reth< mod tests { use super::*; use alloy_eips::eip7685::RequestsOrHash; - use alloy_network::{AnyHeader, AnyRpcBlock, AnyRpcHeader, AnyRpcTransaction}; - use alloy_primitives::{Address, Bloom, B256, B64, U256}; + use alloy_primitives::{Address, Bloom, B256, U256}; use alloy_rpc_types_engine::{ CancunPayloadFields, ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3, PraguePayloadFields, }; - use alloy_rpc_types_eth::{Block, BlockTransactions}; #[test] fn payload_to_new_payload_v3_uses_standard_ethereum_params() { @@ -498,41 +496,47 @@ mod tests { #[test] fn ethereum_block_to_payload_rejects_unsupported_transaction_types() { - let tx: AnyRpcTransaction = serde_json::from_value(serde_json::json!({ - "blockHash": "0xef664d656f841b5ad6a2b527b963f1eb48b97d7889d742f6cbff6950388e24cd", - "blockNumber": "0x1", - "depositReceiptVersion": "0x1", - "from": "0x36bde71c97b33cc4729cf772ae268934f7ab70b2", - "gas": "0x5208", - "gasPrice": "0x1", - "hash": "0x0bf1845c5d7a82ec92365d5027f7310793d53004f3c86aa80965c67bf7e7dc80", - "input": "0x", - "mint": "0x0", - "nonce": "0x0", - "r": "0x0", - "s": "0x0", - "sourceHash": "0x074adb22f2e6ed9bdd31c52eefc1f050e5db56eb85056450bccd79a6649520b3", - "to": "0x4200000000000000000000000000000000000007", - "transactionIndex": "0x0", - "type": "0x7e", - "v": "0x0", - "value": "0x0" + let block = serde_json::from_value::(serde_json::json!({ + "hash": "0xef664d656f841b5ad6a2b527b963f1eb48b97d7889d742f6cbff6950388e24cd", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "miner": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494", + "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": format!("0x{}", "00".repeat(256)), + "difficulty": "0x0", + "number": "0x1", + "gasLimit": "0x1c9c380", + "gasUsed": "0x0", + "timestamp": "0x1", + "extraData": "0x", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "baseFeePerGas": "0x1", + "transactions": [{ + "blockHash": "0xef664d656f841b5ad6a2b527b963f1eb48b97d7889d742f6cbff6950388e24cd", + "blockNumber": "0x1", + "depositReceiptVersion": "0x1", + "from": "0x36bde71c97b33cc4729cf772ae268934f7ab70b2", + "gas": "0x5208", + "gasPrice": "0x1", + "hash": "0x0bf1845c5d7a82ec92365d5027f7310793d53004f3c86aa80965c67bf7e7dc80", + "input": "0x", + "mint": "0x0", + "nonce": "0x0", + "r": "0x0", + "s": "0x0", + "sourceHash": "0x074adb22f2e6ed9bdd31c52eefc1f050e5db56eb85056450bccd79a6649520b3", + "to": "0x4200000000000000000000000000000000000007", + "transactionIndex": "0x0", + "type": "0x7e", + "v": "0x0", + "value": "0x0" + }], + "uncles": [] })) - .expect("transaction deserializes"); - let block = AnyRpcBlock::new( - Block::new( - AnyRpcHeader::from_sealed( - AnyHeader { - nonce: Some(B64::ZERO), - mix_hash: Some(B256::ZERO), - ..Default::default() - } - .seal(B256::ZERO), - ), - BlockTransactions::Full(vec![tx]), - ) - .into(), - ); + .expect("block deserializes"); let err = ethereum_block_to_payload(block).expect_err("unsupported tx fails"); assert!(err.to_string().contains("unsupported tx type")); From d3103dae788efab071b885bc18b29e365a48e357 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 1 Apr 2026 13:05:02 +0200 Subject: [PATCH 5/8] refactor(reth-bench): remove payload serializer tests --- bin/reth-bench/src/valid_payload.rs | 136 ---------------------------- 1 file changed, 136 deletions(-) diff --git a/bin/reth-bench/src/valid_payload.rs b/bin/reth-bench/src/valid_payload.rs index f7a58b976b8..b438ff85c87 100644 --- a/bin/reth-bench/src/valid_payload.rs +++ b/bin/reth-bench/src/valid_payload.rs @@ -432,139 +432,3 @@ pub(crate) async fn call_forkchoice_updated_with_reth< } } } - -#[cfg(test)] -mod tests { - use super::*; - use alloy_eips::eip7685::RequestsOrHash; - use alloy_primitives::{Address, Bloom, B256, U256}; - use alloy_rpc_types_engine::{ - CancunPayloadFields, ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3, - PraguePayloadFields, - }; - - #[test] - fn payload_to_new_payload_v3_uses_standard_ethereum_params() { - let payload = sample_execution_payload_v3(); - let execution_payload = ExecutionPayload::V3(payload.clone()); - let parent_beacon_block_root = B256::from([0x11; 32]); - let versioned_hash = B256::from([0x22; 32]); - let sidecar = ExecutionPayloadSidecar::v3(CancunPayloadFields::new( - parent_beacon_block_root, - vec![versioned_hash], - )); - - let (version, params, _) = - payload_to_new_payload(execution_payload, sidecar, None).expect("payload encodes"); - - assert_eq!(version, EngineApiMessageVersion::V3); - assert_eq!( - params, - serde_json::to_value((payload, vec![versioned_hash], parent_beacon_block_root)) - .expect("params serialize"), - ); - } - - #[test] - fn payload_to_new_payload_v4_preserves_requests_hash() { - let payload = sample_execution_payload_v3(); - let execution_payload = ExecutionPayload::V3(payload.clone()); - let parent_beacon_block_root = B256::from([0x33; 32]); - let versioned_hash = B256::from([0x44; 32]); - let requests_hash = B256::from([0x55; 32]); - let requests = RequestsOrHash::Hash(requests_hash); - let sidecar = ExecutionPayloadSidecar::v4( - CancunPayloadFields::new(parent_beacon_block_root, vec![versioned_hash]), - PraguePayloadFields::new(requests.clone()), - ); - - let (version, params, _) = - payload_to_new_payload(execution_payload, sidecar, None).expect("payload encodes"); - - assert_eq!(version, EngineApiMessageVersion::V4); - assert_eq!( - params, - serde_json::to_value(( - payload, - vec![versioned_hash], - parent_beacon_block_root, - requests, - )) - .expect("params serialize"), - ); - } - - #[test] - fn ethereum_block_to_payload_rejects_unsupported_transaction_types() { - let block = serde_json::from_value::(serde_json::json!({ - "hash": "0xef664d656f841b5ad6a2b527b963f1eb48b97d7889d742f6cbff6950388e24cd", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "miner": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494", - "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": format!("0x{}", "00".repeat(256)), - "difficulty": "0x0", - "number": "0x1", - "gasLimit": "0x1c9c380", - "gasUsed": "0x0", - "timestamp": "0x1", - "extraData": "0x", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0x0000000000000000", - "baseFeePerGas": "0x1", - "transactions": [{ - "blockHash": "0xef664d656f841b5ad6a2b527b963f1eb48b97d7889d742f6cbff6950388e24cd", - "blockNumber": "0x1", - "depositReceiptVersion": "0x1", - "from": "0x36bde71c97b33cc4729cf772ae268934f7ab70b2", - "gas": "0x5208", - "gasPrice": "0x1", - "hash": "0x0bf1845c5d7a82ec92365d5027f7310793d53004f3c86aa80965c67bf7e7dc80", - "input": "0x", - "mint": "0x0", - "nonce": "0x0", - "r": "0x0", - "s": "0x0", - "sourceHash": "0x074adb22f2e6ed9bdd31c52eefc1f050e5db56eb85056450bccd79a6649520b3", - "to": "0x4200000000000000000000000000000000000007", - "transactionIndex": "0x0", - "type": "0x7e", - "v": "0x0", - "value": "0x0" - }], - "uncles": [] - })) - .expect("block deserializes"); - - let err = ethereum_block_to_payload(block).expect_err("unsupported tx fails"); - assert!(err.to_string().contains("unsupported tx type")); - } - - fn sample_execution_payload_v3() -> ExecutionPayloadV3 { - ExecutionPayloadV3 { - payload_inner: ExecutionPayloadV2 { - payload_inner: ExecutionPayloadV1 { - parent_hash: B256::from([0x01; 32]), - fee_recipient: Address::from([0x02; 20]), - state_root: B256::from([0x03; 32]), - receipts_root: B256::from([0x04; 32]), - logs_bloom: Bloom::default(), - prev_randao: B256::from([0x05; 32]), - block_number: 42, - gas_limit: 30_000_000, - gas_used: 21_000, - timestamp: 1_715_555_555, - extra_data: Bytes::default(), - base_fee_per_gas: U256::from(7), - block_hash: B256::from([0x06; 32]), - transactions: vec![], - }, - withdrawals: vec![], - }, - blob_gas_used: 10, - excess_blob_gas: 20, - } - } -} From 09685631fdf0f18f1b12f559f33463be6a6add1f Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 1 Apr 2026 13:07:34 +0200 Subject: [PATCH 6/8] refactor(reth-bench): inline block payload conversion --- bin/reth-bench/src/valid_payload.rs | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/bin/reth-bench/src/valid_payload.rs b/bin/reth-bench/src/valid_payload.rs index b438ff85c87..8cb94dfc438 100644 --- a/bin/reth-bench/src/valid_payload.rs +++ b/bin/reth-bench/src/valid_payload.rs @@ -191,7 +191,14 @@ pub(crate) fn block_to_new_payload( )); } - let (payload, sidecar) = ethereum_block_to_payload(block)?; + let block = block + .into_inner() + .map_header(|header| header.map(|h| h.into_header_with_defaults())) + .try_map_transactions(|tx| -> eyre::Result { + tx.try_into().map_err(|_| eyre::eyre!("unsupported tx type")) + })? + .into_consensus(); + let (payload, sidecar) = ExecutionPayload::from_block_slow(&block); let (version, params, execution_data) = payload_to_new_payload(payload, sidecar, None)?; if reth_new_payload { @@ -208,20 +215,6 @@ pub(crate) fn block_to_new_payload( } } -fn ethereum_block_to_payload( - block: AnyRpcBlock, -) -> eyre::Result<(ExecutionPayload, ExecutionPayloadSidecar)> { - let block = block - .into_inner() - .map_header(|header| header.map(|h| h.into_header_with_defaults())) - .try_map_transactions(|tx| -> eyre::Result { - tx.try_into().map_err(|_| eyre::eyre!("unsupported tx type")) - })? - .into_consensus(); - - Ok(ExecutionPayload::from_block_slow(&block)) -} - /// Converts an execution payload and sidecar into versioned engine API params and an /// [`ExecutionData`]. /// From 0003b4ae632db3ddbec20d89a37132b19330bc8d Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 1 Apr 2026 13:12:59 +0200 Subject: [PATCH 7/8] fix(reth-bench): sync lockfile after main merge --- Cargo.lock | 37 ------------------- .../src/bench/generate_big_block.rs | 6 +-- 2 files changed, 3 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d213967c684..79e19b6c449 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6317,43 +6317,6 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" -[[package]] -name = "op-alloy-consensus" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadcb964b0aa645d12e952d470c7585d23286d8bcf1ac41589410b6724216b68" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-network", - "alloy-primitives", - "alloy-rlp", - "alloy-rpc-types-eth", - "alloy-serde", - "derive_more", - "serde", - "thiserror 2.0.18", -] - -[[package]] -name = "op-alloy-rpc-types-engine" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c0ac5c5ddcbffadcd097d278c717d34849bcc629f6e4f8514eb000ec862def8" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-primitives", - "alloy-rlp", - "alloy-rpc-types-engine", - "alloy-serde", - "derive_more", - "op-alloy-consensus", - "serde", - "sha2", - "thiserror 2.0.18", -] - [[package]] name = "opaque-debug" version = "0.3.1" diff --git a/bin/reth-bench/src/bench/generate_big_block.rs b/bin/reth-bench/src/bench/generate_big_block.rs index 17f28e86e98..8ac77137311 100644 --- a/bin/reth-bench/src/bench/generate_big_block.rs +++ b/bin/reth-bench/src/bench/generate_big_block.rs @@ -5,7 +5,7 @@ //! and saves the result to disk as a [`BigBlockPayload`] JSON file containing the merged //! [`ExecutionData`] and environment switches at each block boundary. -use alloy_consensus::TxReceipt; +use alloy_consensus::{TxEnvelope, TxReceipt}; use alloy_eips::{eip1559::BaseFeeParams, eip7840::BlobParams, Typed2718}; use alloy_primitives::{Bloom, Bytes, B256}; use alloy_provider::{network::AnyNetwork, Provider, RootProvider}; @@ -365,8 +365,8 @@ impl Command { let block = rpc_block .into_inner() .map_header(|header| header.map(|h| h.into_header_with_defaults())) - .try_map_transactions(|tx| { - tx.try_into_either::() + .try_map_transactions(|tx| -> eyre::Result { + tx.try_into().map_err(|_| eyre::eyre!("unsupported tx type")) })? .into_consensus(); From 9876ea360084f217bab7cc0a95ac29107998e21e Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 1 Apr 2026 13:16:21 +0200 Subject: [PATCH 8/8] chore: remove unused op-alloy workspace deps --- Cargo.toml | 9 --------- scripts/patch-alloy.sh | 27 +++++---------------------- 2 files changed, 5 insertions(+), 31 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c84c425fa74..90c8e34194d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -484,11 +484,6 @@ alloy-transport-http = { version = "1.8.2", features = ["reqwest-rustls-tls"], d alloy-transport-ipc = { version = "1.8.2", default-features = false } alloy-transport-ws = { version = "1.8.2", default-features = false } -# op -op-alloy-rpc-types = { version = "0.24.0", default-features = false } -op-alloy-rpc-types-engine = { version = "0.24.0", default-features = false } -op-alloy-consensus = { version = "0.24.0", default-features = false } - # misc either = { version = "1.15.0", default-features = false } arrayvec = { version = "0.7.6", default-features = false } @@ -735,10 +730,6 @@ ipnet = "2.11" # alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } # alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# op-alloy-consensus = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } -# op-alloy-rpc-types = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } -# op-alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } -# # revm-inspectors = { git = "https://github.com/paradigmxyz/revm-inspectors", rev = "1207e33" } # # jsonrpsee = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } diff --git a/scripts/patch-alloy.sh b/scripts/patch-alloy.sh index be6017581b3..abe22b12811 100755 --- a/scripts/patch-alloy.sh +++ b/scripts/patch-alloy.sh @@ -2,18 +2,17 @@ # Patches alloy dependencies in Cargo.toml for testing breaking changes. # # Usage: -# ./scripts/patch-alloy.sh [--alloy ] [--evm ] [--op ] +# ./scripts/patch-alloy.sh [--alloy ] [--evm ] # # Examples: # ./scripts/patch-alloy.sh --alloy main # ./scripts/patch-alloy.sh --alloy feat/new-api --evm main -# ./scripts/patch-alloy.sh --alloy main --evm main --op main +# ./scripts/patch-alloy.sh --alloy main --evm main set -euo pipefail ALLOY_BRANCH="" ALLOY_EVM_BRANCH="" -OP_ALLOY_BRANCH="" while [[ $# -gt 0 ]]; do case $1 in @@ -25,17 +24,12 @@ while [[ $# -gt 0 ]]; do ALLOY_EVM_BRANCH="$2" shift 2 ;; - --op) - OP_ALLOY_BRANCH="$2" - shift 2 - ;; -h|--help) - echo "Usage: $0 [--alloy ] [--evm ] [--op ]" + echo "Usage: $0 [--alloy ] [--evm ]" echo "" echo "Options:" echo " --alloy Patch alloy-rs/alloy crates" echo " --evm Patch alloy-rs/evm crates (alloy-evm, alloy-op-evm)" - echo " --op Patch alloy-rs/op-alloy crates" exit 0 ;; *) @@ -45,8 +39,8 @@ while [[ $# -gt 0 ]]; do esac done -if [[ -z "$ALLOY_BRANCH" && -z "$ALLOY_EVM_BRANCH" && -z "$OP_ALLOY_BRANCH" ]]; then - echo "Error: At least one of --alloy, --evm, or --op must be specified" +if [[ -z "$ALLOY_BRANCH" && -z "$ALLOY_EVM_BRANCH" ]]; then + echo "Error: At least one of --alloy or --evm must be specified" exit 1 fi @@ -97,17 +91,6 @@ alloy-op-evm = { git = "https://github.com/alloy-rs/evm", branch = "$ALLOY_EVM_B EOF fi -if [[ -n "$OP_ALLOY_BRANCH" ]]; then - echo "Patching alloy-rs/op-alloy with branch: $OP_ALLOY_BRANCH" - cat >> "$CARGO_TOML" << EOF -op-alloy-consensus = { git = "https://github.com/alloy-rs/op-alloy", branch = "$OP_ALLOY_BRANCH" } -op-alloy-network = { git = "https://github.com/alloy-rs/op-alloy", branch = "$OP_ALLOY_BRANCH" } -op-alloy-rpc-types = { git = "https://github.com/alloy-rs/op-alloy", branch = "$OP_ALLOY_BRANCH" } -op-alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/op-alloy", branch = "$OP_ALLOY_BRANCH" } -op-alloy-rpc-jsonrpsee = { git = "https://github.com/alloy-rs/op-alloy", branch = "$OP_ALLOY_BRANCH" } -EOF -fi - echo "Done. Patches appended to $CARGO_TOML" echo "" echo "Run 'cargo check --workspace --all-features' to verify compilation."