@@ -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 ,
@@ -106,6 +106,17 @@ pub trait ChangedAccountsHook: Send + Sync + 'static {
106106 /// load native balance/nonce, so implementations always see a consistent
107107 /// view of the chain.
108108 fn transform ( & self , state : & dyn StateProvider , accounts : & mut Vec < ChangedAccount > ) ;
109+
110+ /// Extends the dirty set with queued senders whose executability may have
111+ /// changed due to off-account state updates in the canonical update.
112+ fn extend_reload_queued_senders < R > (
113+ & self ,
114+ _queued_senders : & HashSet < Address > ,
115+ _old : Option < & ExecutionOutcome < R > > ,
116+ _new : & ExecutionOutcome < R > ,
117+ _dirty_addresses : & mut HashSet < Address > ,
118+ ) {
119+ }
109120}
110121
111122/// No-op implementation for chains that don't need balance augmentation.
@@ -391,8 +402,8 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
391402 let old_first = old_blocks. first ( ) ;
392403
393404 // check if the reorg is not canonical with the pool's block
394- if !( old_first. parent_hash ( ) == pool_info. last_seen_block_hash ||
395- new_first. parent_hash ( ) == pool_info. last_seen_block_hash )
405+ if !( old_first. parent_hash ( ) == pool_info. last_seen_block_hash
406+ || new_first. parent_hash ( ) == pool_info. last_seen_block_hash )
396407 {
397408 // the new block points to a higher block than the oldest block in the old chain
398409 maintained_state = MaintainedPoolState :: Drifted ;
@@ -446,7 +457,6 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
446457 if let Ok ( state) = client. history_by_block_hash ( new_tip. hash ( ) ) {
447458 hook. transform ( & * state, & mut changed_accounts) ;
448459 }
449-
450460 // all transactions mined in the new chain
451461 let new_mined_transactions: HashSet < _ > = new_blocks. transaction_hashes ( ) . collect ( ) ;
452462
@@ -498,6 +508,14 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
498508 metrics. inc_reinserted_transactions ( pruned_old_transactions. len ( ) ) ;
499509 let _ = pool. add_external_transactions ( pruned_old_transactions) . await ;
500510
511+ let queued_senders = queued_senders ( & pool) ;
512+ hook. extend_reload_queued_senders (
513+ & queued_senders,
514+ Some ( old_state) ,
515+ new_state,
516+ & mut dirty_addresses,
517+ ) ;
518+
501519 // keep track of new mined blob transactions
502520 blob_store_tracker. add_new_chain_blocks ( & new_blocks) ;
503521 }
@@ -541,7 +559,7 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
541559 // keep track of mined blob transactions
542560 blob_store_tracker. add_new_chain_blocks ( & blocks) ;
543561
544- continue
562+ continue ;
545563 }
546564
547565 let mut changed_accounts = Vec :: with_capacity ( state. state ( ) . len ( ) ) ;
@@ -553,7 +571,6 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
553571 if let Ok ( tip_state) = client. history_by_block_hash ( tip. hash ( ) ) {
554572 hook. transform ( & * tip_state, & mut changed_accounts) ;
555573 }
556-
557574 let mined_transactions = blocks. transaction_hashes ( ) . collect ( ) ;
558575
559576 // check if the range of the commit is canonical with the pool's block
@@ -575,6 +592,14 @@ pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>(
575592 } ;
576593 pool. on_canonical_state_change ( update) ;
577594
595+ let queued_senders = queued_senders ( & pool) ;
596+ hook. extend_reload_queued_senders (
597+ & queued_senders,
598+ None ,
599+ state,
600+ & mut dirty_addresses,
601+ ) ;
602+
578603 // keep track of mined blob transactions
579604 blob_store_tracker. add_new_chain_blocks ( & blocks) ;
580605 }
@@ -683,6 +708,10 @@ where
683708 Ok ( res)
684709}
685710
711+ fn queued_senders < P : TransactionPool > ( pool : & P ) -> HashSet < Address > {
712+ pool. queued_transactions ( ) . into_iter ( ) . map ( |tx| tx. sender ( ) ) . collect ( )
713+ }
714+
686715/// Loads transactions from a file, decodes them from the JSON or RLP format, and
687716/// inserts them into the transaction pool on node boot up.
688717/// The file is removed after the transactions have been successfully processed.
@@ -694,14 +723,14 @@ where
694723 P : TransactionPool < Transaction : PoolTransaction < Consensus : SignedTransaction > > ,
695724{
696725 if !file_path. exists ( ) {
697- return Ok ( ( ) )
726+ return Ok ( ( ) ) ;
698727 }
699728
700729 debug ! ( target: "txpool" , txs_file =?file_path, "Check local persistent storage for saved transactions" ) ;
701730 let data = reth_fs_util:: read ( file_path) ?;
702731
703732 if data. is_empty ( ) {
704- return Ok ( ( ) )
733+ return Ok ( ( ) ) ;
705734 }
706735
707736 let pool_transactions: Vec < ( TransactionOrigin , <P as TransactionPool >:: Transaction ) > =
@@ -752,7 +781,7 @@ where
752781 let local_transactions = pool. get_local_transactions ( ) ;
753782 if local_transactions. is_empty ( ) {
754783 trace ! ( target: "txpool" , "no local transactions to save" ) ;
755- return
784+ return ;
756785 }
757786
758787 let local_transactions = local_transactions
@@ -769,7 +798,7 @@ where
769798 Ok ( data) => data,
770799 Err ( err) => {
771800 warn ! ( target: "txpool" , %err, txs_file=?file_path, "failed to serialize local transactions to json" ) ;
772- return
801+ return ;
773802 }
774803 } ;
775804
@@ -824,7 +853,7 @@ pub async fn backup_local_transactions_task<P>(
824853{
825854 let Some ( transactions_path) = config. transactions_path else {
826855 // nothing to do
827- return
856+ return ;
828857 } ;
829858
830859 if let Err ( err) = load_and_reinsert_transactions ( pool. clone ( ) , & transactions_path) . await {
0 commit comments