@@ -810,11 +810,18 @@ where
810810 }
811811 }
812812
813- fn build_candidate <
813+ /// Takes the current best flashblock candidate, execute new transaction and build a new candidate only if it's better
814+ #[ expect( clippy:: too_many_arguments) ]
815+ fn refresh_best_flashblock_candidate <
814816 DB : Database < Error = ProviderError > + std:: fmt:: Debug + AsRef < P > ,
815817 P : StateRootProvider + HashedPostStateProvider + StorageRootProvider ,
816818 > (
817819 & self ,
820+ best : Option < (
821+ OpBuiltPayload ,
822+ FlashblocksPayloadV1 ,
823+ ExecutionInfo < FlashblocksExecutionInfo > ,
824+ ) > ,
818825 ctx : & OpPayloadBuilderCtx < FlashblocksExtraCtx > ,
819826 state : & mut State < DB > ,
820827 state_provider : impl reth:: providers:: StateProvider + Clone ,
@@ -859,20 +866,32 @@ where
859866 error ! ( target: "payload_builder" , "Error simulating builder txs: {}" , e) ;
860867 } ;
861868
862- // build block
863- let build_result = build_block (
869+ // Check if we can build a better block by comparing execution results
870+ let is_better_candidate = |prev : & ExecutionInfo < _ > , new : & ExecutionInfo < _ > | {
871+ new. cumulative_gas_used > prev. cumulative_gas_used
872+ } ;
873+ if best
874+ . as_ref ( )
875+ . is_some_and ( |( _, _, prev) | !is_better_candidate ( prev, & batch_info) )
876+ {
877+ // Not better, nothing to refresh so we can return early
878+ return Ok ( best. expect ( "safe: best matched Some" ) ) ;
879+ }
880+
881+ // build block and return new best
882+ build_block (
864883 state, // todo
865884 ctx,
866885 & mut batch_info,
867886 ctx. extra_ctx . calculate_state_root || ctx. attributes ( ) . no_tx_pool ,
868- ) ;
869- build_result
870- . map ( | ( payload , mut fb ) | {
871- fb. index = ctx . flashblock_index ( ) ;
872- fb . base = None ;
873- ( payload, fb, batch_info)
874- } )
875- . wrap_err ( "failed to build payload" )
887+ )
888+ . map ( | ( payload , mut fb ) | {
889+ fb . index = ctx . flashblock_index ( ) ;
890+ fb. base = None ;
891+
892+ ( payload, fb, batch_info)
893+ } )
894+ . wrap_err ( "failed to build payload" )
876895 }
877896
878897 #[ expect( clippy:: too_many_arguments) ]
@@ -933,26 +952,15 @@ where
933952
934953 // Build one candidate (blocking here)
935954 // todo: would be best to build async and select on candidate_build/block_cancel/fb_cancel
936- match self . build_candidate (
955+ best = Some ( self . refresh_best_flashblock_candidate (
956+ best,
937957 & * ctx,
938958 state,
939959 & state_provider,
940960 best_txs,
941961 target_gas_for_batch,
942962 target_da_for_batch,
943- ) {
944- Ok ( candidate) => {
945- if best
946- . as_ref ( )
947- . is_none_or ( |b| candidate. 1 . diff . gas_used > b. 1 . diff . gas_used )
948- {
949- best = Some ( candidate) ;
950- }
951- }
952- Err ( _) => {
953- ctx. metrics . invalid_blocks_count . increment ( 1 ) ;
954- }
955- }
963+ ) ?) ;
956964 }
957965
958966 // 3. --- Cancellation token received, send best ---
0 commit comments