@@ -109,6 +109,10 @@ func validateTxPoolInternals(pool *TxPool) error {
109109 if priced := pool .priced .items .Len () - pool .priced .stales ; priced != pending + queued {
110110 return fmt .Errorf ("total priced transaction count %d != %d pending + %d queued" , priced , pending , queued )
111111 }
112+ if queued != len (pool .queuedTs ) {
113+ return fmt .Errorf ("total queued transaction count %d != %d queuedTs length" , queued , len (pool .queuedTs ))
114+ }
115+
112116 // Ensure the next nonce to assign is the correct one
113117 for addr , txs := range pool .pending {
114118 // Find the last transaction
@@ -868,7 +872,7 @@ func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) {
868872func testTransactionQueueTimeLimiting (t * testing.T , nolocals bool ) {
869873 // Reduce the eviction interval to a testable amount
870874 defer func (old time.Duration ) { evictionInterval = old }(evictionInterval )
871- evictionInterval = time .Second
875+ evictionInterval = time .Millisecond * 100
872876
873877 // Create the pool to test the non-expiration enforcement
874878 statedb , _ := state .New (common.Hash {}, state .NewDatabase (rawdb .NewMemoryDatabase ()), nil )
@@ -905,6 +909,22 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
905909 if err := validateTxPoolInternals (pool ); err != nil {
906910 t .Fatalf ("pool internal state corrupted: %v" , err )
907911 }
912+
913+ // Allow the eviction interval to run
914+ time .Sleep (2 * evictionInterval )
915+
916+ // Transactions should not be evicted from the queue yet since lifetime duration has not passed
917+ pending , queued = pool .Stats ()
918+ if pending != 0 {
919+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 0 )
920+ }
921+ if queued != 2 {
922+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 2 )
923+ }
924+ if err := validateTxPoolInternals (pool ); err != nil {
925+ t .Fatalf ("pool internal state corrupted: %v" , err )
926+ }
927+
908928 // Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains
909929 time .Sleep (2 * config .Lifetime )
910930
@@ -924,6 +944,117 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
924944 if err := validateTxPoolInternals (pool ); err != nil {
925945 t .Fatalf ("pool internal state corrupted: %v" , err )
926946 }
947+
948+ // remove current transactions and increase nonce to prepare for a reset and cleanup
949+ statedb .SetNonce (crypto .PubkeyToAddress (remote .PublicKey ), 2 )
950+ statedb .SetNonce (crypto .PubkeyToAddress (local .PublicKey ), 2 )
951+
952+ <- pool .requestReset (nil , nil )
953+
954+ // make sure queue, pending are cleared
955+ pending , queued = pool .Stats ()
956+ if pending != 0 {
957+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 0 )
958+ }
959+ if queued != 0 {
960+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 0 )
961+ }
962+ if err := validateTxPoolInternals (pool ); err != nil {
963+ t .Fatalf ("pool internal state corrupted: %v" , err )
964+ }
965+
966+ if err := pool .AddLocal (pricedTransaction (2 , 100000 , big .NewInt (1 ), local )); err != nil {
967+ t .Fatalf ("failed to add remote transaction: %v" , err )
968+ }
969+ if err := pool .AddLocal (pricedTransaction (4 , 100000 , big .NewInt (1 ), local )); err != nil {
970+ t .Fatalf ("failed to add remote transaction: %v" , err )
971+ }
972+ if err := pool .addRemoteSync (pricedTransaction (2 , 100000 , big .NewInt (1 ), remote )); err != nil {
973+ t .Fatalf ("failed to add remote transaction: %v" , err )
974+ }
975+ if err := pool .addRemoteSync (pricedTransaction (4 , 100000 , big .NewInt (1 ), remote )); err != nil {
976+ t .Fatalf ("failed to add remote transaction: %v" , err )
977+ }
978+
979+ // wait a short amount of time to add an additional future queued item to test proper eviction when
980+ // pending is removed
981+ time .Sleep (2 * evictionInterval )
982+ if err := pool .addRemoteSync (pricedTransaction (5 , 100000 , big .NewInt (1 ), remote )); err != nil {
983+ t .Fatalf ("failed to add remote transaction: %v" , err )
984+ }
985+
986+ // Make sure future queue and pending have transactions
987+ pending , queued = pool .Stats ()
988+ if pending != 2 {
989+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 2 )
990+ }
991+ if queued != 3 {
992+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 3 )
993+ }
994+ if err := validateTxPoolInternals (pool ); err != nil {
995+ t .Fatalf ("pool internal state corrupted: %v" , err )
996+ }
997+
998+ // Trigger a reset to make sure queued items are not evicted
999+ statedb .SetNonce (crypto .PubkeyToAddress (remote .PublicKey ), 3 )
1000+ statedb .SetNonce (crypto .PubkeyToAddress (local .PublicKey ), 3 )
1001+ <- pool .requestReset (nil , nil )
1002+
1003+ // Wait for eviction to run
1004+ time .Sleep (evictionInterval * 2 )
1005+
1006+ // a pool reset, empty pending list, or demotion of pending transactions should maintain
1007+ // queued transactions for non locals and locals alike if the lifetime duration has not passed yet
1008+ pending , queued = pool .Stats ()
1009+ if pending != 0 {
1010+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 0 )
1011+ }
1012+ if queued != 3 {
1013+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 2 )
1014+ }
1015+ if err := validateTxPoolInternals (pool ); err != nil {
1016+ t .Fatalf ("pool internal state corrupted: %v" , err )
1017+ }
1018+
1019+ // Wait for the lifetime to run for all transactions except the one that was added later
1020+ time .Sleep (evictionInterval * 7 )
1021+ pending , queued = pool .Stats ()
1022+ if pending != 0 {
1023+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 0 )
1024+ }
1025+ if nolocals {
1026+ if queued != 1 {
1027+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 1 )
1028+ }
1029+ } else {
1030+ if queued != 2 {
1031+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 2 )
1032+ }
1033+ }
1034+
1035+ if err := validateTxPoolInternals (pool ); err != nil {
1036+ t .Fatalf ("pool internal state corrupted: %v" , err )
1037+ }
1038+
1039+ // lifetime should pass for the final transaction
1040+ time .Sleep (evictionInterval * 2 )
1041+
1042+ pending , queued = pool .Stats ()
1043+ if pending != 0 {
1044+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 0 )
1045+ }
1046+ if nolocals {
1047+ if queued != 0 {
1048+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 2 )
1049+ }
1050+ } else {
1051+ if queued != 1 {
1052+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 0 )
1053+ }
1054+ }
1055+ if err := validateTxPoolInternals (pool ); err != nil {
1056+ t .Fatalf ("pool internal state corrupted: %v" , err )
1057+ }
9271058}
9281059
9291060// Tests that even if the transaction count belonging to a single account goes
0 commit comments