From 479ad41457ad4a880ab68814196d0c863f21745f Mon Sep 17 00:00:00 2001 From: Rob Schleusner Date: Tue, 3 Oct 2023 10:30:27 -0500 Subject: [PATCH] Recovers current header if it's not found in DB on startup --- core/headerchain.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/core/headerchain.go b/core/headerchain.go index f48d872100..032c52c74c 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -487,6 +487,12 @@ func (hc *HeaderChain) loadLastState() error { // properly and it doesn't crash the nodes hc.currentHeader.Store(hc.genesisHeader) } + } else { + // Recover the current header + log.Warn("Recovering Current Header") + recoverdHeader := hc.RecoverCurrentHeader() + rawdb.WriteHeadBlockHash(hc.headerDb, recoverdHeader.Hash()) + hc.currentHeader.Store(recoverdHeader) } heads := make([]*types.Header, 0) @@ -669,6 +675,30 @@ func (hc *HeaderChain) GetHeaderOrCandidate(hash common.Hash, number uint64) *ty return header } +// RecoverCurrentHeader retrieves the current head header of the canonical chain. The +// header is retrieved from the HeaderChain's internal cache +func (hc *HeaderChain) RecoverCurrentHeader() *types.Header { + // Start logarithmic ascent to find the upper bound + high := uint64(1) + for hc.GetHeaderByNumber(high) != nil { + high *= 2 + } + // Run binary search to find the max header + low := high / 2 + for low <= high { + mid := (low + high) / 2 + if hc.GetHeaderByNumber(mid) != nil { + low = mid + 1 + } else { + high = mid - 1 + } + } + header := hc.GetHeaderByNumber(high) + log.Info("Header Recovered: ", "hash", header.Hash().String()) + + return header +} + // GetHeaderOrCandidateByHash retrieves a block header from the database by hash, caching it if // found. func (hc *HeaderChain) GetHeaderOrCandidateByHash(hash common.Hash) *types.Header {