diff --git a/les/fetcher.go b/les/fetcher.go index 9d224176fc..d0a74ad258 100644 --- a/les/fetcher.go +++ b/les/fetcher.go @@ -46,7 +46,7 @@ type lightFetcher struct { peers map[*peer]*fetcherPeerInfo lastUpdateStats *updateStatsEntry - lock sync.Mutex // qwerqwerqwe + lock sync.Mutex deliverChn chan fetchResponse reqMu sync.RWMutex requested map[uint64]fetchRequest @@ -560,8 +560,13 @@ func (f *lightFetcher) checkAnnouncedHeaders(fp *fetcherPeerInfo, headers []*typ return true } // we ran out of recently delivered headers but have not reached a node known by this peer yet, continue matching - td = f.chain.GetTd(header.ParentHash, header.Number.Uint64()-1) - header = f.chain.GetHeader(header.ParentHash, header.Number.Uint64()-1) + hash, number := header.ParentHash, header.Number.Uint64()-1 + td = f.chain.GetTd(hash, number) + header = f.chain.GetHeader(hash, number) + if header == nil || td == nil { + log.Error("Missing parent of validated header", "hash", hash, "number", number) + return false + } } else { header = headers[i] td = tds[i] @@ -645,13 +650,18 @@ func (f *lightFetcher) checkKnownNode(p *peer, n *fetcherTreeNode) bool { if td == nil { return false } + header := f.chain.GetHeader(n.hash, n.number) + // check the availability of both header and td because reads are not protected by chain db mutex + // Note: returning false is always safe here + if header == nil { + return false + } fp := f.peers[p] if fp == nil { p.Log().Debug("Unknown peer to check known nodes") return false } - header := f.chain.GetHeader(n.hash, n.number) if !f.checkAnnouncedHeaders(fp, []*types.Header{header}, []*big.Int{td}) { p.Log().Debug("Inconsistent announcement") go f.pm.removePeer(p.id)