diff --git a/eth/txtracker/tracker.go b/eth/txtracker/tracker.go index beaab60977..8458c8253d 100644 --- a/eth/txtracker/tracker.go +++ b/eth/txtracker/tracker.go @@ -37,6 +37,7 @@ type PeerStats struct { type Chain interface { SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription GetBlockByNumber(number uint64) *types.Block + GetBlock(hash common.Hash, number uint64) *types.Block CurrentFinalBlock() *types.Header } @@ -146,8 +147,9 @@ func (t *Tracker) loop() { } func (t *Tracker) handleChainHead(ev core.ChainHeadEvent) { - // Update recent-inclusion EMA from the new head block. - block := t.chain.GetBlockByNumber(ev.Header.Number.Uint64()) + // Fetch the head block by hash (not just number) to avoid using a + // reorged block if the tracker goroutine lags behind the chain. + block := t.chain.GetBlock(ev.Header.Hash(), ev.Header.Number.Uint64()) if block == nil { return } diff --git a/eth/txtracker/tracker_test.go b/eth/txtracker/tracker_test.go index 35c315ac8f..36d72def23 100644 --- a/eth/txtracker/tracker_test.go +++ b/eth/txtracker/tracker_test.go @@ -35,6 +35,11 @@ func (c *mockChain) GetBlockByNumber(number uint64) *types.Block { return c.blocks[number] } +func (c *mockChain) GetBlock(hash common.Hash, number uint64) *types.Block { + // In tests we only key by number; ignore hash. + return c.GetBlockByNumber(number) +} + func (c *mockChain) CurrentFinalBlock() *types.Header { c.mu.Lock() defer c.mu.Unlock()