@@ -17,7 +17,7 @@ use futures_util::{
1717} ;
1818use reth_chain_state:: CanonStateNotification ;
1919use reth_chainspec:: { ChainSpecProvider , EthChainSpec } ;
20- use reth_execution_types:: ChangedAccount ;
20+ use reth_execution_types:: { ChangedAccount , ExecutionOutcome } ;
2121use reth_fs_util:: FsPathError ;
2222use reth_primitives_traits:: {
2323 transaction:: signed:: SignedTransaction , NodePrimitives , SealedHeader ,
@@ -100,6 +100,17 @@ pub trait ChangedAccountsHook: Send + Sync + 'static {
100100 /// additional state (e.g. ERC-20 storage) and adjust the `balance` field of
101101 /// each [`ChangedAccount`].
102102 fn transform ( & self , accounts : & mut Vec < ChangedAccount > ) ;
103+
104+ /// Extends the dirty set with queued senders whose executability may have
105+ /// changed due to off-account state updates in the canonical update.
106+ fn extend_reload_queued_senders < R > (
107+ & self ,
108+ _queued_senders : & HashSet < Address > ,
109+ _old : Option < & ExecutionOutcome < R > > ,
110+ _new : & ExecutionOutcome < R > ,
111+ _dirty_addresses : & mut HashSet < Address > ,
112+ ) {
113+ }
103114}
104115
105116/// No-op implementation for chains that don't need balance augmentation.
@@ -383,8 +394,8 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
383394 let old_first = old_blocks. first ( ) ;
384395
385396 // check if the reorg is not canonical with the pool's block
386- if !( old_first. parent_hash ( ) == pool_info. last_seen_block_hash ||
387- new_first. parent_hash ( ) == pool_info. last_seen_block_hash )
397+ if !( old_first. parent_hash ( ) == pool_info. last_seen_block_hash
398+ || new_first. parent_hash ( ) == pool_info. last_seen_block_hash )
388399 {
389400 // the new block points to a higher block than the oldest block in the old chain
390401 maintained_state = MaintainedPoolState :: Drifted ;
@@ -436,7 +447,6 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
436447 // we can use extend here because they are unique
437448 changed_accounts. extend ( new_changed_accounts. into_iter ( ) . map ( |entry| entry. 0 ) ) ;
438449 hook. transform ( & mut changed_accounts) ;
439-
440450 // all transactions mined in the new chain
441451 let new_mined_transactions: HashSet < _ > = new_blocks. transaction_hashes ( ) . collect ( ) ;
442452
@@ -488,6 +498,14 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
488498 metrics. inc_reinserted_transactions ( pruned_old_transactions. len ( ) ) ;
489499 let _ = pool. add_external_transactions ( pruned_old_transactions) . await ;
490500
501+ let queued_senders = queued_senders ( & pool) ;
502+ hook. extend_reload_queued_senders (
503+ & queued_senders,
504+ Some ( old_state) ,
505+ new_state,
506+ & mut dirty_addresses,
507+ ) ;
508+
491509 // keep track of new mined blob transactions
492510 blob_store_tracker. add_new_chain_blocks ( & new_blocks) ;
493511 }
@@ -531,7 +549,7 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
531549 // keep track of mined blob transactions
532550 blob_store_tracker. add_new_chain_blocks ( & blocks) ;
533551
534- continue
552+ continue ;
535553 }
536554
537555 let mut changed_accounts = Vec :: with_capacity ( state. state ( ) . len ( ) ) ;
@@ -541,7 +559,6 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
541559 changed_accounts. push ( acc) ;
542560 }
543561 hook. transform ( & mut changed_accounts) ;
544-
545562 let mined_transactions = blocks. transaction_hashes ( ) . collect ( ) ;
546563
547564 // check if the range of the commit is canonical with the pool's block
@@ -563,6 +580,14 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
563580 } ;
564581 pool. on_canonical_state_change ( update) ;
565582
583+ let queued_senders = queued_senders ( & pool) ;
584+ hook. extend_reload_queued_senders (
585+ & queued_senders,
586+ None ,
587+ state,
588+ & mut dirty_addresses,
589+ ) ;
590+
566591 // keep track of mined blob transactions
567592 blob_store_tracker. add_new_chain_blocks ( & blocks) ;
568593 }
@@ -671,6 +696,10 @@ where
671696 Ok ( res)
672697}
673698
699+ fn queued_senders < P : TransactionPool > ( pool : & P ) -> HashSet < Address > {
700+ pool. queued_transactions ( ) . into_iter ( ) . map ( |tx| tx. sender ( ) ) . collect ( )
701+ }
702+
674703/// Loads transactions from a file, decodes them from the JSON or RLP format, and
675704/// inserts them into the transaction pool on node boot up.
676705/// The file is removed after the transactions have been successfully processed.
@@ -682,14 +711,14 @@ where
682711 P : TransactionPool < Transaction : PoolTransaction < Consensus : SignedTransaction > > ,
683712{
684713 if !file_path. exists ( ) {
685- return Ok ( ( ) )
714+ return Ok ( ( ) ) ;
686715 }
687716
688717 debug ! ( target: "txpool" , txs_file =?file_path, "Check local persistent storage for saved transactions" ) ;
689718 let data = reth_fs_util:: read ( file_path) ?;
690719
691720 if data. is_empty ( ) {
692- return Ok ( ( ) )
721+ return Ok ( ( ) ) ;
693722 }
694723
695724 let pool_transactions: Vec < ( TransactionOrigin , <P as TransactionPool >:: Transaction ) > =
@@ -740,7 +769,7 @@ where
740769 let local_transactions = pool. get_local_transactions ( ) ;
741770 if local_transactions. is_empty ( ) {
742771 trace ! ( target: "txpool" , "no local transactions to save" ) ;
743- return
772+ return ;
744773 }
745774
746775 let local_transactions = local_transactions
@@ -757,7 +786,7 @@ where
757786 Ok ( data) => data,
758787 Err ( err) => {
759788 warn ! ( target: "txpool" , %err, txs_file=?file_path, "failed to serialize local transactions to json" ) ;
760- return
789+ return ;
761790 }
762791 } ;
763792
@@ -812,7 +841,7 @@ pub async fn backup_local_transactions_task<P>(
812841{
813842 let Some ( transactions_path) = config. transactions_path else {
814843 // nothing to do
815- return
844+ return ;
816845 } ;
817846
818847 if let Err ( err) = load_and_reinsert_transactions ( pool. clone ( ) , & transactions_path) . await {
0 commit comments