@@ -251,7 +251,7 @@ func (pool *TxPool) resetState() {
251
251
}
252
252
// Check the queue and move transactions over to the pending if possible
253
253
// or remove those that have become invalid
254
- pool .promoteExecutables (currentState )
254
+ pool .promoteExecutables (currentState , nil )
255
255
}
256
256
257
257
// Stop terminates the transaction pool.
@@ -546,7 +546,8 @@ func (pool *TxPool) Add(tx *types.Transaction) error {
546
546
if err != nil {
547
547
return err
548
548
}
549
- pool .promoteExecutables (state )
549
+ from , _ := types .Sender (pool .signer , tx ) // already validated
550
+ pool .promoteExecutables (state , []common.Address {from })
550
551
}
551
552
return nil
552
553
}
@@ -557,24 +558,26 @@ func (pool *TxPool) AddBatch(txs []*types.Transaction) error {
557
558
defer pool .mu .Unlock ()
558
559
559
560
// Add the batch of transaction, tracking the accepted ones
560
- replaced , added := true , 0
561
+ dirty := make ( map [common. Address ] struct {})
561
562
for _ , tx := range txs {
562
563
if replace , err := pool .add (tx ); err == nil {
563
- added ++
564
564
if ! replace {
565
- replaced = false
565
+ from , _ := types .Sender (pool .signer , tx ) // already validated
566
+ dirty [from ] = struct {}{}
566
567
}
567
568
}
568
569
}
569
570
// Only reprocess the internal state if something was actually added
570
- if added > 0 {
571
- if ! replaced {
572
- state , err := pool .currentState ()
573
- if err != nil {
574
- return err
575
- }
576
- pool .promoteExecutables (state )
571
+ if len (dirty ) > 0 {
572
+ state , err := pool .currentState ()
573
+ if err != nil {
574
+ return err
575
+ }
576
+ addrs := make ([]common.Address , 0 , len (dirty ))
577
+ for addr , _ := range dirty {
578
+ addrs = append (addrs , addr )
577
579
}
580
+ pool .promoteExecutables (state , addrs )
578
581
}
579
582
return nil
580
583
}
@@ -651,12 +654,23 @@ func (pool *TxPool) removeTx(hash common.Hash) {
651
654
// promoteExecutables moves transactions that have become processable from the
652
655
// future queue to the set of pending transactions. During this process, all
653
656
// invalidated transactions (low nonce, low balance) are deleted.
654
- func (pool * TxPool ) promoteExecutables (state * state.StateDB ) {
657
+ func (pool * TxPool ) promoteExecutables (state * state.StateDB , accounts []common. Address ) {
655
658
gaslimit := pool .gasLimit ()
656
659
660
+ // Gather all the accounts potentially needing updates
661
+ if accounts == nil {
662
+ accounts = make ([]common.Address , 0 , len (pool .queue ))
663
+ for addr , _ := range pool .queue {
664
+ accounts = append (accounts , addr )
665
+ }
666
+ }
657
667
// Iterate over all accounts and promote any executable transactions
658
668
queued := uint64 (0 )
659
- for addr , list := range pool .queue {
669
+ for _ , addr := range accounts {
670
+ list := pool .queue [addr ]
671
+ if list == nil {
672
+ continue // Just in case someone calls with a non existing account
673
+ }
660
674
// Drop all transactions that are deemed too old (low nonce)
661
675
for _ , tx := range list .Forward (state .GetNonce (addr )) {
662
676
hash := tx .Hash ()
0 commit comments