@@ -367,27 +367,39 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
367367 // stage, as we already have an access to all of the accounts
368368 let mut balances = AccountsBalances :: default ( ) ;
369369
370+ let mut replenish_retried = false ;
370371 let ( mut program_cache_for_tx_batch, program_cache_us) = measure_us ! ( {
371- let program_cache_for_tx_batch = self . replenish_program_cache(
372- callbacks,
373- & program_accounts_map,
374- & mut execute_timings,
375- config. check_program_modification_slot,
376- config. limit_to_load_programs,
377- ) ;
372+ loop {
373+ let program_cache_for_tx_batch = self . replenish_program_cache(
374+ callbacks,
375+ & program_accounts_map,
376+ & mut execute_timings,
377+ config. check_program_modification_slot,
378+ config. limit_to_load_programs,
379+ ) ;
378380
379- if program_cache_for_tx_batch. hit_max_limit {
380- return LoadAndExecuteSanitizedTransactionsOutput {
381- error_metrics,
382- execute_timings,
383- processing_results: ( 0 ..sanitized_txs. len( ) )
384- . map( |_| Err ( TransactionError :: ProgramCacheHitMaxLimit ) )
385- . collect( ) ,
386- balances,
387- } ;
388- }
381+ if program_cache_for_tx_batch. hit_max_limit {
382+ if !replenish_retried {
383+ replenish_retried = true ;
384+ self . program_cache
385+ . write( )
386+ . unwrap( )
387+ . prune_by_deployment_slot( self . slot) ;
388+ continue ;
389+ }
389390
390- program_cache_for_tx_batch
391+ return LoadAndExecuteSanitizedTransactionsOutput {
392+ error_metrics,
393+ execute_timings,
394+ processing_results: ( 0 ..sanitized_txs. len( ) )
395+ . map( |_| Err ( TransactionError :: ProgramCacheHitMaxLimit ) )
396+ . collect( ) ,
397+ balances,
398+ } ;
399+ }
400+
401+ break program_cache_for_tx_batch;
402+ }
391403 } ) ;
392404
393405 // Determine a capacity for the internal account cache. This
0 commit comments