diff --git a/crates/op-rbuilder/src/builders/builder_tx.rs b/crates/op-rbuilder/src/builders/builder_tx.rs index c4dacb469..a124e0fa4 100644 --- a/crates/op-rbuilder/src/builders/builder_tx.rs +++ b/crates/op-rbuilder/src/builders/builder_tx.rs @@ -138,25 +138,31 @@ impl BuilderTransactionError { } } -pub trait BuilderTransactions { +pub trait BuilderTransactions { // Simulates and returns the signed builder transactions. The simulation modifies and commit // changes to the db so call new_simulation_state to simulate on a new copy of the state + #[expect(clippy::too_many_arguments)] fn simulate_builder_txs( &self, state_provider: impl StateProvider + Clone, - info: &mut ExecutionInfo, - ctx: &OpPayloadBuilderCtx, + info: &mut ExecutionInfo, + ctx: &OpPayloadBuilderCtx, db: &mut State, top_of_block: bool, + is_first_flashblock: bool, + is_last_flashblock: bool, ) -> Result, BuilderTransactionError>; + #[expect(clippy::too_many_arguments)] fn simulate_builder_txs_with_state_copy( &self, state_provider: impl StateProvider + Clone, - info: &mut ExecutionInfo, - ctx: &OpPayloadBuilderCtx, + info: &mut ExecutionInfo, + ctx: &OpPayloadBuilderCtx, db: &State, top_of_block: bool, + is_first_flashblock: bool, + is_last_flashblock: bool, ) -> Result, BuilderTransactionError> { let mut simulation_state = self.new_simulation_state(state_provider.clone(), db); self.simulate_builder_txs( @@ -165,98 +171,100 @@ pub trait BuilderTransactions, - builder_ctx: &OpPayloadBuilderCtx, + info: &mut ExecutionInfo, + builder_ctx: &OpPayloadBuilderCtx, db: &mut State, top_of_block: bool, + is_first_flashblock: bool, + is_last_flashblock: bool, ) -> Result, BuilderTransactionError> { - { - let builder_txs = self.simulate_builder_txs_with_state_copy( - state_provider, - info, - builder_ctx, - db, - top_of_block, - )?; - - let mut evm = builder_ctx - .evm_config - .evm_with_env(&mut *db, builder_ctx.evm_env.clone()); - - let mut invalid = HashSet::new(); - - for builder_tx in builder_txs.iter() { - if builder_tx.is_top_of_block != top_of_block { - // don't commit tx if the buidler tx is not being added in the intended - // position in the block - continue; - } - if invalid.contains(&builder_tx.signed_tx.signer()) { - warn!(target: "payload_builder", tx_hash = ?builder_tx.signed_tx.tx_hash(), "builder signer invalid as previous builder tx reverted"); - continue; - } + let builder_txs = self.simulate_builder_txs_with_state_copy( + state_provider, + info, + builder_ctx, + db, + top_of_block, + is_first_flashblock, + is_last_flashblock, + )?; + + let mut evm = builder_ctx + .evm_config + .evm_with_env(&mut *db, builder_ctx.evm_env.clone()); + + let mut invalid = HashSet::new(); + + for builder_tx in builder_txs.iter() { + if builder_tx.is_top_of_block != top_of_block { + // don't commit tx if the buidler tx is not being added in the intended + // position in the block + continue; + } + if invalid.contains(&builder_tx.signed_tx.signer()) { + warn!(target: "payload_builder", tx_hash = ?builder_tx.signed_tx.tx_hash(), "builder signer invalid as previous builder tx reverted"); + continue; + } - let ResultAndState { result, state } = match evm.transact(&builder_tx.signed_tx) { - Ok(res) => res, - Err(err) => { - if let Some(err) = err.as_invalid_tx_err() { - if err.is_nonce_too_low() { - // if the nonce is too low, we can skip this transaction - trace!(target: "payload_builder", %err, ?builder_tx.signed_tx, "skipping nonce too low builder transaction"); - } else { - // if the transaction is invalid, we can skip it and all of its - // descendants - trace!(target: "payload_builder", %err, ?builder_tx.signed_tx, "skipping invalid builder transaction and its descendants"); - invalid.insert(builder_tx.signed_tx.signer()); - } - - continue; + let ResultAndState { result, state } = match evm.transact(&builder_tx.signed_tx) { + Ok(res) => res, + Err(err) => { + if let Some(err) = err.as_invalid_tx_err() { + if err.is_nonce_too_low() { + // if the nonce is too low, we can skip this transaction + trace!(target: "payload_builder", %err, ?builder_tx.signed_tx, "skipping nonce too low builder transaction"); + } else { + // if the transaction is invalid, we can skip it and all of its + // descendants + trace!(target: "payload_builder", %err, ?builder_tx.signed_tx, "skipping invalid builder transaction and its descendants"); + invalid.insert(builder_tx.signed_tx.signer()); } - // this is an error that we should treat as fatal for this attempt - return Err(BuilderTransactionError::EvmExecutionError(Box::new(err))); - } - }; - if !result.is_success() { - warn!(target: "payload_builder", tx_hash = ?builder_tx.signed_tx.tx_hash(), result = ?result, "builder tx reverted"); - invalid.insert(builder_tx.signed_tx.signer()); - continue; + continue; + } + // this is an error that we should treat as fatal for this attempt + return Err(BuilderTransactionError::EvmExecutionError(Box::new(err))); } + }; - // Add gas used by the transaction to cumulative gas used, before creating the receipt - let gas_used = result.gas_used(); - info.cumulative_gas_used += gas_used; - info.cumulative_da_bytes_used += builder_tx.da_size; - - let ctx = ReceiptBuilderCtx { - tx: builder_tx.signed_tx.inner(), - evm: &evm, - result, - state: &state, - cumulative_gas_used: info.cumulative_gas_used, - }; - info.receipts.push(builder_ctx.build_receipt(ctx, None)); - - // Commit changes - evm.db_mut().commit(state); - - // Append sender and transaction to the respective lists - info.executed_senders.push(builder_tx.signed_tx.signer()); - info.executed_transactions - .push(builder_tx.signed_tx.clone().into_inner()); + if !result.is_success() { + warn!(target: "payload_builder", tx_hash = ?builder_tx.signed_tx.tx_hash(), result = ?result, "builder tx reverted"); + invalid.insert(builder_tx.signed_tx.signer()); + continue; } - // Release the db reference by dropping evm - drop(evm); - - Ok(builder_txs) + // Add gas used by the transaction to cumulative gas used, before creating the receipt + let gas_used = result.gas_used(); + info.cumulative_gas_used += gas_used; + info.cumulative_da_bytes_used += builder_tx.da_size; + + let ctx = ReceiptBuilderCtx { + tx: builder_tx.signed_tx.inner(), + evm: &evm, + result, + state: &state, + cumulative_gas_used: info.cumulative_gas_used, + }; + info.receipts.push(builder_ctx.build_receipt(ctx, None)); + + // Commit changes + evm.db_mut().commit(state); + + // Append sender and transaction to the respective lists + info.executed_senders.push(builder_tx.signed_tx.signer()); + info.executed_transactions + .push(builder_tx.signed_tx.clone().into_inner()); } + + Ok(builder_txs) } // Creates a copy of the state to simulate against @@ -280,7 +288,7 @@ pub trait BuilderTransactions, + ctx: &OpPayloadBuilderCtx, db: impl DatabaseRef, ) -> Result, BuilderTransactionError> { let nonce = get_nonce(db, from.address)?; @@ -301,7 +309,7 @@ pub trait BuilderTransactions>, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, db: &mut State, ) -> Result<(), BuilderTransactionError> { let mut evm = ctx.evm_config.evm_with_env(&mut *db, ctx.evm_env.clone()); @@ -389,22 +397,18 @@ pub trait BuilderTransactions { +pub(super) struct BuilderTxBase { pub signer: Option, - _marker: std::marker::PhantomData, } -impl BuilderTxBase { +impl BuilderTxBase { pub(super) fn new(signer: Option) -> Self { - Self { - signer, - _marker: std::marker::PhantomData, - } + Self { signer } } pub(super) fn simulate_builder_tx( &self, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, db: impl DatabaseRef, ) -> Result, BuilderTransactionError> { match self.signer { @@ -449,7 +453,7 @@ impl BuilderTxBase { fn signed_builder_tx( &self, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, db: impl DatabaseRef, signer: Signer, gas_used: u64, diff --git a/crates/op-rbuilder/src/builders/context.rs b/crates/op-rbuilder/src/builders/context.rs index 7c0deec69..120aab466 100644 --- a/crates/op-rbuilder/src/builders/context.rs +++ b/crates/op-rbuilder/src/builders/context.rs @@ -53,19 +53,9 @@ use crate::{ tx_signer::Signer, }; -/// Extra context trait that optionally provides the current flashblock index within a block. -pub trait MaybeFlashblockIndex { - fn flashblock_index(&self) -> Option { - None - } -} - -/// Standard (non-flashblock) builds have no flashblock index. -impl MaybeFlashblockIndex for () {} - /// Container type that holds all necessities to build a new payload. #[derive(Debug)] -pub struct OpPayloadBuilderCtx { +pub struct OpPayloadBuilderCtx { /// The type that knows how to perform system calls and configure the evm. pub evm_config: OpEvmConfig, /// The DA config for the payload builder @@ -86,8 +76,6 @@ pub struct OpPayloadBuilderCtx { pub builder_signer: Option, /// The metrics for the builder pub metrics: Arc, - /// Extra context for the payload builder - pub extra_ctx: ExtraCtx, /// Max gas that can be used by a transaction. pub max_gas_per_txn: Option, /// Rate limiting based on gas. This is an optional feature. @@ -96,15 +84,11 @@ pub struct OpPayloadBuilderCtx { pub backrun_ctx: BackrunBundlesPayloadCtx, } -impl OpPayloadBuilderCtx { +impl OpPayloadBuilderCtx { pub(super) fn with_cancel(self, cancel: CancellationToken) -> Self { Self { cancel, ..self } } - pub(super) fn with_extra_ctx(self, extra_ctx: ExtraCtx) -> Self { - Self { extra_ctx, ..self } - } - /// Returns the parent block the payload will be build on. pub fn parent(&self) -> &SealedHeader { &self.config.parent_header @@ -166,10 +150,7 @@ impl OpPayloadBuilderCtx { /// This will return the culmative DA bytes * scalar after Jovian /// after Ecotone, this will always return Some(0) as blobs aren't supported /// pre Ecotone, these fields aren't used. - pub fn blob_fields( - &self, - info: &ExecutionInfo, - ) -> (Option, Option) { + pub fn blob_fields(&self, info: &ExecutionInfo) -> (Option, Option) { // For payload validation if let Some(blob_fields) = info.optional_blob_fields { return blob_fields; @@ -265,7 +246,7 @@ impl OpPayloadBuilderCtx { } } -impl OpPayloadBuilderCtx { +impl OpPayloadBuilderCtx { /// Constructs a receipt for the given transaction. pub fn build_receipt( &self, @@ -299,10 +280,10 @@ impl OpPayloadBuilderCtx { } /// Executes all sequencer transactions that are included in the payload attributes. - pub(super) fn execute_sequencer_transactions( + pub(super) fn execute_sequencer_transactions( &self, db: &mut State, - ) -> Result, PayloadBuilderError> { + ) -> Result { let mut info = ExecutionInfo::with_capacity(self.attributes().transactions.len()); let mut evm = self.evm_config.evm_with_env(&mut *db, self.evm_env.clone()); @@ -398,18 +379,20 @@ impl OpPayloadBuilderCtx { } } -impl OpPayloadBuilderCtx { +impl OpPayloadBuilderCtx { /// Executes the given best transactions and updates the execution info. /// /// Returns `Ok(Some(())` if the job was cancelled. - pub(super) fn execute_best_transactions( + #[expect(clippy::too_many_arguments)] + pub(super) fn execute_best_transactions( &self, - info: &mut ExecutionInfo, + info: &mut ExecutionInfo, db: &mut State, best_txs: &mut impl PayloadTxsBounds, block_gas_limit: u64, block_da_limit: Option, block_da_footprint_limit: Option, + flashblock_index: Option, ) -> Result, PayloadBuilderError> { let execute_txs_start_time = Instant::now(); let mut num_txs_considered = 0; @@ -704,7 +687,7 @@ impl OpPayloadBuilderCtx, - pub flashtestations_builder_tx: - Option>, + pub base_builder_tx: BuilderTxBase, + pub flashtestations_builder_tx: Option, } impl FlashblocksBuilderTx { pub(super) fn new( signer: Option, - flashtestations_builder_tx: Option< - FlashtestationsBuilderTx, - >, + flashtestations_builder_tx: Option, ) -> Self { let base_builder_tx = BuilderTxBase::new(signer); Self { @@ -77,23 +71,25 @@ impl FlashblocksBuilderTx { } } -impl BuilderTransactions for FlashblocksBuilderTx { +impl BuilderTransactions for FlashblocksBuilderTx { fn simulate_builder_txs( &self, state_provider: impl StateProvider + Clone, - info: &mut ExecutionInfo, - ctx: &OpPayloadBuilderCtx, + info: &mut ExecutionInfo, + ctx: &OpPayloadBuilderCtx, db: &mut State, top_of_block: bool, + is_first_flashblock: bool, + is_last_flashblock: bool, ) -> Result, BuilderTransactionError> { let mut builder_txs = Vec::::new(); - if ctx.is_first_flashblock() { + if is_first_flashblock { let flashblocks_builder_tx = self.base_builder_tx.simulate_builder_tx(ctx, &mut *db)?; builder_txs.extend(flashblocks_builder_tx.clone()); } - if ctx.is_last_flashblock() { + if is_last_flashblock { let base_tx = self.base_builder_tx.simulate_builder_tx(ctx, &mut *db)?; builder_txs.extend(base_tx.clone()); @@ -109,6 +105,8 @@ impl BuilderTransactions for Flas ctx, db, top_of_block, + is_first_flashblock, + is_last_flashblock, ) { Ok(flashtestations_builder_txs) => { builder_txs.extend(flashtestations_builder_txs) @@ -129,9 +127,8 @@ pub(super) struct FlashblocksNumberBuilderTx { pub signer: Signer, pub flashblock_number_address: Address, pub use_permit: bool, - pub base_builder_tx: BuilderTxBase, - pub flashtestations_builder_tx: - Option>, + pub base_builder_tx: BuilderTxBase, + pub flashtestations_builder_tx: Option, } impl FlashblocksNumberBuilderTx { @@ -139,9 +136,7 @@ impl FlashblocksNumberBuilderTx { signer: Signer, flashblock_number_address: Address, use_permit: bool, - flashtestations_builder_tx: Option< - FlashtestationsBuilderTx, - >, + flashtestations_builder_tx: Option, ) -> Self { let base_builder_tx = BuilderTxBase::new(Some(signer)); Self { @@ -155,7 +150,7 @@ impl FlashblocksNumberBuilderTx { fn signed_increment_flashblocks_tx( &self, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result { let calldata = IFlashblockNumber::incrementFlashblockNumberCall {}; @@ -166,7 +161,7 @@ impl FlashblocksNumberBuilderTx { &self, flashtestations_signer: &Signer, current_flashblock_number: U256, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result { let struct_hash_calldata = IFlashblockNumber::computeStructHashCall { @@ -185,7 +180,7 @@ impl FlashblocksNumberBuilderTx { fn signed_increment_flashblocks_permit_tx( &self, flashtestations_signer: &Signer, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result { let current_flashblock_calldata = IFlashblockNumber::flashblockNumberCall {}; @@ -203,7 +198,7 @@ impl FlashblocksNumberBuilderTx { fn increment_flashblocks_tx( &self, calldata: T, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result { let SimulationSuccessResult { gas_used, .. } = self.simulate_flashblocks_call( @@ -233,7 +228,7 @@ impl FlashblocksNumberBuilderTx { fn simulate_flashblocks_readonly_call( &self, calldata: T, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result, BuilderTransactionError> { self.simulate_flashblocks_call(calldata, vec![], ctx, evm) @@ -243,7 +238,7 @@ impl FlashblocksNumberBuilderTx { &self, calldata: T, expected_logs: Vec, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result, BuilderTransactionError> { let tx_req = OpTransactionRequest::default() @@ -261,20 +256,20 @@ impl FlashblocksNumberBuilderTx { } } -impl BuilderTransactions - for FlashblocksNumberBuilderTx -{ +impl BuilderTransactions for FlashblocksNumberBuilderTx { fn simulate_builder_txs( &self, state_provider: impl StateProvider + Clone, - info: &mut ExecutionInfo, - ctx: &OpPayloadBuilderCtx, + info: &mut ExecutionInfo, + ctx: &OpPayloadBuilderCtx, db: &mut State, top_of_block: bool, + is_first_flashblock: bool, + is_last_flashblock: bool, ) -> Result, BuilderTransactionError> { let mut builder_txs = Vec::::new(); - if ctx.is_first_flashblock() { + if is_first_flashblock { // fallback block builder tx builder_txs.extend(self.base_builder_tx.simulate_builder_tx(ctx, &mut *db)?); } else { @@ -310,7 +305,7 @@ impl BuilderTransactions builder_txs.extend(tx); } - if ctx.is_last_flashblock() + if is_last_flashblock && let Some(flashtestations_builder_tx) = &self.flashtestations_builder_tx { // Commit state that should be included to compute the correct nonce @@ -328,6 +323,8 @@ impl BuilderTransactions ctx, db, top_of_block, + is_first_flashblock, + is_last_flashblock, ) { Ok(flashtestations_builder_txs) => builder_txs.extend(flashtestations_builder_txs), Err(e) => { diff --git a/crates/op-rbuilder/src/builders/flashblocks/ctx.rs b/crates/op-rbuilder/src/builders/flashblocks/ctx.rs index a65b87b70..2e6c088ef 100644 --- a/crates/op-rbuilder/src/builders/flashblocks/ctx.rs +++ b/crates/op-rbuilder/src/builders/flashblocks/ctx.rs @@ -101,7 +101,6 @@ impl OpPayloadSyncerCtx { cancel, builder_signer: None, metrics: self.metrics, - extra_ctx: (), max_gas_per_txn: self.max_gas_per_txn, address_gas_limiter: AddressGasLimiter::new(GasLimiterArgs::default()), backrun_ctx, diff --git a/crates/op-rbuilder/src/builders/flashblocks/payload.rs b/crates/op-rbuilder/src/builders/flashblocks/payload.rs index 096aea22e..318926904 100644 --- a/crates/op-rbuilder/src/builders/flashblocks/payload.rs +++ b/crates/op-rbuilder/src/builders/flashblocks/payload.rs @@ -4,7 +4,7 @@ use crate::{ builders::{ BuilderConfig, builder_tx::BuilderTransactions, - context::{MaybeFlashblockIndex, OpPayloadBuilderCtx}, + context::OpPayloadBuilderCtx, flashblocks::{ best_txs::BestFlashblocksTxs, config::FlashBlocksConfigExt, timing::FlashblockScheduler, }, @@ -21,7 +21,7 @@ use alloy_consensus::{ }; use alloy_eips::{Encodable2718, eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE}; use alloy_evm::block::BlockExecutionResult; -use alloy_primitives::{Address, B256, U256}; +use alloy_primitives::{Address, B256, Bytes, U256}; use eyre::WrapErr as _; use op_alloy_rpc_types_engine::{ OpFlashblockPayload, OpFlashblockPayloadBase, OpFlashblockPayloadDelta, @@ -86,13 +86,7 @@ type NextBestFlashblocksTxs = BestFlashblocksTxs< >; #[derive(Debug, Default, Clone)] -pub(super) struct FlashblocksExecutionInfo { - /// Index of the last consumed flashblock - last_flashblock_index: usize, -} - -#[derive(Debug, Default, Clone)] -pub struct FlashblocksExtraCtx { +pub(super) struct FlashblocksState { /// Current flashblock index flashblock_index: u64, /// Target flashblock count per block @@ -111,17 +105,23 @@ pub struct FlashblocksExtraCtx { da_footprint_per_batch: Option, /// Whether to disable state root calculation for each flashblock disable_state_root: bool, + /// Index into ExecutionInfo tracking the last consumed flashblock + /// Used for slicing transactions/receipts per flashblock + last_flashblock_tx_index: usize, } -impl MaybeFlashblockIndex for FlashblocksExtraCtx { - fn flashblock_index(&self) -> Option { - Some(self.flashblock_index) +impl FlashblocksState { + fn new(target_flashblock_count: u64, disable_state_root: bool) -> Self { + Self { + target_flashblock_count, + disable_state_root, + ..Default::default() + } } -} -impl FlashblocksExtraCtx { + /// Creates state for the next flashblock with updated limits fn next( - self, + &self, target_gas_for_batch: u64, target_da_for_batch: Option, target_da_footprint_for_batch: Option, @@ -131,33 +131,97 @@ impl FlashblocksExtraCtx { target_gas_for_batch, target_da_for_batch, target_da_footprint_for_batch, - ..self + target_flashblock_count: self.target_flashblock_count, + gas_per_batch: self.gas_per_batch, + da_per_batch: self.da_per_batch, + da_footprint_per_batch: self.da_footprint_per_batch, + disable_state_root: self.disable_state_root, + last_flashblock_tx_index: self.last_flashblock_tx_index, } } -} -impl OpPayloadBuilderCtx { - /// Returns the current flashblock index - pub(crate) fn flashblock_index(&self) -> u64 { - self.extra_ctx.flashblock_index + fn with_batch_limits( + mut self, + gas_per_batch: u64, + da_per_batch: Option, + da_footprint_per_batch: Option, + target_gas_for_batch: u64, + target_da_for_batch: Option, + target_da_footprint_for_batch: Option, + ) -> Self { + self.gas_per_batch = gas_per_batch; + self.da_per_batch = da_per_batch; + self.da_footprint_per_batch = da_footprint_per_batch; + self.target_gas_for_batch = target_gas_for_batch; + self.target_da_for_batch = target_da_for_batch; + self.target_da_footprint_for_batch = target_da_footprint_for_batch; + self + } + + fn flashblock_index(&self) -> u64 { + self.flashblock_index + } + + fn target_flashblock_count(&self) -> u64 { + self.target_flashblock_count + } + + fn is_first_flashblock(&self) -> bool { + self.flashblock_index == 0 + } + + fn is_last_flashblock(&self) -> bool { + self.flashblock_index == self.target_flashblock_count + } + + fn target_gas_for_batch(&self) -> u64 { + self.target_gas_for_batch + } + + fn target_da_for_batch(&self) -> Option { + self.target_da_for_batch + } + + fn target_da_footprint_for_batch(&self) -> Option { + self.target_da_footprint_for_batch } - /// Returns the target flashblock count - pub(crate) fn target_flashblock_count(&self) -> u64 { - self.extra_ctx.target_flashblock_count + fn gas_per_batch(&self) -> u64 { + self.gas_per_batch } - /// Returns if the flashblock is the first fallback block - pub(crate) fn is_first_flashblock(&self) -> bool { - self.flashblock_index() == 0 + fn da_per_batch(&self) -> Option { + self.da_per_batch + } + + fn da_footprint_per_batch(&self) -> Option { + self.da_footprint_per_batch + } + + fn disable_state_root(&self) -> bool { + self.disable_state_root + } + + fn set_last_flashblock_tx_index(&mut self, index: usize) { + self.last_flashblock_tx_index = index; + } + + /// Extracts new transactions since the last flashblock + fn slice_new_transactions<'a>( + &self, + all_transactions: &'a [OpTransactionSigned], + ) -> &'a [OpTransactionSigned] { + &all_transactions[self.last_flashblock_tx_index..] } - /// Returns if the flashblock is the last one - pub(crate) fn is_last_flashblock(&self) -> bool { - self.flashblock_index() == self.target_flashblock_count() + /// Extracts new receipts since the last flashblock + fn slice_new_receipts<'a>(&self, all_receipts: &'a [OpReceipt]) -> &'a [OpReceipt] { + &all_receipts[self.last_flashblock_tx_index..] } } +// Flashblocks-specific helper methods moved to FlashblocksState + /// Optimism's payload builder #[derive(Debug, Clone)] pub(super) struct OpPayloadBuilder { @@ -252,7 +316,7 @@ impl OpPayloadBuilder where Pool: PoolBounds, Client: ClientBounds, - BuilderTx: BuilderTransactions + Send + Sync, + BuilderTx: BuilderTransactions + Send + Sync, { fn get_op_payload_builder_ctx( &self, @@ -260,8 +324,7 @@ where OpPayloadBuilderAttributes, >, cancel: CancellationToken, - extra_ctx: FlashblocksExtraCtx, - ) -> eyre::Result> { + ) -> eyre::Result { let chain_spec = self.client.chain_spec(); let timestamp = config.attributes.timestamp(); @@ -308,7 +371,7 @@ where args: self.config.backrun_bundle_args.clone(), }; - Ok(OpPayloadBuilderCtx:: { + Ok(OpPayloadBuilderCtx { evm_config: self.evm_config.clone(), chain_spec, config, @@ -319,7 +382,6 @@ where gas_limit_config: self.config.gas_limit_config.clone(), builder_signer: self.config.builder_signer, metrics: self.metrics.clone(), - extra_ctx, max_gas_per_txn: self.config.max_gas_per_txn, address_gas_limiter: self.address_gas_limiter.clone(), backrun_ctx, @@ -365,17 +427,13 @@ where let disable_state_root = self.config.specific.disable_state_root; let ctx = self - .get_op_payload_builder_ctx( - config.clone(), - block_cancel.clone(), - FlashblocksExtraCtx { - target_flashblock_count: self.config.flashblocks_per_block(), - disable_state_root, - ..Default::default() - }, - ) + .get_op_payload_builder_ctx(config.clone(), block_cancel.clone()) .map_err(|e| PayloadBuilderError::Other(e.into()))?; + // Initialize flashblocks state for this block + let mut fb_state = + FlashblocksState::new(self.config.flashblocks_per_block(), disable_state_root); + let state_provider = self.client.state_by_block_hash(ctx.parent().hash())?; let db = StateProviderDatabase::new(&state_provider); self.address_gas_limiter.refresh(ctx.block_number()); @@ -394,9 +452,15 @@ where // We add first builder tx right after deposits if !ctx.attributes().no_tx_pool - && let Err(e) = - self.builder_tx - .add_builder_txs(&state_provider, &mut info, &ctx, &mut state, false) + && let Err(e) = self.builder_tx.add_builder_txs( + &state_provider, + &mut info, + &ctx, + &mut state, + false, + fb_state.is_first_flashblock(), + fb_state.is_last_flashblock(), + ) { error!( target: "payload_builder", @@ -408,6 +472,7 @@ where let (payload, fb_payload) = build_block( &mut state, &ctx, + Some(&mut fb_state), &mut info, !disable_state_root || ctx.attributes().no_tx_pool, // need to calculate state root for CL sync )?; @@ -508,21 +573,23 @@ where .da_footprint_scalar .map(|_| ctx.block_gas_limit() / target_flashblocks); - let extra_ctx = FlashblocksExtraCtx { - flashblock_index: 1, - target_flashblock_count: target_flashblocks, - target_gas_for_batch: gas_per_batch, - target_da_for_batch: da_per_batch, + fb_state = fb_state.with_batch_limits( gas_per_batch, da_per_batch, da_footprint_per_batch, - disable_state_root, - target_da_footprint_for_batch: da_footprint_per_batch, + gas_per_batch, + da_per_batch, + da_footprint_per_batch, + ); + fb_state = FlashblocksState { + flashblock_index: 1, + target_flashblock_count: target_flashblocks, + ..fb_state }; let fb_cancel = block_cancel.child_token(); let mut ctx = self - .get_op_payload_builder_ctx(config, fb_cancel.clone(), extra_ctx) + .get_op_payload_builder_ctx(config, fb_cancel.clone()) .map_err(|e| PayloadBuilderError::Other(e.into()))?; // Create best_transaction iterator @@ -550,14 +617,14 @@ where debug!( target: "payload_builder", id = %fb_payload.payload_id, - flashblock_index = ctx.flashblock_index(), + flashblock_index = fb_state.flashblock_index(), block_number = ctx.block_number(), "Received signal to build flashblock", ); ctx = ctx.with_cancel(new_fb_cancel); } else { // Channel closed - block building cancelled - self.record_flashblocks_metrics(&ctx, &info, target_flashblocks, &span); + self.record_flashblocks_metrics(&ctx, &fb_state, &info, target_flashblocks, &span); return Ok(()); } @@ -573,8 +640,9 @@ where let _entered = fb_span.enter(); // Build flashblock after receiving signal - let next_flashblocks_ctx = match self.build_next_flashblock( + let next_flashblock_state = match self.build_next_flashblock( &ctx, + &mut fb_state, &mut info, &mut state, &state_provider, @@ -582,16 +650,22 @@ where &block_cancel, &best_payload, ) { - Ok(Some(next_flashblocks_ctx)) => next_flashblocks_ctx, + Ok(Some(next_flashblock_state)) => next_flashblock_state, Ok(None) => { - self.record_flashblocks_metrics(&ctx, &info, target_flashblocks, &span); + self.record_flashblocks_metrics( + &ctx, + &fb_state, + &info, + target_flashblocks, + &span, + ); return Ok(()); } Err(err) => { error!( target: "payload_builder", id = %fb_payload.payload_id, - flashblock_index = ctx.flashblock_index(), + flashblock_index = fb_state.flashblock_index(), block_number = ctx.block_number(), ?err, "Failed to build flashblock", @@ -600,7 +674,7 @@ where } }; - ctx = ctx.with_extra_ctx(next_flashblocks_ctx); + fb_state = next_flashblock_state; } } @@ -610,18 +684,19 @@ where P: StateRootProvider + HashedPostStateProvider + StorageRootProvider, >( &self, - ctx: &OpPayloadBuilderCtx, - info: &mut ExecutionInfo, + ctx: &OpPayloadBuilderCtx, + fb_state: &mut FlashblocksState, + info: &mut ExecutionInfo, state: &mut State, state_provider: impl reth::providers::StateProvider + Clone, best_txs: &mut NextBestFlashblocksTxs, block_cancel: &CancellationToken, best_payload: &BlockCell, - ) -> eyre::Result> { - let flashblock_index = ctx.flashblock_index(); - let mut target_gas_for_batch = ctx.extra_ctx.target_gas_for_batch; - let mut target_da_for_batch = ctx.extra_ctx.target_da_for_batch; - let mut target_da_footprint_for_batch = ctx.extra_ctx.target_da_footprint_for_batch; + ) -> eyre::Result> { + let flashblock_index = fb_state.flashblock_index(); + let mut target_gas_for_batch = fb_state.target_gas_for_batch(); + let mut target_da_for_batch = fb_state.target_da_for_batch(); + let mut target_da_footprint_for_batch = fb_state.target_da_footprint_for_batch(); info!( target: "payload_builder", @@ -637,17 +712,21 @@ where ); let flashblock_build_start_time = Instant::now(); - let builder_txs = - match self - .builder_tx - .add_builder_txs(&state_provider, info, ctx, state, true) - { - Ok(builder_txs) => builder_txs, - Err(e) => { - error!(target: "payload_builder", "Error simulating builder txs: {}", e); - vec![] - } - }; + let builder_txs = self + .builder_tx + .add_builder_txs( + &state_provider, + info, + ctx, + state, + true, + fb_state.is_first_flashblock(), + fb_state.is_last_flashblock(), + ) + .inspect_err( + |e| error!(target: "payload_builder", "Error simulating builder txs: {}", e), + ) + .unwrap_or_default(); // only reserve builder tx gas / da size that has not been committed yet // committed builder txs would have counted towards the gas / da used @@ -697,14 +776,15 @@ where target_gas_for_batch.min(ctx.block_gas_limit()), target_da_for_batch, target_da_footprint_for_batch, + Some(fb_state.flashblock_index), ) .wrap_err("failed to execute best transactions")?; // Extract last transactions - let new_transactions = info.executed_transactions[info.extra.last_flashblock_index..] - .to_vec() + let new_transactions: Vec<_> = fb_state + .slice_new_transactions(&info.executed_transactions) .iter() .map(|tx| tx.tx_hash()) - .collect::>(); + .collect(); best_txs.mark_commited(new_transactions); // We got block cancelled, we won't need anything from the block at this point @@ -721,19 +801,26 @@ where .payload_transaction_simulation_gauge .set(payload_transaction_simulation_time); - if let Err(e) = self - .builder_tx - .add_builder_txs(&state_provider, info, ctx, state, false) - { + if let Err(e) = self.builder_tx.add_builder_txs( + &state_provider, + info, + ctx, + state, + false, + fb_state.is_first_flashblock(), + fb_state.is_last_flashblock(), + ) { error!(target: "payload_builder", "Error simulating builder txs: {}", e); - }; + } let total_block_built_duration = Instant::now(); + let disable_state_root = fb_state.disable_state_root(); let build_result = build_block( state, ctx, + Some(fb_state), info, - !ctx.extra_ctx.disable_state_root || ctx.attributes().no_tx_pool, + !disable_state_root || ctx.attributes().no_tx_pool, ); let total_block_built_duration = total_block_built_duration.elapsed(); ctx.metrics @@ -785,7 +872,7 @@ where .record(info.executed_transactions.len() as f64); // Update bundle_state for next iteration - if let Some(da_limit) = ctx.extra_ctx.da_per_batch { + if let Some(da_limit) = fb_state.da_per_batch() { if let Some(da) = target_da_for_batch.as_mut() { *da += da_limit; } else { @@ -796,16 +883,16 @@ where } let target_gas_for_batch = - ctx.extra_ctx.target_gas_for_batch + ctx.extra_ctx.gas_per_batch; + fb_state.target_gas_for_batch() + fb_state.gas_per_batch(); if let (Some(footprint), Some(da_footprint_limit)) = ( target_da_footprint_for_batch.as_mut(), - ctx.extra_ctx.da_footprint_per_batch, + fb_state.da_footprint_per_batch(), ) { *footprint += da_footprint_limit; } - let next_extra_ctx = ctx.extra_ctx.clone().next( + let next_flashblock_state = fb_state.next( target_gas_for_batch, target_da_for_batch, target_da_footprint_for_batch, @@ -818,11 +905,11 @@ where flashblock_index = flashblock_index, current_gas = info.cumulative_gas_used, current_da = info.cumulative_da_bytes_used, - target_flashblocks = ctx.target_flashblock_count(), + target_flashblocks = fb_state.target_flashblock_count(), "Flashblock built" ); - Ok(Some(next_extra_ctx)) + Ok(Some(next_flashblock_state)) } } } @@ -830,18 +917,19 @@ where /// Do some logging and metric recording when we stop build flashblocks fn record_flashblocks_metrics( &self, - ctx: &OpPayloadBuilderCtx, - info: &ExecutionInfo, + ctx: &OpPayloadBuilderCtx, + fb_state: &FlashblocksState, + info: &ExecutionInfo, flashblocks_per_block: u64, span: &tracing::Span, ) { ctx.metrics.block_built_success.increment(1); ctx.metrics .flashblock_count - .record(ctx.flashblock_index() as f64); + .record(fb_state.flashblock_index() as f64); ctx.metrics .missing_flashblocks_count - .record(flashblocks_per_block.saturating_sub(ctx.flashblock_index()) as f64); + .record(flashblocks_per_block.saturating_sub(fb_state.flashblock_index()) as f64); ctx.metrics .payload_num_tx .record(info.executed_transactions.len() as f64); @@ -854,11 +942,11 @@ where event = "build_complete", id = %ctx.payload_id(), flashblocks_per_block = flashblocks_per_block, - flashblock_index = ctx.flashblock_index(), + flashblock_index = fb_state.flashblock_index(), "Flashblocks building complete" ); - span.record("flashblock_count", ctx.flashblock_index()); + span.record("flashblock_count", fb_state.flashblock_index()); } } @@ -867,8 +955,7 @@ impl PayloadBuilder for OpPayloadBuilder + Clone + Send + Sync, + BuilderTx: BuilderTransactions + Clone + Send + Sync, { type Attributes = OpPayloadBuilderAttributes; type BuiltPayload = OpBuiltPayload; @@ -882,13 +969,12 @@ where } } -fn execute_pre_steps( +fn execute_pre_steps( state: &mut State, - ctx: &OpPayloadBuilderCtx, -) -> Result, PayloadBuilderError> + ctx: &OpPayloadBuilderCtx, +) -> Result where DB: Database + std::fmt::Debug, - ExtraCtx: std::fmt::Debug + Default, { // 1. apply pre-execution changes ctx.evm_config @@ -902,16 +988,16 @@ where Ok(info) } -pub(super) fn build_block( +pub(super) fn build_block( state: &mut State, - ctx: &OpPayloadBuilderCtx, - info: &mut ExecutionInfo, + ctx: &OpPayloadBuilderCtx, + fb_state: Option<&mut FlashblocksState>, + info: &mut ExecutionInfo, calculate_state_root: bool, ) -> Result<(OpBuiltPayload, OpFlashblockPayload), PayloadBuilderError> where DB: Database + AsRef

, P: StateRootProvider + HashedPostStateProvider + StorageRootProvider, - ExtraCtx: std::fmt::Debug + Default, { // We use it to preserve state, so we run merge_transitions on transition state at most once let untouched_transition_state = state.transition_state.clone(); @@ -1086,20 +1172,29 @@ where let block_hash = sealed_block.hash(); // pick the new transactions from the info field and update the last flashblock index - let new_transactions = info.executed_transactions[info.extra.last_flashblock_index..].to_vec(); + let (new_transactions, new_receipts) = if let Some(fb_state) = fb_state { + let new_txs = fb_state.slice_new_transactions(&info.executed_transactions); + let new_receipts = fb_state.slice_new_receipts(&info.receipts); + fb_state.set_last_flashblock_tx_index(info.executed_transactions.len()); + (new_txs, new_receipts) + } else { + ( + info.executed_transactions.as_slice(), + info.receipts.as_slice(), + ) + }; - let new_transactions_encoded = new_transactions + let new_transactions_encoded: Vec = new_transactions .iter() .map(|tx| tx.encoded_2718().into()) - .collect::>(); + .collect(); - let new_receipts = info.receipts[info.extra.last_flashblock_index..].to_vec(); - info.extra.last_flashblock_index = info.executed_transactions.len(); - let receipts_with_hash = new_transactions + let receipts_with_hash: BTreeMap = new_transactions .iter() .zip(new_receipts.iter()) .map(|(tx, receipt)| (tx.tx_hash(), convert_receipt(receipt))) - .collect::>(); + .collect(); + let metadata = OpFlashblockPayloadMetadata { receipts: receipts_with_hash, new_account_balances, diff --git a/crates/op-rbuilder/src/builders/flashblocks/payload_handler.rs b/crates/op-rbuilder/src/builders/flashblocks/payload_handler.rs index 59a86ea04..4fc8fd99e 100644 --- a/crates/op-rbuilder/src/builders/flashblocks/payload_handler.rs +++ b/crates/op-rbuilder/src/builders/flashblocks/payload_handler.rs @@ -1,7 +1,5 @@ use crate::{ - builders::flashblocks::{ - ctx::OpPayloadSyncerCtx, p2p::Message, payload::FlashblocksExecutionInfo, - }, + builders::flashblocks::{ctx::OpPayloadSyncerCtx, p2p::Message, payload::build_block}, primitives::reth::ExecutionInfo, traits::ClientBounds, }; @@ -288,13 +286,8 @@ where cancel, ); - let (built_payload, fb_payload) = crate::builders::flashblocks::payload::build_block( - &mut state, - &builder_ctx, - &mut info, - true, - ) - .wrap_err("failed to build flashblock")?; + let (built_payload, fb_payload) = build_block(&mut state, &builder_ctx, None, &mut info, true) + .wrap_err("failed to build flashblock")?; builder_ctx .metrics @@ -320,7 +313,7 @@ where #[allow(clippy::too_many_arguments)] fn execute_transactions( ctx: &OpPayloadSyncerCtx, - info: &mut ExecutionInfo, + info: &mut ExecutionInfo, state: &mut State, txs: Vec, gas_limit: u64, diff --git a/crates/op-rbuilder/src/builders/flashblocks/service.rs b/crates/op-rbuilder/src/builders/flashblocks/service.rs index a790cb595..c520f7bb4 100644 --- a/crates/op-rbuilder/src/builders/flashblocks/service.rs +++ b/crates/op-rbuilder/src/builders/flashblocks/service.rs @@ -6,7 +6,6 @@ use crate::{ flashblocks::{ builder_tx::{FlashblocksBuilderTx, FlashblocksNumberBuilderTx}, p2p::{AGENT_VERSION, FLASHBLOCKS_STREAM_PROTOCOL, Message}, - payload::{FlashblocksExecutionInfo, FlashblocksExtraCtx}, payload_handler::PayloadHandler, wspub::WebSocketPublisher, }, @@ -38,12 +37,7 @@ impl FlashblocksServiceBuilder { where Node: NodeBounds, Pool: PoolBounds, - BuilderTx: BuilderTransactions - + Unpin - + Clone - + Send - + Sync - + 'static, + BuilderTx: BuilderTransactions + Unpin + Clone + Send + Sync + 'static, { // TODO: is there a different global token? // this is effectively unused right now due to the usage of reth's `task_executor`. diff --git a/crates/op-rbuilder/src/builders/standard/builder_tx.rs b/crates/op-rbuilder/src/builders/standard/builder_tx.rs index ececc887e..be0f03780 100644 --- a/crates/op-rbuilder/src/builders/standard/builder_tx.rs +++ b/crates/op-rbuilder/src/builders/standard/builder_tx.rs @@ -43,6 +43,8 @@ impl BuilderTransactions for StandardBuilderTx { ctx: &OpPayloadBuilderCtx, db: &mut State, top_of_block: bool, + is_first_flashblock: bool, + is_last_flashblock: bool, ) -> Result, BuilderTransactionError> { let mut builder_txs = Vec::::new(); let standard_builder_tx = self.base_builder_tx.simulate_builder_tx(ctx, &mut *db)?; @@ -57,6 +59,8 @@ impl BuilderTransactions for StandardBuilderTx { ctx, db, top_of_block, + is_first_flashblock, + is_last_flashblock, ) { Ok(flashtestations_builder_txs) => builder_txs.extend(flashtestations_builder_txs), Err(e) => { diff --git a/crates/op-rbuilder/src/builders/standard/payload.rs b/crates/op-rbuilder/src/builders/standard/payload.rs index dd5e5145e..48dd9d1d8 100644 --- a/crates/op-rbuilder/src/builders/standard/payload.rs +++ b/crates/op-rbuilder/src/builders/standard/payload.rs @@ -258,7 +258,6 @@ where cancel, builder_signer: self.config.builder_signer, metrics: self.metrics.clone(), - extra_ctx: Default::default(), max_gas_per_txn: self.config.max_gas_per_txn, address_gas_limiter: self.address_gas_limiter.clone(), backrun_ctx, @@ -368,14 +367,12 @@ impl OpBuilder<'_, Txs> { // 4. if mem pool transactions are requested we execute them // gas reserved for builder tx - let builder_txs = - match builder_tx.add_builder_txs(&state_provider, &mut info, ctx, db, true) { - Ok(builder_txs) => builder_txs, - Err(e) => { - error!(target: "payload_builder", "Error adding builder txs to block: {}", e); - vec![] - } - }; + let builder_txs = builder_tx + .add_builder_txs(&state_provider, &mut info, ctx, db, true, false, false) + .inspect_err( + |e| error!(target: "payload_builder", "Error adding builder txs to block: {}", e), + ) + .unwrap_or_default(); let builder_tx_gas = builder_txs.iter().fold(0, |acc, tx| acc + tx.gas_used); @@ -425,6 +422,7 @@ impl OpBuilder<'_, Txs> { block_gas_limit, block_da_limit, block_da_footprint, + None, )? .is_some() { @@ -433,7 +431,9 @@ impl OpBuilder<'_, Txs> { } // Add builder tx to the block - if let Err(e) = builder_tx.add_builder_txs(&state_provider, &mut info, ctx, db, false) { + if let Err(e) = + builder_tx.add_builder_txs(&state_provider, &mut info, ctx, db, false, false, false) + { error!(target: "payload_builder", "Error adding builder txs to fallback block: {}", e); }; diff --git a/crates/op-rbuilder/src/flashtestations/builder_tx.rs b/crates/op-rbuilder/src/flashtestations/builder_tx.rs index 7651b846e..07e216f97 100644 --- a/crates/op-rbuilder/src/flashtestations/builder_tx.rs +++ b/crates/op-rbuilder/src/flashtestations/builder_tx.rs @@ -42,11 +42,7 @@ pub struct FlashtestationsBuilderTxArgs { } #[derive(Debug, Clone)] -pub struct FlashtestationsBuilderTx -where - ExtraCtx: Debug + Default, - Extra: Debug + Default, -{ +pub struct FlashtestationsBuilderTx { // Attestation for the builder attestation: Vec, // Extra registration data for the builder @@ -65,15 +61,9 @@ where enable_block_proofs: bool, // Builder key for the flashtestation permit tx builder_signer: Signer, - // Extra context and data - _marker: std::marker::PhantomData<(ExtraCtx, Extra)>, } -impl FlashtestationsBuilderTx -where - ExtraCtx: Debug + Default, - Extra: Debug + Default, -{ +impl FlashtestationsBuilderTx { pub fn new(args: FlashtestationsBuilderTxArgs) -> Self { Self { attestation: args.attestation, @@ -85,7 +75,6 @@ where registered: Arc::new(AtomicBool::new(args.registered)), enable_block_proofs: args.enable_block_proofs, builder_signer: args.builder_key, - _marker: std::marker::PhantomData, } } @@ -128,7 +117,7 @@ where fn set_registered( &self, state_provider: impl StateProvider + Clone, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, ) -> Result<(), BuilderTransactionError> { let state = StateProviderDatabase::new(state_provider.clone()); let mut simulation_state = State::builder() @@ -157,7 +146,7 @@ where fn get_permit_nonce( &self, contract_address: Address, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result { let calldata = IERC20Permit::noncesCall { @@ -171,7 +160,7 @@ where fn registration_permit_signature( &self, permit_nonce: U256, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result { let struct_hash_calldata = IFlashtestationRegistry::computeStructHashCall { @@ -200,7 +189,7 @@ where fn signed_registration_permit_tx( &self, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm<&mut State, NoOpInspector, PrecompilesMap>, ) -> Result { let permit_nonce = self.get_permit_nonce(self.registry_address, ctx, evm)?; @@ -247,7 +236,7 @@ where &self, permit_nonce: U256, block_content_hash: B256, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result { let struct_hash_calldata = IBlockBuilderPolicy::computeStructHashCall { @@ -276,7 +265,7 @@ where fn signed_block_proof_permit_tx( &self, transactions: &[OpTransactionSigned], - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result { let permit_nonce = self.get_permit_nonce(self.builder_policy_address, ctx, evm)?; @@ -323,7 +312,7 @@ where &self, contract_address: Address, calldata: T, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result, BuilderTransactionError> { self.flashtestations_call(contract_address, calldata, vec![], ctx, evm) @@ -334,7 +323,7 @@ where contract_address: Address, calldata: T, expected_topics: Vec, - ctx: &OpPayloadBuilderCtx, + ctx: &OpPayloadBuilderCtx, evm: &mut OpEvm, ) -> Result, BuilderTransactionError> { let tx_req = OpTransactionRequest::default() @@ -364,19 +353,16 @@ where } } -impl BuilderTransactions - for FlashtestationsBuilderTx -where - ExtraCtx: Debug + Default, - Extra: Debug + Default, -{ +impl BuilderTransactions for FlashtestationsBuilderTx { fn simulate_builder_txs( &self, state_provider: impl StateProvider + Clone, - info: &mut ExecutionInfo, - ctx: &OpPayloadBuilderCtx, + info: &mut ExecutionInfo, + ctx: &OpPayloadBuilderCtx, db: &mut State, _top_of_block: bool, + _is_first_flashblock: bool, + _is_last_flashblock: bool, ) -> Result, BuilderTransactionError> { // set registered by simulating against the committed state if !self.registered.load(std::sync::atomic::Ordering::SeqCst) { diff --git a/crates/op-rbuilder/src/flashtestations/service.rs b/crates/op-rbuilder/src/flashtestations/service.rs index 73896119c..da33730bd 100644 --- a/crates/op-rbuilder/src/flashtestations/service.rs +++ b/crates/op-rbuilder/src/flashtestations/service.rs @@ -17,16 +17,11 @@ use crate::{ metrics::record_tee_metrics, tx_signer::{Signer, generate_key_from_seed, generate_signer}, }; -use std::fmt::Debug; -pub async fn bootstrap_flashtestations( +pub async fn bootstrap_flashtestations( args: FlashtestationsArgs, builder_key: Signer, -) -> eyre::Result> -where - ExtraCtx: Debug + Default, - Extra: Debug + Default, -{ +) -> eyre::Result { let tee_service_signer = load_or_generate_tee_key( &args.flashtestations_key_path, args.debug, diff --git a/crates/op-rbuilder/src/primitives/reth/execution.rs b/crates/op-rbuilder/src/primitives/reth/execution.rs index b557b4b45..0d3155720 100644 --- a/crates/op-rbuilder/src/primitives/reth/execution.rs +++ b/crates/op-rbuilder/src/primitives/reth/execution.rs @@ -27,7 +27,7 @@ pub enum TxnExecutionResult { } #[derive(Default, Debug)] -pub struct ExecutionInfo { +pub struct ExecutionInfo { /// All executed transactions (unrecovered). pub executed_transactions: Vec, /// The recovered senders for the executed transactions. @@ -40,15 +40,13 @@ pub struct ExecutionInfo { pub cumulative_da_bytes_used: u64, /// Tracks fees from executed mempool transactions pub total_fees: U256, - /// Extra execution information that can be attached by individual builders. - pub extra: Extra, /// DA Footprint Scalar for Jovian pub da_footprint_scalar: Option, /// Optional blob fields for payload validation pub optional_blob_fields: Option<(Option, Option)>, } -impl ExecutionInfo { +impl ExecutionInfo { /// Create a new instance with allocated slots. pub fn with_capacity(capacity: usize) -> Self { Self { @@ -58,7 +56,6 @@ impl ExecutionInfo { cumulative_gas_used: 0, cumulative_da_bytes_used: 0, total_fees: U256::ZERO, - extra: Default::default(), da_footprint_scalar: None, optional_blob_fields: None, }