mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 14:46:42 +00:00
eth/fetcher: separate monotonic clock and system time function
This commit is contained in:
parent
0427856858
commit
8bbc12e1ab
3 changed files with 22 additions and 11 deletions
|
|
@ -203,21 +203,22 @@ type TxFetcher struct {
|
|||
dropPeer func(string) // Drops a peer in case of announcement violation
|
||||
|
||||
step chan struct{} // Notification channel when the fetcher loop iterates
|
||||
clock mclock.Clock // Time wrapper to simulate in tests
|
||||
clock mclock.Clock // Monotonic clock or simulated clock for tests
|
||||
realTime func() time.Time // Real system time or simulated time for tests
|
||||
rand *mrand.Rand // Randomizer to use in tests instead of map range loops (soft-random)
|
||||
}
|
||||
|
||||
// NewTxFetcher creates a transaction fetcher to retrieve transaction
|
||||
// based on hash announcements.
|
||||
func NewTxFetcher(hasTx func(common.Hash) bool, addTxs func([]*types.Transaction) []error, fetchTxs func(string, []common.Hash) error, dropPeer func(string)) *TxFetcher {
|
||||
return NewTxFetcherForTests(hasTx, addTxs, fetchTxs, dropPeer, mclock.System{}, nil)
|
||||
return NewTxFetcherForTests(hasTx, addTxs, fetchTxs, dropPeer, mclock.System{}, time.Now, nil)
|
||||
}
|
||||
|
||||
// NewTxFetcherForTests is a testing method to mock out the realtime clock with
|
||||
// a simulated version and the internal randomness with a deterministic one.
|
||||
func NewTxFetcherForTests(
|
||||
hasTx func(common.Hash) bool, addTxs func([]*types.Transaction) []error, fetchTxs func(string, []common.Hash) error, dropPeer func(string),
|
||||
clock mclock.Clock, rand *mrand.Rand) *TxFetcher {
|
||||
clock mclock.Clock, realTime func() time.Time, rand *mrand.Rand) *TxFetcher {
|
||||
return &TxFetcher{
|
||||
notify: make(chan *txAnnounce),
|
||||
cleanup: make(chan *txDelivery),
|
||||
|
|
@ -237,6 +238,7 @@ func NewTxFetcherForTests(
|
|||
fetchTxs: fetchTxs,
|
||||
dropPeer: dropPeer,
|
||||
clock: clock,
|
||||
realTime: realTime,
|
||||
rand: rand,
|
||||
}
|
||||
}
|
||||
|
|
@ -293,8 +295,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)
|
||||
now := time.Unix(int64(f.clock.Now()/1000000000), 0)
|
||||
if ok && prevTime.Before(now.Add(-maxTxUnderpricedTimeout)) {
|
||||
if ok && prevTime.Before(f.realTime().Add(-maxTxUnderpricedTimeout)) {
|
||||
f.underpriced.Remove(hash)
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2160,6 +2160,11 @@ func TestTransactionForgotten(t *testing.T) {
|
|||
|
||||
// Create a mock clock for deterministic time control
|
||||
mockClock := new(mclock.Simulated)
|
||||
mockTime := func() time.Time {
|
||||
nanoTime := int64(mockClock.Now())
|
||||
return time.Unix(nanoTime/1000000000, nanoTime%1000000000)
|
||||
}
|
||||
|
||||
fetcher := NewTxFetcherForTests(
|
||||
func(common.Hash) bool { return false },
|
||||
func(txs []*types.Transaction) []error {
|
||||
|
|
@ -2172,6 +2177,7 @@ func TestTransactionForgotten(t *testing.T) {
|
|||
func(string, []common.Hash) error { return nil },
|
||||
func(string) {},
|
||||
mockClock,
|
||||
mockTime,
|
||||
rand.New(rand.NewSource(0)), // Use fixed seed for deterministic behavior
|
||||
)
|
||||
fetcher.Start()
|
||||
|
|
@ -2181,7 +2187,7 @@ func TestTransactionForgotten(t *testing.T) {
|
|||
tx1 := types.NewTransaction(0, common.Address{}, big.NewInt(100), 21000, big.NewInt(1), nil)
|
||||
tx2 := types.NewTransaction(1, common.Address{}, big.NewInt(100), 21000, big.NewInt(1), nil)
|
||||
|
||||
now := time.Unix(int64(mockClock.Now()/1000000000), 0)
|
||||
now := mockTime()
|
||||
tx1.SetTime(now)
|
||||
tx2.SetTime(now)
|
||||
|
||||
|
|
@ -2234,8 +2240,7 @@ func TestTransactionForgotten(t *testing.T) {
|
|||
}
|
||||
|
||||
// Re-enqueue tx1 with updated timestamp
|
||||
now = time.Unix(int64(mockClock.Now()/1000000000), 0)
|
||||
tx1.SetTime(now)
|
||||
tx1.SetTime(mockTime())
|
||||
if err := fetcher.Enqueue("peer", []*types.Transaction{tx1}, false); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,12 @@ func fuzz(input []byte) int {
|
|||
},
|
||||
func(string, []common.Hash) error { return nil },
|
||||
nil,
|
||||
clock, rand,
|
||||
clock,
|
||||
func() time.Time {
|
||||
nanoTime := int64(clock.Now())
|
||||
return time.Unix(nanoTime/1000000000, nanoTime%1000000000)
|
||||
},
|
||||
rand,
|
||||
)
|
||||
f.Start()
|
||||
defer f.Stop()
|
||||
|
|
|
|||
Loading…
Reference in a new issue