@@ -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.
@@ -339,17 +339,6 @@ func (pool *TxPool) Pending() (map[common.Address]types.Transactions, error) {
339
339
pool .mu .Lock ()
340
340
defer pool .mu .Unlock ()
341
341
342
- state , err := pool .currentState ()
343
- if err != nil {
344
- return nil , err
345
- }
346
-
347
- // check queue first
348
- pool .promoteExecutables (state )
349
-
350
- // invalidate any txs
351
- pool .demoteUnexecutables (state )
352
-
353
342
pending := make (map [common.Address ]types.Transactions )
354
343
for addr , list := range pool .pending {
355
344
pending [addr ] = list .Flatten ()
@@ -551,13 +540,14 @@ func (pool *TxPool) Add(tx *types.Transaction) error {
551
540
if err != nil {
552
541
return err
553
542
}
554
- state , err := pool .currentState ()
555
- if err != nil {
556
- return err
557
- }
558
543
// If we added a new transaction, run promotion checks and return
559
544
if ! replace {
560
- pool .promoteExecutables (state )
545
+ state , err := pool .currentState ()
546
+ if err != nil {
547
+ return err
548
+ }
549
+ from , _ := types .Sender (pool .signer , tx ) // already validated
550
+ pool .promoteExecutables (state , []common.Address {from })
561
551
}
562
552
return nil
563
553
}
@@ -568,24 +558,26 @@ func (pool *TxPool) AddBatch(txs []*types.Transaction) error {
568
558
defer pool .mu .Unlock ()
569
559
570
560
// Add the batch of transaction, tracking the accepted ones
571
- replaced , added := true , 0
561
+ dirty := make ( map [common. Address ] struct {})
572
562
for _ , tx := range txs {
573
563
if replace , err := pool .add (tx ); err == nil {
574
- added ++
575
564
if ! replace {
576
- replaced = false
565
+ from , _ := types .Sender (pool .signer , tx ) // already validated
566
+ dirty [from ] = struct {}{}
577
567
}
578
568
}
579
569
}
580
570
// Only reprocess the internal state if something was actually added
581
- if added > 0 {
571
+ if len ( dirty ) > 0 {
582
572
state , err := pool .currentState ()
583
573
if err != nil {
584
574
return err
585
575
}
586
- if ! replaced {
587
- pool .promoteExecutables (state )
576
+ addrs := make ([]common.Address , 0 , len (dirty ))
577
+ for addr , _ := range dirty {
578
+ addrs = append (addrs , addr )
588
579
}
580
+ pool .promoteExecutables (state , addrs )
589
581
}
590
582
return nil
591
583
}
@@ -662,12 +654,23 @@ func (pool *TxPool) removeTx(hash common.Hash) {
662
654
// promoteExecutables moves transactions that have become processable from the
663
655
// future queue to the set of pending transactions. During this process, all
664
656
// invalidated transactions (low nonce, low balance) are deleted.
665
- func (pool * TxPool ) promoteExecutables (state * state.StateDB ) {
657
+ func (pool * TxPool ) promoteExecutables (state * state.StateDB , accounts []common. Address ) {
666
658
gaslimit := pool .gasLimit ()
667
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
+ }
668
667
// Iterate over all accounts and promote any executable transactions
669
668
queued := uint64 (0 )
670
- 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
+ }
671
674
// Drop all transactions that are deemed too old (low nonce)
672
675
for _ , tx := range list .Forward (state .GetNonce (addr )) {
673
676
hash := tx .Hash ()
0 commit comments