@@ -109,6 +109,7 @@ 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+
112113 // Ensure the next nonce to assign is the correct one
113114 for addr , txs := range pool .pending {
114115 // Find the last transaction
@@ -868,7 +869,7 @@ func TestTransactionQueueTimeLimitingNoLocals(t *testing.T) {
868869func testTransactionQueueTimeLimiting (t * testing.T , nolocals bool ) {
869870 // Reduce the eviction interval to a testable amount
870871 defer func (old time.Duration ) { evictionInterval = old }(evictionInterval )
871- evictionInterval = time .Second
872+ evictionInterval = time .Millisecond * 100
872873
873874 // Create the pool to test the non-expiration enforcement
874875 statedb , _ := state .New (common.Hash {}, state .NewDatabase (rawdb .NewMemoryDatabase ()), nil )
@@ -905,6 +906,22 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
905906 if err := validateTxPoolInternals (pool ); err != nil {
906907 t .Fatalf ("pool internal state corrupted: %v" , err )
907908 }
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+
908925 // Wait a bit for eviction to run and clean up any leftovers, and ensure only the local remains
909926 time .Sleep (2 * config .Lifetime )
910927
@@ -924,6 +941,72 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
924941 if err := validateTxPoolInternals (pool ); err != nil {
925942 t .Fatalf ("pool internal state corrupted: %v" , err )
926943 }
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+ }
9271010}
9281011
9291012// Tests that even if the transaction count belonging to a single account goes
0 commit comments