97
97
queuedNofundsMeter = metrics .NewRegisteredMeter ("txpool/queued/nofunds" , nil ) // Dropped due to out-of-funds
98
98
99
99
// General tx metrics
100
- validMeter = metrics .NewRegisteredMeter ("txpool/valid" , nil )
100
+ knownTxMeter = metrics .NewRegisteredMeter ("txpool/known" , nil )
101
+ validTxMeter = metrics .NewRegisteredMeter ("txpool/valid" , nil )
101
102
invalidTxMeter = metrics .NewRegisteredMeter ("txpool/invalid" , nil )
102
103
underpricedTxMeter = metrics .NewRegisteredMeter ("txpool/underpriced" , nil )
103
104
@@ -564,16 +565,15 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
564
565
hash := tx .Hash ()
565
566
if pool .all .Get (hash ) != nil {
566
567
log .Trace ("Discarding already known transaction" , "hash" , hash )
568
+ knownTxMeter .Mark (1 )
567
569
return false , fmt .Errorf ("known transaction: %x" , hash )
568
570
}
569
-
570
571
// If the transaction fails basic validation, discard it
571
572
if err := pool .validateTx (tx , local ); err != nil {
572
573
log .Trace ("Discarding invalid transaction" , "hash" , hash , "err" , err )
573
574
invalidTxMeter .Mark (1 )
574
575
return false , err
575
576
}
576
-
577
577
// If the transaction pool is full, discard underpriced transactions
578
578
if uint64 (pool .all .Count ()) >= pool .config .GlobalSlots + pool .config .GlobalQueue {
579
579
// If the new transaction is underpriced, don't accept it
@@ -590,7 +590,6 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
590
590
pool .removeTx (tx .Hash (), false )
591
591
}
592
592
}
593
-
594
593
// Try to replace an existing transaction in the pending pool
595
594
from , _ := types .Sender (pool .signer , tx ) // already validated
596
595
if list := pool .pending [from ]; list != nil && list .Overlaps (tx ) {
@@ -613,13 +612,11 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e
613
612
log .Trace ("Pooled new executable transaction" , "hash" , hash , "from" , from , "to" , tx .To ())
614
613
return old != nil , nil
615
614
}
616
-
617
615
// New transaction isn't replacing a pending one, push into queue
618
616
replaced , err = pool .enqueueTx (hash , tx )
619
617
if err != nil {
620
618
return false , err
621
619
}
622
-
623
620
// Mark local addresses and journal local transactions
624
621
if local {
625
622
if ! pool .locals .contains (from ) {
@@ -768,11 +765,18 @@ func (pool *TxPool) AddRemote(tx *types.Transaction) error {
768
765
769
766
// addTxs attempts to queue a batch of transactions if they are valid.
770
767
func (pool * TxPool ) addTxs (txs []* types.Transaction , local , sync bool ) []error {
768
+ // Filter out known ones without obtaining the pool lock or recovering signatures
769
+ for i := 0 ; i < len (txs ); i ++ {
770
+ if pool .all .Get (txs [i ].Hash ()) != nil {
771
+ knownTxMeter .Mark (1 )
772
+ txs = append (txs [:i ], txs [i + 1 :]... )
773
+ i --
774
+ }
775
+ }
771
776
// Cache senders in transactions before obtaining lock (pool.signer is immutable)
772
777
for _ , tx := range txs {
773
778
types .Sender (pool .signer , tx )
774
779
}
775
-
776
780
pool .mu .Lock ()
777
781
errs , dirtyAddrs := pool .addTxsLocked (txs , local )
778
782
pool .mu .Unlock ()
@@ -796,7 +800,7 @@ func (pool *TxPool) addTxsLocked(txs []*types.Transaction, local bool) ([]error,
796
800
dirty .addTx (tx )
797
801
}
798
802
}
799
- validMeter .Mark (int64 (len (dirty .accounts )))
803
+ validTxMeter .Mark (int64 (len (dirty .accounts )))
800
804
return errs , dirty
801
805
}
802
806
0 commit comments