diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index 5747626968..a591ac9c47 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -284,7 +284,7 @@ func (f *TxFetcher) Notify(peer string, types []byte, sizes []uint32, hashes []c // isKnownUnderpriced reports whether a transaction hash was recently found to be underpriced. func (f *TxFetcher) isKnownUnderpriced(hash common.Hash) bool { prevTime, ok := f.underpriced.Peek(hash) - if ok && prevTime+maxTxUnderpricedTimeout < time.Now().Unix() { + if ok && prevTime+maxTxUnderpricedTimeout < time.Now().UnixNano() { f.underpriced.Remove(hash) return false } @@ -335,7 +335,7 @@ func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool) // Avoid re-request this transaction when we receive another // announcement. if errors.Is(err, txpool.ErrUnderpriced) || errors.Is(err, txpool.ErrReplaceUnderpriced) { - f.underpriced.Add(batch[j].Hash(), batch[j].Time().Unix()) + f.underpriced.Add(batch[j].Hash(), batch[j].Time().UnixNano()) } // Track a few interesting failure types switch { diff --git a/eth/fetcher/tx_fetcher_test.go b/eth/fetcher/tx_fetcher_test.go index fbb9ff9dcc..bd75d17915 100644 --- a/eth/fetcher/tx_fetcher_test.go +++ b/eth/fetcher/tx_fetcher_test.go @@ -1993,3 +1993,34 @@ func containsHash(slice []common.Hash, hash common.Hash) bool { } return false } + +// Tests that a transaction is forgotten after the timeout. +func TestTransactionForgotten(t *testing.T) { + fetcher := NewTxFetcher( + func(common.Hash) bool { return false }, + func(txs []*types.Transaction) []error { + errs := make([]error, len(txs)) + for i := 0; i < len(errs); i++ { + errs[i] = txpool.ErrUnderpriced + } + return errs + }, + func(string, []common.Hash) error { return nil }, + ) + go fetcher.loop() + tx1 := types.NewTransaction(0, common.Address{}, common.Big0, 0, common.Big0, nil) + tx1.SetTime(time.Now().Add(-5 * time.Minute)) + tx2 := types.NewTransaction(1, common.Address{}, common.Big0, 0, common.Big0, nil) + if fetcher.isKnownUnderpriced(tx1.Hash()) { + t.Fatal("unknown hash can not be underpriced") + } + if err := fetcher.Enqueue("asdf", []*types.Transaction{tx1, tx2}, false); err != nil { + t.Fatal(err) + } + if fetcher.isKnownUnderpriced(tx1.Hash()) { + t.Fatal("transaction should be evicted by this point") + } + if !fetcher.isKnownUnderpriced(tx2.Hash()) { + t.Fatal("transaction should not be known underpriced") + } +}