diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index 24038fb4c6ee94e64feaaef54dc39d2b29845335..9deab0df1b63629c46a48e23e948714b98bcd388 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -755,117 +755,110 @@ func (hd *HeaderDownload) InsertHeaders(hf FeedHeaderFunc, terminalTotalDifficul hd.lock.Lock() defer hd.lock.Unlock() - checkVerify := true checkInsert := true - for checkVerify || checkInsert { - if checkVerify { - checkVerify = false - // Perform verification if needed - for hd.verifyQueue.Len() > 0 { - link := hd.verifyQueue[0] - select { - case <-logChannel: - log.Info(fmt.Sprintf("[%s] Verifying headers", logPrefix), "progress", hd.highestInDb) - default: - } - skip := false - if link.blockHeight <= hd.preverifiedHeight { - if link.blockHeight <= hd.highestInDb { - // There was preverified alternative to this link, drop - skip = true - } else { - break // Wait to be mark as pre-verified or an alternative to be inserted - } - } - if !skip { - _, skip = hd.badHeaders[link.hash] - } - if !skip && !link.persisted { - _, skip = hd.badHeaders[link.header.ParentHash] - } - if !skip { - if err := hd.VerifyHeader(link.header); err != nil { - if errors.Is(err, consensus.ErrFutureBlock) { - // This may become valid later - log.Warn("Added future link", "hash", link.hash, "height", link.blockHeight, "timestamp", link.header.Time) - break // prevent removal of the link from the hd.linkQueue - } else { - log.Warn("Verification failed for header", "hash", link.hash, "height", link.blockHeight, "err", err) - skip = true - } - } + for checkInsert { + checkInsert = false + // Check what we can insert without verification + for hd.insertQueue.Len() > 0 && hd.insertQueue[0].blockHeight <= hd.highestInDb+1 { + link := hd.insertQueue[0] + _, bad := hd.badHeaders[link.hash] + if !bad && !link.persisted { + _, bad = hd.badHeaders[link.header.ParentHash] + } + if bad { + // If the link or its parent is marked bad, throw it out + hd.moveLinkToQueue(link, NoQueue) + delete(hd.links, link.hash) + continue + } + // Make sure long insertions do not appear as a stuck stage 1 + select { + case <-logChannel: + log.Info(fmt.Sprintf("[%s] Inserting headers", logPrefix), "progress", hd.highestInDb) + default: + } + td, err := hf(link.header, link.headerRaw, link.hash, link.blockHeight) + if err != nil { + return false, err + } + if td != nil { + if hd.seenAnnounces.Pop(link.hash) { + hd.toAnnounce = append(hd.toAnnounce, Announce{Hash: link.hash, Number: link.blockHeight}) } - if skip { - hd.moveLinkToQueue(link, NoQueue) - delete(hd.links, link.hash) - continue + // Check if transition to proof-of-stake happened and stop forward syncing + if terminalTotalDifficulty != nil && td.Cmp(terminalTotalDifficulty) >= 0 { + hd.highestInDb = link.blockHeight + log.Info(POSPandaBanner) + return true, nil } - link.verified = true - hd.moveLinkToQueue(link, InsertQueueID) - checkInsert = true } - } - if checkInsert { - checkInsert = false - // Check what we can insert without verification - for hd.insertQueue.Len() > 0 && hd.insertQueue[0].blockHeight <= hd.highestInDb+1 { - link := hd.insertQueue[0] - _, bad := hd.badHeaders[link.hash] - if !bad && !link.persisted { - _, bad = hd.badHeaders[link.header.ParentHash] - } - if bad { - // If the link or its parent is marked bad, throw it out - hd.moveLinkToQueue(link, NoQueue) - delete(hd.links, link.hash) + + if link.blockHeight > hd.highestInDb { + hd.highestInDb = link.blockHeight + } + link.persisted = true + link.header = nil // Drop header reference to free memory, as we won't need it anymore + link.headerRaw = nil + hd.moveLinkToQueue(link, PersistedQueueID) + for _, nextLink := range link.next { + if nextLink.persisted { continue } - // Make sure long insertions do not appear as a stuck stage 1 - select { - case <-logChannel: - log.Info(fmt.Sprintf("[%s] Inserting headers", logPrefix), "progress", hd.highestInDb) - default: - } - td, err := hf(link.header, link.headerRaw, link.hash, link.blockHeight) - if err != nil { - return false, err - } - if td != nil { - if hd.seenAnnounces.Pop(link.hash) { - hd.toAnnounce = append(hd.toAnnounce, Announce{Hash: link.hash, Number: link.blockHeight}) - } - // Check if transition to proof-of-stake happened and stop forward syncing - if terminalTotalDifficulty != nil && td.Cmp(terminalTotalDifficulty) >= 0 { - hd.highestInDb = link.blockHeight - log.Info(POSPandaBanner) - return true, nil - } + if nextLink.verified { + hd.moveLinkToQueue(nextLink, InsertQueueID) + } else { + hd.moveLinkToQueue(nextLink, VerifyQueueID) } - - if link.blockHeight > hd.highestInDb { - hd.highestInDb = link.blockHeight - checkVerify = true // highestInDb changes, so that there might be more links in verifyQueue to process + } + } + for hd.persistedLinkQueue.Len() > hd.persistedLinkLimit { + link := heap.Pop(&hd.persistedLinkQueue).(*Link) + delete(hd.links, link.hash) + } + // Perform verification if needed + for hd.verifyQueue.Len() > 0 { + link := hd.verifyQueue[0] + select { + case <-logChannel: + log.Info(fmt.Sprintf("[%s] Verifying headers", logPrefix), "progress", hd.highestInDb) + default: + } + skip := false + if link.blockHeight <= hd.preverifiedHeight { + if link.blockHeight <= hd.highestInDb { + // There was preverified alternative to this link, drop + skip = true + } else { + break // Wait to be mark as pre-verified or an alternative to be inserted } - link.persisted = true - link.header = nil // Drop header reference to free memory, as we won't need it anymore - link.headerRaw = nil - hd.moveLinkToQueue(link, PersistedQueueID) - for _, nextLink := range link.next { - if nextLink.persisted { - continue - } - if nextLink.verified { - hd.moveLinkToQueue(nextLink, InsertQueueID) + } + if !skip { + _, skip = hd.badHeaders[link.hash] + } + if !skip && !link.persisted { + _, skip = hd.badHeaders[link.header.ParentHash] + } + if !skip { + if err := hd.VerifyHeader(link.header); err != nil { + if errors.Is(err, consensus.ErrFutureBlock) { + // This may become valid later + log.Warn("Added future link", "hash", link.hash, "height", link.blockHeight, "timestamp", link.header.Time) + break // prevent removal of the link from the hd.linkQueue } else { - hd.moveLinkToQueue(nextLink, VerifyQueueID) - checkVerify = true + log.Warn("Verification failed for header", "hash", link.hash, "height", link.blockHeight, "err", err) + skip = true } } } - for hd.persistedLinkQueue.Len() > hd.persistedLinkLimit { - link := heap.Pop(&hd.persistedLinkQueue).(*Link) + if skip { + hd.moveLinkToQueue(link, NoQueue) delete(hd.links, link.hash) + } else { + link.verified = true + hd.moveLinkToQueue(link, InsertQueueID) + checkInsert = true + break } } }