11//! Scroll's payload builder implementation.
22
33use super :: { PayloadBuildingBaseFeeProvider , ScrollPayloadBuilderError } ;
4- use crate :: config:: ScrollBuilderConfig ;
4+ use crate :: config:: { PayloadBuildingBreaker , ScrollBuilderConfig } ;
55
66use alloy_consensus:: { Transaction , Typed2718 } ;
77use alloy_primitives:: { B256 , U256 } ;
@@ -57,7 +57,7 @@ impl<T: PoolTransaction> ScrollPayloadTransactions<T> for () {
5757}
5858
5959/// Scroll's payload builder.
60- #[ derive( Debug , Clone ) ]
60+ #[ derive( Clone , Debug ) ]
6161pub struct ScrollPayloadBuilder < Pool , Client , Evm , Txs = ( ) > {
6262 /// The type responsible for creating the evm.
6363 pub evm_config : Evm ,
@@ -134,15 +134,10 @@ where
134134 let state = StateProviderDatabase :: new ( & state_provider) ;
135135
136136 if ctx. attributes ( ) . no_tx_pool {
137- builder. build ( state, & state_provider, ctx, self . builder_config . clone ( ) )
137+ builder. build ( state, & state_provider, ctx, & self . builder_config )
138138 } else {
139139 // sequencer mode we can reuse cachedreads from previous runs
140- builder. build (
141- cached_reads. as_db_mut ( state) ,
142- & state_provider,
143- ctx,
144- self . builder_config . clone ( ) ,
145- )
140+ builder. build ( cached_reads. as_db_mut ( state) , & state_provider, ctx, & self . builder_config )
146141 }
147142 . map ( |out| out. with_cached_reads ( cached_reads) )
148143 }
@@ -222,7 +217,7 @@ impl<Txs> ScrollBuilder<'_, Txs> {
222217 db : impl Database < Error = ProviderError > ,
223218 state_provider : impl StateProvider ,
224219 ctx : ScrollPayloadBuilderCtx < EvmConfig , ChainSpec > ,
225- builder_config : ScrollBuilderConfig ,
220+ builder_config : & ScrollBuilderConfig ,
226221 ) -> Result < BuildOutcomeKind < ScrollBuiltPayload > , PayloadBuilderError >
227222 where
228223 EvmConfig : ConfigureEvm <
@@ -234,6 +229,7 @@ impl<Txs> ScrollBuilder<'_, Txs> {
234229 {
235230 let Self { best } = self ;
236231 tracing:: debug!( target: "payload_builder" , id=%ctx. payload_id( ) , parent_header = ?ctx. parent( ) . hash( ) , parent_number = ctx. parent( ) . number, "building new payload" ) ;
232+ let breaker = builder_config. breaker ( ) ;
237233
238234 let mut db = State :: builder ( ) . with_database ( db) . with_bundle_update ( ) . build ( ) ;
239235
@@ -251,8 +247,9 @@ impl<Txs> ScrollBuilder<'_, Txs> {
251247 // 3. if mem pool transactions are requested we execute them
252248 if !ctx. attributes ( ) . no_tx_pool {
253249 let best_txs = best ( ctx. best_transaction_attributes ( builder. evm_mut ( ) . block ( ) ) ) ;
254- if ctx. execute_best_transactions ( & mut info, & mut builder, best_txs) ?. is_some ( ) {
255- return Ok ( BuildOutcomeKind :: Cancelled )
250+ if ctx. execute_best_transactions ( & mut info, & mut builder, best_txs, breaker) ?. is_some ( )
251+ {
252+ return Ok ( BuildOutcomeKind :: Cancelled ) ;
256253 }
257254
258255 // check if the new payload is even more valuable
@@ -371,7 +368,7 @@ where
371368 pub fn block_builder < ' a , DB : Database > (
372369 & ' a self ,
373370 db : & ' a mut State < DB > ,
374- builder_config : ScrollBuilderConfig ,
371+ builder_config : & ScrollBuilderConfig ,
375372 ) -> Result < impl BlockBuilder < Primitives = Evm :: Primitives > + ' a , PayloadBuilderError > {
376373 // get the base fee for the attributes.
377374 let base_fee: u64 = if self . chain_spec . is_curie_active_at_block ( self . parent ( ) . number + 1 ) {
@@ -390,7 +387,7 @@ where
390387 ScrollNextBlockEnvAttributes {
391388 timestamp : self . attributes ( ) . timestamp ( ) ,
392389 suggested_fee_recipient : self . attributes ( ) . suggested_fee_recipient ( ) ,
393- gas_limit : builder_config. desired_gas_limit ,
390+ gas_limit : builder_config. gas_limit ,
394391 base_fee,
395392 } ,
396393 )
@@ -459,6 +456,7 @@ where
459456 mut best_txs : impl PayloadTransactions <
460457 Transaction : PoolTransaction < Consensus = TxTy < Evm :: Primitives > > ,
461458 > ,
459+ breaker : PayloadBuildingBreaker ,
462460 ) -> Result < Option < ( ) > , PayloadBuilderError > {
463461 let block_gas_limit = builder. evm_mut ( ) . block ( ) . gas_limit ;
464462 let base_fee = builder. evm_mut ( ) . block ( ) . basefee ;
@@ -484,6 +482,12 @@ where
484482 return Ok ( Some ( ( ) ) )
485483 }
486484
485+ // check if the execution needs to be halted.
486+ if breaker. should_break ( info. cumulative_gas_used ) {
487+ tracing:: trace!( target: "scroll::payload_builder" , ?info, "breaking execution loop" ) ;
488+ return Ok ( None ) ;
489+ }
490+
487491 let gas_used = match builder. execute_transaction ( tx. clone ( ) ) {
488492 Ok ( gas_used) => gas_used,
489493 Err ( BlockExecutionError :: Validation ( BlockValidationError :: InvalidTx {
0 commit comments