@@ -85,20 +85,30 @@ pub struct FlashblocksExtraCtx {
8585 target_gas_for_batch : u64 ,
8686 /// Total DA bytes left for the current flashblock
8787 target_da_for_batch : Option < u64 > ,
88+ /// Total DA footprint left for the current flashblock
89+ target_da_footprint_for_batch : Option < u64 > ,
8890 /// Gas limit per flashblock
8991 gas_per_batch : u64 ,
9092 /// DA bytes limit per flashblock
9193 da_per_batch : Option < u64 > ,
94+ /// DA footprint limit per flashblock
95+ da_footprint_per_batch : Option < u64 > ,
9296 /// Whether to disable state root calculation for each flashblock
9397 disable_state_root : bool ,
9498}
9599
96100impl FlashblocksExtraCtx {
97- fn next ( self , target_gas_for_batch : u64 , target_da_for_batch : Option < u64 > ) -> Self {
101+ fn next (
102+ self ,
103+ target_gas_for_batch : u64 ,
104+ target_da_for_batch : Option < u64 > ,
105+ target_da_footprint_for_batch : Option < u64 > ,
106+ ) -> Self {
98107 Self {
99108 flashblock_index : self . flashblock_index + 1 ,
100109 target_gas_for_batch,
101110 target_da_for_batch,
111+ target_da_footprint_for_batch,
102112 ..self
103113 }
104114 }
@@ -344,28 +354,18 @@ where
344354 ctx. metrics . sequencer_tx_gauge . set ( sequencer_tx_time) ;
345355
346356 // We add first builder tx right after deposits
347- let builder_txs = if ctx. attributes ( ) . no_tx_pool {
348- vec ! [ ]
349- } else {
350- match self . builder_tx . add_builder_txs (
351- & state_provider,
352- & mut info,
353- & ctx,
354- & mut state,
355- false ,
356- ) {
357- Ok ( builder_txs) => builder_txs,
358- Err ( e) => {
359- error ! ( target: "payload_builder" , "Error adding builder txs to fallback block: {}" , e) ;
360- vec ! [ ]
361- }
362- }
357+ if !ctx. attributes ( ) . no_tx_pool
358+ && let Err ( e) =
359+ self . builder_tx
360+ . add_builder_txs ( & state_provider, & mut info, & ctx, & mut state, false )
361+ {
362+ error ! (
363+ target: "payload_builder" ,
364+ "Error adding builder txs to fallback block: {}" ,
365+ e
366+ ) ;
363367 } ;
364368
365- // We subtract gas limit and da limit for builder transaction from the whole limit
366- let builder_tx_gas = builder_txs. iter ( ) . fold ( 0 , |acc, tx| acc + tx. gas_used ) ;
367- let builder_tx_da_size: u64 = builder_txs. iter ( ) . fold ( 0 , |acc, tx| acc + tx. da_size ) ;
368-
369369 let ( payload, fb_payload) = build_block (
370370 & mut state,
371371 & ctx,
@@ -438,34 +438,33 @@ where
438438 . first_flashblock_time_offset
439439 . record ( first_flashblock_offset. as_millis ( ) as f64 ) ;
440440 let gas_per_batch = ctx. block_gas_limit ( ) / flashblocks_per_block;
441- let target_gas_for_batch = gas_per_batch;
442441 let da_per_batch = ctx
443442 . da_config
444443 . max_da_block_size ( )
445444 . map ( |da_limit| da_limit / flashblocks_per_block) ;
446445 // Check that builder tx won't affect fb limit too much
447446 if let Some ( da_limit) = da_per_batch {
448447 // We error if we can't insert any tx aside from builder tx in flashblock
449- if da_limit / 2 < builder_tx_da_size {
448+ if info . cumulative_da_bytes_used >= da_limit {
450449 error ! (
451450 "Builder tx da size subtraction caused max_da_block_size to be 0. No transaction would be included."
452451 ) ;
453452 }
454453 }
455- let mut target_da_for_batch = da_per_batch;
454+ let da_footprint_per_batch = info
455+ . da_footprint_scalar
456+ . map ( |_| ctx. block_gas_limit ( ) / flashblocks_per_block) ;
456457
457- // Account for already included builder tx
458- if let Some ( da_limit) = target_da_for_batch. as_mut ( ) {
459- * da_limit = da_limit. saturating_sub ( builder_tx_da_size) ;
460- }
461458 let extra_ctx = FlashblocksExtraCtx {
462459 flashblock_index : 1 ,
463460 target_flashblock_count : flashblocks_per_block,
464- target_gas_for_batch : target_gas_for_batch . saturating_sub ( builder_tx_gas ) ,
465- target_da_for_batch,
461+ target_gas_for_batch : gas_per_batch ,
462+ target_da_for_batch : da_per_batch ,
466463 gas_per_batch,
467464 da_per_batch,
465+ da_footprint_per_batch,
468466 disable_state_root,
467+ target_da_footprint_for_batch : da_footprint_per_batch,
469468 } ;
470469
471470 let mut fb_cancel = block_cancel. child_token ( ) ;
@@ -613,6 +612,7 @@ where
613612 let flashblock_index = ctx. flashblock_index ( ) ;
614613 let mut target_gas_for_batch = ctx. extra_ctx . target_gas_for_batch ;
615614 let mut target_da_for_batch = ctx. extra_ctx . target_da_for_batch ;
615+ let mut target_da_footprint_for_batch = ctx. extra_ctx . target_da_footprint_for_batch ;
616616
617617 info ! (
618618 target: "payload_builder" ,
@@ -623,6 +623,7 @@ where
623623 target_da = target_da_for_batch,
624624 da_used = info. cumulative_da_bytes_used,
625625 block_gas_used = ctx. block_gas_limit( ) ,
626+ target_da_footprint = target_da_footprint_for_batch,
626627 "Building flashblock" ,
627628 ) ;
628629 let flashblock_build_start_time = Instant :: now ( ) ;
@@ -639,15 +640,30 @@ where
639640 }
640641 } ;
641642
642- let builder_tx_gas = builder_txs. iter ( ) . fold ( 0 , |acc, tx| acc + tx. gas_used ) ;
643- let builder_tx_da_size: u64 = builder_txs. iter ( ) . fold ( 0 , |acc, tx| acc + tx. da_size ) ;
643+ // only reserve builder tx gas / da size that has not been committed yet
644+ // committed builder txs would have counted towards the gas / da used
645+ let builder_tx_gas = builder_txs
646+ . iter ( )
647+ . filter ( |tx| !tx. is_top_of_block )
648+ . fold ( 0 , |acc, tx| acc + tx. gas_used ) ;
649+ let builder_tx_da_size: u64 = builder_txs
650+ . iter ( )
651+ . filter ( |tx| !tx. is_top_of_block )
652+ . fold ( 0 , |acc, tx| acc + tx. da_size ) ;
644653 target_gas_for_batch = target_gas_for_batch. saturating_sub ( builder_tx_gas) ;
645654
646655 // saturating sub just in case, we will log an error if da_limit too small for builder_tx_da_size
647656 if let Some ( da_limit) = target_da_for_batch. as_mut ( ) {
648657 * da_limit = da_limit. saturating_sub ( builder_tx_da_size) ;
649658 }
650659
660+ if let ( Some ( footprint) , Some ( scalar) ) = (
661+ target_da_footprint_for_batch. as_mut ( ) ,
662+ info. da_footprint_scalar ,
663+ ) {
664+ * footprint = footprint. saturating_sub ( builder_tx_da_size. saturating_mul ( scalar as u64 ) ) ;
665+ }
666+
651667 let best_txs_start_time = Instant :: now ( ) ;
652668 best_txs. refresh_iterator (
653669 BestPayloadTransactions :: new (
@@ -671,6 +687,7 @@ where
671687 best_txs,
672688 target_gas_for_batch. min ( ctx. block_gas_limit ( ) ) ,
673689 target_da_for_batch,
690+ target_da_footprint_for_batch,
674691 )
675692 . wrap_err ( "failed to execute best transactions" ) ?;
676693 // Extract last transactions
@@ -779,10 +796,19 @@ where
779796
780797 let target_gas_for_batch =
781798 ctx. extra_ctx . target_gas_for_batch + ctx. extra_ctx . gas_per_batch ;
782- let next_extra_ctx = ctx
783- . extra_ctx
784- . clone ( )
785- . next ( target_gas_for_batch, target_da_for_batch) ;
799+
800+ if let ( Some ( footprint) , Some ( da_footprint_limit) ) = (
801+ target_da_footprint_for_batch. as_mut ( ) ,
802+ ctx. extra_ctx . da_footprint_per_batch ,
803+ ) {
804+ * footprint += da_footprint_limit;
805+ }
806+
807+ let next_extra_ctx = ctx. extra_ctx . clone ( ) . next (
808+ target_gas_for_batch,
809+ target_da_for_batch,
810+ target_da_footprint_for_batch,
811+ ) ;
786812
787813 info ! (
788814 target: "payload_builder" ,
0 commit comments