@@ -109,6 +109,10 @@ func validateTxPoolInternals(pool *TxPool) error {
109
109
if priced := pool .priced .items .Len () - pool .priced .stales ; priced != pending + queued {
110
110
return fmt .Errorf ("total priced transaction count %d != %d pending + %d queued" , priced , pending , queued )
111
111
}
112
+ if queued != len (pool .queuedTs ) {
113
+ return fmt .Errorf ("total queued transaction count %d != %d queuedTs length" , queued , len (pool .queuedTs ))
114
+ }
115
+
112
116
// Ensure the next nonce to assign is the correct one
113
117
for addr , txs := range pool .pending {
114
118
// Find the last transaction
@@ -868,7 +872,7 @@ func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) {
868
872
func testTransactionQueueTimeLimiting (t * testing.T , nolocals bool ) {
869
873
// Reduce the eviction interval to a testable amount
870
874
defer func (old time.Duration ) { evictionInterval = old }(evictionInterval )
871
- evictionInterval = time .Second
875
+ evictionInterval = time .Millisecond * 100
872
876
873
877
// Create the pool to test the non-expiration enforcement
874
878
statedb , _ := state .New (common.Hash {}, state .NewDatabase (rawdb .NewMemoryDatabase ()), nil )
@@ -905,6 +909,22 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
905
909
if err := validateTxPoolInternals (pool ); err != nil {
906
910
t .Fatalf ("pool internal state corrupted: %v" , err )
907
911
}
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
+
908
928
// Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains
909
929
time .Sleep (2 * config .Lifetime )
910
930
@@ -924,6 +944,117 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
924
944
if err := validateTxPoolInternals (pool ); err != nil {
925
945
t .Fatalf ("pool internal state corrupted: %v" , err )
926
946
}
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
+ }
927
1058
}
928
1059
929
1060
// Tests that even if the transaction count belonging to a single account goes
0 commit comments