@@ -618,6 +618,96 @@ func testTransactionLimitingEquivalency(t *testing.T, origin uint64) {
618
618
}
619
619
}
620
620
621
+ // Tests that if the transaction count belonging to multiple accounts go above
622
+ // some hard threshold, the higher transactions are dropped to prevent DOS
623
+ // attacks.
624
+ func TestTransactionPendingGlobalLimiting (t * testing.T ) {
625
+ // Reduce the queue limits to shorten test time
626
+ defer func (old uint64 ) { maxPendingTotal = old }(maxPendingTotal )
627
+ maxPendingTotal = minPendingPerAccount * 10
628
+
629
+ // Create the pool to test the limit enforcement with
630
+ db , _ := ethdb .NewMemDatabase ()
631
+ statedb , _ := state .New (common.Hash {}, db )
632
+
633
+ pool := NewTxPool (testChainConfig (), new (event.TypeMux ), func () (* state.StateDB , error ) { return statedb , nil }, func () * big.Int { return big .NewInt (1000000 ) })
634
+ pool .resetState ()
635
+
636
+ // Create a number of test accounts and fund them
637
+ state , _ := pool .currentState ()
638
+
639
+ keys := make ([]* ecdsa.PrivateKey , 5 )
640
+ for i := 0 ; i < len (keys ); i ++ {
641
+ keys [i ], _ = crypto .GenerateKey ()
642
+ state .AddBalance (crypto .PubkeyToAddress (keys [i ].PublicKey ), big .NewInt (1000000 ))
643
+ }
644
+ // Generate and queue a batch of transactions
645
+ nonces := make (map [common.Address ]uint64 )
646
+
647
+ txs := types.Transactions {}
648
+ for _ , key := range keys {
649
+ addr := crypto .PubkeyToAddress (key .PublicKey )
650
+ for j := 0 ; j < int (maxPendingTotal )/ len (keys )* 2 ; j ++ {
651
+ txs = append (txs , transaction (nonces [addr ], big .NewInt (100000 ), key ))
652
+ nonces [addr ]++
653
+ }
654
+ }
655
+ // Import the batch and verify that limits have been enforced
656
+ pool .AddBatch (txs )
657
+
658
+ pending := 0
659
+ for _ , list := range pool .pending {
660
+ pending += list .Len ()
661
+ }
662
+ if pending > int (maxPendingTotal ) {
663
+ t .Fatalf ("total pending transactions overflow allowance: %d > %d" , pending , maxPendingTotal )
664
+ }
665
+ }
666
+
667
+ // Tests that if the transaction count belonging to multiple accounts go above
668
+ // some hard threshold, if they are under the minimum guaranteed slot count then
669
+ // the transactions are still kept.
670
+ func TestTransactionPendingMinimumAllowance (t * testing.T ) {
671
+ // Reduce the queue limits to shorten test time
672
+ defer func (old uint64 ) { maxPendingTotal = old }(maxPendingTotal )
673
+ maxPendingTotal = 0
674
+
675
+ // Create the pool to test the limit enforcement with
676
+ db , _ := ethdb .NewMemDatabase ()
677
+ statedb , _ := state .New (common.Hash {}, db )
678
+
679
+ pool := NewTxPool (testChainConfig (), new (event.TypeMux ), func () (* state.StateDB , error ) { return statedb , nil }, func () * big.Int { return big .NewInt (1000000 ) })
680
+ pool .resetState ()
681
+
682
+ // Create a number of test accounts and fund them
683
+ state , _ := pool .currentState ()
684
+
685
+ keys := make ([]* ecdsa.PrivateKey , 5 )
686
+ for i := 0 ; i < len (keys ); i ++ {
687
+ keys [i ], _ = crypto .GenerateKey ()
688
+ state .AddBalance (crypto .PubkeyToAddress (keys [i ].PublicKey ), big .NewInt (1000000 ))
689
+ }
690
+ // Generate and queue a batch of transactions
691
+ nonces := make (map [common.Address ]uint64 )
692
+
693
+ txs := types.Transactions {}
694
+ for _ , key := range keys {
695
+ addr := crypto .PubkeyToAddress (key .PublicKey )
696
+ for j := 0 ; j < int (minPendingPerAccount )* 2 ; j ++ {
697
+ txs = append (txs , transaction (nonces [addr ], big .NewInt (100000 ), key ))
698
+ nonces [addr ]++
699
+ }
700
+ }
701
+ // Import the batch and verify that limits have been enforced
702
+ pool .AddBatch (txs )
703
+
704
+ for addr , list := range pool .pending {
705
+ if list .Len () != int (minPendingPerAccount ) {
706
+ t .Errorf ("addr %x: total pending transactions mismatch: have %d, want %d" , addr , list .Len (), minPendingPerAccount )
707
+ }
708
+ }
709
+ }
710
+
621
711
// Benchmarks the speed of validating the contents of the pending queue of the
622
712
// transaction pool.
623
713
func BenchmarkPendingDemotion100 (b * testing.B ) { benchmarkPendingDemotion (b , 100 ) }
0 commit comments