diff --git a/crates/op-rbuilder/src/builders/flashblocks/payload.rs b/crates/op-rbuilder/src/builders/flashblocks/payload.rs index b92e35c7..82005158 100644 --- a/crates/op-rbuilder/src/builders/flashblocks/payload.rs +++ b/crates/op-rbuilder/src/builders/flashblocks/payload.rs @@ -16,7 +16,7 @@ use crate::{ traits::{ClientBounds, PoolBounds}, }; use alloy_consensus::{ - BlockBody, EMPTY_OMMER_ROOT_HASH, Header, constants::EMPTY_WITHDRAWALS, proofs, + BlockBody, EMPTY_OMMER_ROOT_HASH, Header, TxReceipt, constants::EMPTY_WITHDRAWALS, proofs, }; use alloy_eips::{Encodable2718, eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE}; use alloy_evm::block::BlockExecutionResult; @@ -40,8 +40,7 @@ use reth_optimism_primitives::{OpReceipt, OpTransactionSigned}; use reth_payload_util::BestPayloadTransactions; use reth_primitives_traits::RecoveredBlock; use reth_provider::{ - ExecutionOutcome, HashedPostStateProvider, ProviderError, StateRootProvider, - StorageRootProvider, + HashedPostStateProvider, ProviderError, StateRootProvider, StorageRootProvider, }; use reth_revm::{ State, database::StateProviderDatabase, db::states::bundle_state::BundleRetention, @@ -923,41 +922,12 @@ where )); } - let execution_outcome = ExecutionOutcome::new( - state.bundle_state.clone(), - vec![info.receipts.clone()], - block_number, - vec![], + let receipts_root = calculate_receipt_root_no_memo_optimism( + &info.receipts, + &ctx.chain_spec, + ctx.attributes().timestamp(), ); - - let receipts_root = execution_outcome - .generic_receipts_root_slow(block_number, |receipts| { - calculate_receipt_root_no_memo_optimism( - receipts, - &ctx.chain_spec, - ctx.attributes().timestamp(), - ) - }) - .ok_or_else(|| { - PayloadBuilderError::Other( - eyre::eyre!( - "receipts and block number not in range, block number {}", - block_number - ) - .into(), - ) - })?; - let logs_bloom = execution_outcome - .block_logs_bloom(block_number) - .ok_or_else(|| { - PayloadBuilderError::Other( - eyre::eyre!( - "logs bloom and block number not in range, block number {}", - block_number - ) - .into(), - ) - })?; + let logs_bloom = alloy_primitives::logs_bloom(info.receipts.iter().flat_map(|r| r.logs())); // TODO: maybe recreate state with bundle in here // calculate the state root @@ -968,7 +938,7 @@ where if calculate_state_root { let state_provider = state.database.as_ref(); - hashed_state = state_provider.hashed_post_state(execution_outcome.state()); + hashed_state = state_provider.hashed_post_state(&state.bundle_state); (state_root, trie_output) = { state .database @@ -1002,7 +972,7 @@ where // withdrawals root field in block header is used for storage root of L2 predeploy // `l2tol1-message-passer` Some( - isthmus::withdrawals_root(execution_outcome.state(), state.database.as_ref()) + isthmus::withdrawals_root(&state.bundle_state, state.database.as_ref()) .map_err(PayloadBuilderError::other)?, ) } else if ctx @@ -1020,9 +990,17 @@ where let (excess_blob_gas, blob_gas_used) = ctx.blob_fields(info); let extra_data = ctx.extra_data()?; - // Create BlockExecutionOutput for BuiltPayloadExecutedBlock + // need to read balances before take_bundle() below + let new_account_balances = state + .bundle_state + .state + .iter() + .filter_map(|(address, account)| account.info.as_ref().map(|info| (*address, info.balance))) + .collect::>(); + + let bundle_state = state.take_bundle(); let execution_output = BlockExecutionOutput { - state: state.bundle_state.clone(), + state: bundle_state, result: BlockExecutionResult { receipts: info.receipts.clone(), requests: Default::default(), @@ -1095,8 +1073,7 @@ where let new_transactions = info.executed_transactions[info.extra.last_flashblock_index..].to_vec(); let new_transactions_encoded = new_transactions - .clone() - .into_iter() + .iter() .map(|tx| tx.encoded_2718().into()) .collect::>(); @@ -1107,13 +1084,6 @@ where .zip(new_receipts.iter()) .map(|(tx, receipt)| (tx.tx_hash(), convert_receipt(receipt))) .collect::>(); - let new_account_balances = state - .bundle_state - .state - .iter() - .filter_map(|(address, account)| account.info.as_ref().map(|info| (*address, info.balance))) - .collect::>(); - let metadata = OpFlashblockPayloadMetadata { receipts: receipts_with_hash, new_account_balances, @@ -1158,9 +1128,7 @@ where }, metadata, }; - - // We clean bundle and place initial state transaction back - state.take_bundle(); + // Need to ensure `state.bundle = None`, was done previously with `state.take_bundle()` state.transition_state = untouched_transition_state; Ok(( diff --git a/crates/op-rbuilder/src/builders/standard/payload.rs b/crates/op-rbuilder/src/builders/standard/payload.rs index 6c4ff4c4..0fe399a2 100644 --- a/crates/op-rbuilder/src/builders/standard/payload.rs +++ b/crates/op-rbuilder/src/builders/standard/payload.rs @@ -7,7 +7,7 @@ use crate::{ traits::{ClientBounds, PayloadTxsBounds, PoolBounds}, }; use alloy_consensus::{ - BlockBody, EMPTY_OMMER_ROOT_HASH, Header, constants::EMPTY_WITHDRAWALS, proofs, + BlockBody, EMPTY_OMMER_ROOT_HASH, Header, TxReceipt, constants::EMPTY_WITHDRAWALS, proofs, }; use alloy_eips::{eip7685::EMPTY_REQUESTS_HASH, merge::BEACON_NONCE}; use alloy_evm::{Database, block::BlockExecutionResult}; @@ -26,7 +26,7 @@ use reth_payload_primitives::BuiltPayloadExecutedBlock; use reth_payload_util::{BestPayloadTransactions, NoopPayloadTransactions, PayloadTransactions}; use reth_primitives::RecoveredBlock; use reth_primitives_traits::InMemorySize; -use reth_provider::{ExecutionOutcome, StateProvider}; +use reth_provider::StateProvider; use reth_revm::{ State, database::StateProviderDatabase, db::states::bundle_state::BundleRetention, }; @@ -478,45 +478,24 @@ impl OpBuilder<'_, Txs> { } }; - let block_number = ctx.block_number(); // OP doesn't support blobs/EIP-4844. // https://specs.optimism.io/protocol/exec-engine.html#ecotone-disable-blob-transactions // Need [Some] or [None] based on hardfork to match block hash. let (excess_blob_gas, blob_gas_used) = ctx.blob_fields(&info); let bundle_state = db.take_bundle(); - let execution_outcome = ExecutionOutcome::new( - bundle_state.clone(), - vec![info.receipts.clone()], - block_number, - Vec::new(), + + let receipts_root = calculate_receipt_root_no_memo_optimism( + &info.receipts, + &ctx.chain_spec, + ctx.attributes().timestamp(), ); - let execution_output = BlockExecutionOutput { - state: bundle_state, - result: BlockExecutionResult { - receipts: info.receipts, - requests: Default::default(), - gas_used: info.cumulative_gas_used, - blob_gas_used: blob_gas_used.unwrap_or_default(), - }, - }; - let receipts_root = execution_outcome - .generic_receipts_root_slow(block_number, |receipts| { - calculate_receipt_root_no_memo_optimism( - receipts, - &ctx.chain_spec, - ctx.attributes().timestamp(), - ) - }) - .expect("Number is in range"); - let logs_bloom = execution_outcome - .block_logs_bloom(block_number) - .expect("Number is in range"); + let logs_bloom = alloy_primitives::logs_bloom(info.receipts.iter().flat_map(|r| r.logs())); // calculate the state root let state_root_start_time = Instant::now(); - let hashed_state = state_provider.hashed_post_state(execution_outcome.state()); + let hashed_state = state_provider.hashed_post_state(&bundle_state); let (state_root, trie_output) = { state_provider .state_root_with_updates(hashed_state.clone()) @@ -542,7 +521,7 @@ impl OpBuilder<'_, Txs> { // `l2tol1-message-passer` ( Some( - isthmus::withdrawals_root(execution_outcome.state(), state_provider) + isthmus::withdrawals_root(&bundle_state, state_provider) .map_err(PayloadBuilderError::other)?, ), Some(EMPTY_REQUESTS_HASH), @@ -553,6 +532,16 @@ impl OpBuilder<'_, Txs> { (None, None) }; + let execution_output = BlockExecutionOutput { + state: bundle_state, + result: BlockExecutionResult { + receipts: info.receipts, + requests: Default::default(), + gas_used: info.cumulative_gas_used, + blob_gas_used: blob_gas_used.unwrap_or_default(), + }, + }; + // create the block header let transactions_root = proofs::calculate_transaction_root(&info.executed_transactions);