@@ -109,6 +109,7 @@ 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
+
112
113
// Ensure the next nonce to assign is the correct one
113
114
for addr , txs := range pool .pending {
114
115
// Find the last transaction
@@ -868,7 +869,7 @@ func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) {
868
869
func testTransactionQueueTimeLimiting (t * testing.T , nolocals bool ) {
869
870
// Reduce the eviction interval to a testable amount
870
871
defer func (old time.Duration ) { evictionInterval = old }(evictionInterval )
871
- evictionInterval = time .Second
872
+ evictionInterval = time .Millisecond * 100
872
873
873
874
// Create the pool to test the non-expiration enforcement
874
875
statedb , _ := state .New (common.Hash {}, state .NewDatabase (rawdb .NewMemoryDatabase ()), nil )
@@ -905,6 +906,22 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
905
906
if err := validateTxPoolInternals (pool ); err != nil {
906
907
t .Fatalf ("pool internal state corrupted: %v" , err )
907
908
}
909
+
910
+ // Allow the eviction interval to run
911
+ time .Sleep (2 * evictionInterval )
912
+
913
+ // Transactions should not be evicted from the queue yet since lifetime duration has not passed
914
+ pending , queued = pool .Stats ()
915
+ if pending != 0 {
916
+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 0 )
917
+ }
918
+ if queued != 2 {
919
+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 2 )
920
+ }
921
+ if err := validateTxPoolInternals (pool ); err != nil {
922
+ t .Fatalf ("pool internal state corrupted: %v" , err )
923
+ }
924
+
908
925
// Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains
909
926
time .Sleep (2 * config .Lifetime )
910
927
@@ -924,6 +941,72 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
924
941
if err := validateTxPoolInternals (pool ); err != nil {
925
942
t .Fatalf ("pool internal state corrupted: %v" , err )
926
943
}
944
+
945
+ // remove current transactions and increase nonce to prepare for a reset and cleanup
946
+ statedb .SetNonce (crypto .PubkeyToAddress (remote .PublicKey ), 2 )
947
+ statedb .SetNonce (crypto .PubkeyToAddress (local .PublicKey ), 2 )
948
+ <- pool .requestReset (nil , nil )
949
+
950
+ // make sure queue, pending are cleared
951
+ pending , queued = pool .Stats ()
952
+ if pending != 0 {
953
+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 0 )
954
+ }
955
+ if queued != 0 {
956
+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 0 )
957
+ }
958
+ if err := validateTxPoolInternals (pool ); err != nil {
959
+ t .Fatalf ("pool internal state corrupted: %v" , err )
960
+ }
961
+
962
+ // Queue gapped transactions
963
+ if err := pool .AddLocal (pricedTransaction (4 , 100000 , big .NewInt (1 ), local )); err != nil {
964
+ t .Fatalf ("failed to add remote transaction: %v" , err )
965
+ }
966
+ if err := pool .addRemoteSync (pricedTransaction (4 , 100000 , big .NewInt (1 ), remote )); err != nil {
967
+ t .Fatalf ("failed to add remote transaction: %v" , err )
968
+ }
969
+ time .Sleep (5 * evictionInterval ) // A half lifetime pass
970
+
971
+ // Queue executable transactions, the life cycle should be restarted.
972
+ if err := pool .AddLocal (pricedTransaction (2 , 100000 , big .NewInt (1 ), local )); err != nil {
973
+ t .Fatalf ("failed to add remote transaction: %v" , err )
974
+ }
975
+ if err := pool .addRemoteSync (pricedTransaction (2 , 100000 , big .NewInt (1 ), remote )); err != nil {
976
+ t .Fatalf ("failed to add remote transaction: %v" , err )
977
+ }
978
+ time .Sleep (6 * evictionInterval )
979
+
980
+ // All gapped transactions shouldn't be kicked out
981
+ pending , queued = pool .Stats ()
982
+ if pending != 2 {
983
+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 2 )
984
+ }
985
+ if queued != 2 {
986
+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 3 )
987
+ }
988
+ if err := validateTxPoolInternals (pool ); err != nil {
989
+ t .Fatalf ("pool internal state corrupted: %v" , err )
990
+ }
991
+
992
+ // The whole life time pass after last promotion, kick out stale transactions
993
+ time .Sleep (2 * config .Lifetime )
994
+ pending , queued = pool .Stats ()
995
+ if pending != 2 {
996
+ t .Fatalf ("pending transactions mismatched: have %d, want %d" , pending , 2 )
997
+ }
998
+ if nolocals {
999
+ if queued != 0 {
1000
+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 0 )
1001
+ }
1002
+ } else {
1003
+ if queued != 1 {
1004
+ t .Fatalf ("queued transactions mismatched: have %d, want %d" , queued , 1 )
1005
+ }
1006
+ }
1007
+ if err := validateTxPoolInternals (pool ); err != nil {
1008
+ t .Fatalf ("pool internal state corrupted: %v" , err )
1009
+ }
927
1010
}
928
1011
929
1012
// Tests that even if the transaction count belonging to a single account goes
0 commit comments