From 055eb26ae884fbe25b198fa011e9ff6f2ae4b1d3 Mon Sep 17 00:00:00 2001 From: Zsolt Felfoldi Date: Thu, 15 Feb 2018 18:08:39 +0100 Subject: [PATCH] les: fix light fetcher database race --- les/fetcher.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) 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)