11use alloy_consensus:: { Eip658Value , Transaction , conditional:: BlockConditionalAttributes } ;
2- use alloy_eips:: Typed2718 ;
2+ use alloy_eips:: { Encodable2718 , Typed2718 } ;
33use alloy_evm:: Database ;
44use alloy_op_evm:: block:: receipt_builder:: OpReceiptBuilder ;
55use alloy_primitives:: { BlockHash , Bytes , U256 } ;
@@ -146,12 +146,20 @@ impl<ExtraCtx: Debug + Default> OpPayloadBuilderCtx<ExtraCtx> {
146146
147147 /// Returns the blob fields for the header.
148148 ///
149- /// This will always return `Some(0)` after ecotone.
150- pub fn blob_fields ( & self ) -> ( Option < u64 > , Option < u64 > ) {
151- // OP doesn't support blobs/EIP-4844.
152- // https://specs.optimism.io/protocol/exec-engine.html#ecotone-disable-blob-transactions
153- // Need [Some] or [None] based on hardfork to match block hash.
154- if self . is_ecotone_active ( ) {
149+ /// This will return the culmative DA bytes * scalar after Jovian
150+ /// after Ecotone, this will always return Some(0) as blobs aren't supported
151+ /// pre Ecotone, these fields aren't used.
152+ pub fn blob_fields < Extra : Debug + Default > (
153+ & self ,
154+ info : & ExecutionInfo < Extra > ,
155+ ) -> ( Option < u64 > , Option < u64 > ) {
156+ if self . is_jovian_active ( ) {
157+ let scalar = info
158+ . da_footprint_scalar
159+ . expect ( "Scalar must be defined for Jovian blocks" ) ;
160+ let result = info. cumulative_da_bytes_used * scalar as u64 ;
161+ ( Some ( 0 ) , Some ( result) )
162+ } else if self . is_ecotone_active ( ) {
155163 ( Some ( 0 ) , Some ( 0 ) )
156164 } else {
157165 ( None , None )
@@ -162,7 +170,15 @@ impl<ExtraCtx: Debug + Default> OpPayloadBuilderCtx<ExtraCtx> {
162170 ///
163171 /// After holocene this extracts the extradata from the payload
164172 pub fn extra_data ( & self ) -> Result < Bytes , PayloadBuilderError > {
165- if self . is_holocene_active ( ) {
173+ if self . is_jovian_active ( ) {
174+ self . attributes ( )
175+ . get_jovian_extra_data (
176+ self . chain_spec . base_fee_params_at_timestamp (
177+ self . attributes ( ) . payload_attributes . timestamp ,
178+ ) ,
179+ )
180+ . map_err ( PayloadBuilderError :: other)
181+ } else if self . is_holocene_active ( ) {
166182 self . attributes ( )
167183 . get_holocene_extra_data (
168184 self . chain_spec . base_fee_params_at_timestamp (
@@ -215,6 +231,12 @@ impl<ExtraCtx: Debug + Default> OpPayloadBuilderCtx<ExtraCtx> {
215231 . is_isthmus_active_at_timestamp ( self . attributes ( ) . timestamp ( ) )
216232 }
217233
234+ /// Returns true if isthmus is active for the payload.
235+ pub fn is_jovian_active ( & self ) -> bool {
236+ self . chain_spec
237+ . is_jovian_active_at_timestamp ( self . attributes ( ) . timestamp ( ) )
238+ }
239+
218240 /// Returns the chain id
219241 pub fn chain_id ( & self ) -> u64 {
220242 self . chain_spec . chain_id ( )
@@ -316,13 +338,20 @@ impl<ExtraCtx: Debug + Default> OpPayloadBuilderCtx<ExtraCtx> {
316338 let gas_used = result. gas_used ( ) ;
317339 info. cumulative_gas_used += gas_used;
318340
341+ if !sequencer_tx. is_deposit ( ) {
342+ info. cumulative_da_bytes_used += op_alloy_flz:: tx_estimated_size_fjord_bytes (
343+ sequencer_tx. encoded_2718 ( ) . as_slice ( ) ,
344+ ) ;
345+ }
346+
319347 let ctx = ReceiptBuilderCtx {
320348 tx : sequencer_tx. inner ( ) ,
321349 evm : & evm,
322350 result,
323351 state : & state,
324352 cumulative_gas_used : info. cumulative_gas_used ,
325353 } ;
354+
326355 info. receipts . push ( self . build_receipt ( ctx, depositor_nonce) ) ;
327356
328357 // commit changes
@@ -333,6 +362,16 @@ impl<ExtraCtx: Debug + Default> OpPayloadBuilderCtx<ExtraCtx> {
333362 info. executed_transactions . push ( sequencer_tx. into_inner ( ) ) ;
334363 }
335364
365+ let da_footprint_gas_scalar = self
366+ . chain_spec
367+ . is_jovian_active_at_timestamp ( self . attributes ( ) . timestamp ( ) )
368+ . then ( || {
369+ L1BlockInfo :: fetch_da_footprint_gas_scalar ( evm. db_mut ( ) )
370+ . expect ( "DA footprint should always be available from the database post jovian" )
371+ } ) ;
372+
373+ info. da_footprint_scalar = da_footprint_gas_scalar;
374+
336375 Ok ( info)
337376 }
338377
@@ -355,6 +394,7 @@ impl<ExtraCtx: Debug + Default> OpPayloadBuilderCtx<ExtraCtx> {
355394 let mut num_bundles_reverted = 0 ;
356395 let mut reverted_gas_used = 0 ;
357396 let base_fee = self . base_fee ( ) ;
397+
358398 let tx_da_limit = self . da_config . max_da_tx_size ( ) ;
359399 let mut evm = self . evm_config . evm_with_env ( & mut * db, self . evm_env . clone ( ) ) ;
360400
@@ -422,23 +462,14 @@ impl<ExtraCtx: Debug + Default> OpPayloadBuilderCtx<ExtraCtx> {
422462 }
423463 }
424464
425- let da_footprint_gas_scalar = self
426- . chain_spec
427- . is_jovian_active_at_timestamp ( self . attributes ( ) . timestamp ( ) )
428- . then_some (
429- L1BlockInfo :: fetch_da_footprint_gas_scalar ( evm. db_mut ( ) ) . expect (
430- "DA footprint should always be available from the database post jovian" ,
431- ) ,
432- ) ;
433-
434465 // ensure we still have capacity for this transaction
435466 if let Err ( result) = info. is_tx_over_limits (
436467 tx_da_size,
437468 block_gas_limit,
438469 tx_da_limit,
439470 block_da_limit,
440471 tx. gas_limit ( ) ,
441- da_footprint_gas_scalar ,
472+ info . da_footprint_scalar ,
442473 ) {
443474 // we can't fit this transaction into the block, so we need to mark it as
444475 // invalid which also removes all dependent transaction from
0 commit comments