From 0e57513d030bb58ac1f0056917ea27db4f48f22f Mon Sep 17 00:00:00 2001 From: Francis Li Date: Mon, 3 Nov 2025 17:13:12 -0800 Subject: [PATCH] Finish linting --- Cargo.lock | 1 - crates/node/builder/src/rpc.rs | 9 ++++- crates/optimism/flashblocks/src/consensus.rs | 39 +++++++++++--------- crates/optimism/node/Cargo.toml | 1 - crates/optimism/node/src/node.rs | 33 +++-------------- crates/optimism/rpc/src/eth/mod.rs | 38 +++++++++---------- examples/custom-node/src/engine.rs | 9 +++++ 7 files changed, 60 insertions(+), 70 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d982822500..264d46b29a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9384,7 +9384,6 @@ dependencies = [ "reth-optimism-chainspec", "reth-optimism-consensus", "reth-optimism-evm", - "reth-optimism-flashblocks", "reth-optimism-forks", "reth-optimism-node", "reth-optimism-payload-builder", diff --git a/crates/node/builder/src/rpc.rs b/crates/node/builder/src/rpc.rs index a66d7b222e..6fb4dd9ce2 100644 --- a/crates/node/builder/src/rpc.rs +++ b/crates/node/builder/src/rpc.rs @@ -973,7 +973,12 @@ where ); let eth_config = config.rpc.eth_config().max_batch_size(config.txpool.max_batch_size()); - let ctx = EthApiCtx { components: &node, config: eth_config, cache }; + let ctx = EthApiCtx { + components: &node, + config: eth_config, + cache, + beacon_engine_handle: beacon_engine_handle.clone(), + }; let eth_api = eth_api_builder.build_eth_api(ctx).await?; let auth_config = config.rpc.auth_server_config(jwt_secret)?; @@ -1137,6 +1142,8 @@ pub struct EthApiCtx<'a, N: FullNodeTypes> { pub config: EthConfig, /// Cache for eth state pub cache: EthStateCache>, + /// Handle to the beacon consensus engine + pub beacon_engine_handle: ConsensusEngineHandle<::Payload>, } impl<'a, N: FullNodeComponents>> diff --git a/crates/optimism/flashblocks/src/consensus.rs b/crates/optimism/flashblocks/src/consensus.rs index 39dfb8b2d4..e9f1b07db4 100644 --- a/crates/optimism/flashblocks/src/consensus.rs +++ b/crates/optimism/flashblocks/src/consensus.rs @@ -1,6 +1,5 @@ -use crate::FlashBlockCompleteSequenceRx; +use crate::{FlashBlockCompleteSequence, FlashBlockCompleteSequenceRx}; use alloy_primitives::B256; -use op_alloy_rpc_types_engine::OpExecutionData; use reth_engine_primitives::ConsensusEngineHandle; use reth_optimism_payload_builder::OpPayloadTypes; use reth_payload_primitives::{EngineApiMessageVersion, PayloadTypes}; @@ -10,15 +9,20 @@ use tracing::*; /// /// [`FlashBlockService`]: crate::FlashBlockService #[derive(Debug)] -pub struct FlashBlockConsensusClient< - P: PayloadTypes = OpPayloadTypes, -> { +pub struct FlashBlockConsensusClient

+where + P: PayloadTypes, +{ /// Handle to execution client. engine_handle: ConsensusEngineHandle

, sequence_receiver: FlashBlockCompleteSequenceRx, } -impl> FlashBlockConsensusClient

{ +impl

FlashBlockConsensusClient

+where + P: PayloadTypes, + P::ExecutionData: for<'a> From<&'a FlashBlockCompleteSequence>, +{ /// Create a new `FlashBlockConsensusClient` with the given Op engine and sequence receiver. pub const fn new( engine_handle: ConsensusEngineHandle

, @@ -35,20 +39,20 @@ impl> FlashBlockConsensusClient Ok(sequence) => { // Extract block information for logging let last_flashblock = sequence.last(); - let block_hash = last_flashblock.diff.block_hash; + let flashblock_count = sequence.count(); let block_number = sequence.payload_base().block_number; - let tx_count = last_flashblock.diff.transactions.len(); + let block_hash = last_flashblock.diff.block_hash; let gas_used = last_flashblock.diff.gas_used; // Convert the flashblock sequence to execution payload - let payload = sequence.to_execution_data(); + let payload = P::ExecutionData::from(&sequence); // Submit new payload to the engine match self.engine_handle.new_payload(payload).await { Ok(result) => { debug!( target: "optimism::flashblocks::consensus::flashblock-client", - flashblock_count = sequence.count(), + flashblock_count, block_number, %block_hash, gas_used, @@ -62,15 +66,16 @@ impl> FlashBlockConsensusClient %err, block_number, %block_hash, - tx_count, gas_used, "failed to submit new payload" ); + return; } } - // Update fork choice to make this block the head - let forkchoice_state = alloy_rpc_types_engine::ForkchoiceState { + // Update fork choice to make this block the head, only after new_payload + // succeeded. + let fcu_state = alloy_rpc_types_engine::ForkchoiceState { head_block_hash: block_hash, safe_block_hash: B256::ZERO, finalized_block_hash: B256::ZERO, @@ -78,7 +83,7 @@ impl> FlashBlockConsensusClient match self .engine_handle - .fork_choice_updated(forkchoice_state, None, EngineApiMessageVersion::V3) + .fork_choice_updated(fcu_state, None, EngineApiMessageVersion::V3) .await { Ok(result) => { @@ -86,9 +91,7 @@ impl> FlashBlockConsensusClient target: "optimism::flashblocks::consensus::flashblock-client", block_number, %block_hash, - head_block_hash = %forkchoice_state.head_block_hash, - safe_block_hash = %forkchoice_state.safe_block_hash, - finalized_block_hash = %forkchoice_state.finalized_block_hash, + head_block_hash = %fcu_state.head_block_hash, ?result, "successfully updated fork choice" ); @@ -99,7 +102,7 @@ impl> FlashBlockConsensusClient %err, block_number, %block_hash, - head_block_hash = %forkchoice_state.head_block_hash, + head_block_hash = %fcu_state.head_block_hash, "failed to submit fork choice update" ); } diff --git a/crates/optimism/node/Cargo.toml b/crates/optimism/node/Cargo.toml index 11cb48c608..0576b3897f 100644 --- a/crates/optimism/node/Cargo.toml +++ b/crates/optimism/node/Cargo.toml @@ -42,7 +42,6 @@ reth-optimism-chainspec.workspace = true reth-optimism-consensus = { workspace = true, features = ["std"] } reth-optimism-forks.workspace = true reth-optimism-primitives = { workspace = true, features = ["serde", "serde-bincode-compat", "reth-codec"] } -reth-optimism-flashblocks.workspace = true # revm with required optimism features # Note: this must be kept to ensure all features are properly enabled/forwarded diff --git a/crates/optimism/node/src/node.rs b/crates/optimism/node/src/node.rs index a68ac8faa7..f973a2e632 100644 --- a/crates/optimism/node/src/node.rs +++ b/crates/optimism/node/src/node.rs @@ -36,7 +36,6 @@ use reth_node_builder::{ use reth_optimism_chainspec::{OpChainSpec, OpHardfork}; use reth_optimism_consensus::OpBeaconConsensus; use reth_optimism_evm::{OpEvmConfig, OpRethReceiptBuilder}; -use reth_optimism_flashblocks::FlashBlockConsensusClient; use reth_optimism_forks::OpHardforks; use reth_optimism_payload_builder::{ builder::OpPayloadTransactions, @@ -45,7 +44,7 @@ use reth_optimism_payload_builder::{ }; use reth_optimism_primitives::{DepositReceipt, OpPrimitives}; use reth_optimism_rpc::{ - eth::{ext::OpEthExtApi, FlashblockApi, OpEthApiBuilder}, + eth::{ext::OpEthExtApi, OpEthApiBuilder}, historical::{HistoricalRpc, HistoricalRpcClient}, miner::{MinerApiExtServer, OpMinerExtApi}, witness::{DebugExecutionWitnessApiServer, OpDebugWitnessApi}, @@ -498,10 +497,7 @@ where Types: NodeTypes< ChainSpec: OpHardforks, Primitives: OpPayloadPrimitives, - Payload: PayloadTypes< - ExecutionData = OpExecutionData, - PayloadBuilderAttributes = Attrs, - >, + Payload: PayloadTypes, >, Evm: ConfigureEvm< NextBlockEnvCtx: BuildNextEnv< @@ -512,7 +508,7 @@ where >, Pool: TransactionPool, >, - EthB: EthApiBuilder, + EthB: EthApiBuilder, PVB: Send, EB: EngineApiBuilder, EVB: EngineValidatorBuilder, @@ -583,10 +579,6 @@ where ctx.node.provider().clone(), ); - // Capture node components needed for FlashBlockConsensusClient - let engine_handle = ctx.beacon_engine_handle.clone(); - let task_executor = ctx.node.task_executor().clone(); - rpc_add_ons .launch_add_ons_with(ctx, move |container| { let reth_node_builder::rpc::RpcModuleContainer { modules, auth_module, registry } = @@ -621,18 +613,6 @@ where )?; } - // Launch FlashBlockConsensusClient if flashblocks are configured - if let Some(flashblock_rx) = registry.eth_api().flashblock_rx() { - info!(target: "reth::cli", "Launching FlashBlockConsensusClient"); - - let flashblock_client = - FlashBlockConsensusClient::new(engine_handle, flashblock_rx)?; - - task_executor.spawn_critical("flashblock consensus client", async move { - flashblock_client.run().await - }); - } - Ok(()) }) .await @@ -646,10 +626,7 @@ where Types: NodeTypes< ChainSpec: OpHardforks, Primitives: OpPayloadPrimitives, - Payload: PayloadTypes< - ExecutionData = OpExecutionData, - PayloadBuilderAttributes = Attrs, - >, + Payload: PayloadTypes, >, Evm: ConfigureEvm< NextBlockEnvCtx: BuildNextEnv< @@ -660,7 +637,7 @@ where >, >, <::Pool as TransactionPool>::Transaction: OpPooledTx, - EthB: EthApiBuilder, + EthB: EthApiBuilder, PVB: PayloadValidatorBuilder, EB: EngineApiBuilder, EVB: EngineValidatorBuilder, diff --git a/crates/optimism/rpc/src/eth/mod.rs b/crates/optimism/rpc/src/eth/mod.rs index ade7cdc97d..83ce060f3d 100644 --- a/crates/optimism/rpc/src/eth/mod.rs +++ b/crates/optimism/rpc/src/eth/mod.rs @@ -20,11 +20,12 @@ pub use receipt::{OpReceiptBuilder, OpReceiptFieldsBuilder}; use reqwest::Url; use reth_chainspec::{EthereumHardforks, Hardforks}; use reth_evm::ConfigureEvm; -use reth_node_api::{FullNodeComponents, FullNodeTypes, HeaderTy, NodeTypes}; +use reth_node_api::{ExecutionPayload, FullNodeComponents, FullNodeTypes, HeaderTy, NodeTypes}; use reth_node_builder::rpc::{EthApiBuilder, EthApiCtx}; use reth_optimism_flashblocks::{ - ExecutionPayloadBaseV1, FlashBlockBuildInfo, FlashBlockCompleteSequenceRx, FlashBlockRx, - FlashBlockService, FlashblocksListeners, PendingBlockRx, PendingFlashBlock, WsFlashBlockStream, + ExecutionPayloadBaseV1, FlashBlockBuildInfo, FlashBlockCompleteSequence, + FlashBlockCompleteSequenceRx, FlashBlockConsensusClient, FlashBlockRx, FlashBlockService, + FlashblocksListeners, PendingBlockRx, PendingFlashBlock, WsFlashBlockStream, }; use reth_rpc::eth::core::EthApiInner; use reth_rpc_eth_api::{ @@ -73,23 +74,6 @@ pub struct OpEthApi { inner: Arc>, } -/// Trait for accessing flashblock related functions from an Eth API. -pub trait FlashblockApi { - /// Returns a flashblock receiver, if any, by resubscribing to it. - fn flashblock_rx(&self) -> Option; -} - -// Implement FlashblockApi for OpEthApi -impl FlashblockApi for OpEthApi -where - N: reth_rpc_eth_api::RpcNodeCore, - Rpc: reth_rpc_eth_api::RpcConvert, -{ - fn flashblock_rx(&self) -> Option { - self.flashblock_rx() - } -} - impl Clone for OpEthApi { fn clone(&self) -> Self { Self { inner: self.inner.clone() } @@ -480,7 +464,12 @@ where + From + Unpin, >, - Types: NodeTypes, + Types: NodeTypes< + ChainSpec: Hardforks + EthereumHardforks, + Payload: reth_node_api::PayloadTypes< + ExecutionData: for<'a> From<&'a FlashBlockCompleteSequence> + ExecutionPayload, + >, + >, >, NetworkT: RpcTypes, OpRpcConvert: RpcConvert, @@ -529,6 +518,13 @@ where ctx.components.task_executor().spawn(Box::pin(service.run(tx))); + info!(target: "reth::cli", "Launching FlashBlockConsensusClient"); + let flashblock_client = FlashBlockConsensusClient::new( + ctx.beacon_engine_handle.clone(), + flashblocks_sequence.subscribe(), + )?; + ctx.components.task_executor().spawn(Box::pin(flashblock_client.run())); + Some(FlashblocksListeners::new( pending_rx, flashblocks_sequence, diff --git a/examples/custom-node/src/engine.rs b/examples/custom-node/src/engine.rs index 0c80e52a66..10b54a9bfb 100644 --- a/examples/custom-node/src/engine.rs +++ b/examples/custom-node/src/engine.rs @@ -68,6 +68,15 @@ impl ExecutionPayload for CustomExecutionData { } } +impl From<&reth_optimism_flashblocks::FlashBlockCompleteSequence> for CustomExecutionData { + fn from(sequence: &reth_optimism_flashblocks::FlashBlockCompleteSequence) -> Self { + let inner = OpExecutionData::from(sequence); + // Derive extension from sequence data - using gas_used from last flashblock as an example + let extension = sequence.last().diff.gas_used; + Self { inner, extension } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CustomPayloadAttributes { #[serde(flatten)]