@@ -36,24 +36,26 @@ const (
36
36
maxNodeCount = 20 // maximum number of fetcherTreeNode entries remembered for each peer
37
37
)
38
38
39
- // lightFetcher
39
+ // lightFetcher implements retrieval of newly announced headers. It also provides a peerHasBlock function for the
40
+ // ODR system to ensure that we only request data related to a certain block from peers who have already processed
41
+ // and announced that block.
40
42
type lightFetcher struct {
41
43
pm * ProtocolManager
42
44
odr * LesOdr
43
45
chain * light.LightChain
44
46
47
+ lock sync.Mutex // lock protects access to the fetcher's internal state variables except sent requests
45
48
maxConfirmedTd * big.Int
46
49
peers map [* peer ]* fetcherPeerInfo
47
50
lastUpdateStats * updateStatsEntry
51
+ syncing bool
52
+ syncDone chan * peer
48
53
49
- lock sync.Mutex // qwerqwerqwe
50
- deliverChn chan fetchResponse
51
- reqMu sync.RWMutex
54
+ reqMu sync.RWMutex // reqMu protects access to sent header fetch requests
52
55
requested map [uint64 ]fetchRequest
56
+ deliverChn chan fetchResponse
53
57
timeoutChn chan uint64
54
58
requestChn chan bool // true if initiated from outside
55
- syncing bool
56
- syncDone chan * peer
57
59
}
58
60
59
61
// fetcherPeerInfo holds fetcher-specific information about each active peer
@@ -560,8 +562,13 @@ func (f *lightFetcher) checkAnnouncedHeaders(fp *fetcherPeerInfo, headers []*typ
560
562
return true
561
563
}
562
564
// we ran out of recently delivered headers but have not reached a node known by this peer yet, continue matching
563
- td = f .chain .GetTd (header .ParentHash , header .Number .Uint64 ()- 1 )
564
- header = f .chain .GetHeader (header .ParentHash , header .Number .Uint64 ()- 1 )
565
+ hash , number := header .ParentHash , header .Number .Uint64 ()- 1
566
+ td = f .chain .GetTd (hash , number )
567
+ header = f .chain .GetHeader (hash , number )
568
+ if header == nil || td == nil {
569
+ log .Error ("Missing parent of validated header" , "hash" , hash , "number" , number )
570
+ return false
571
+ }
565
572
} else {
566
573
header = headers [i ]
567
574
td = tds [i ]
@@ -645,13 +652,18 @@ func (f *lightFetcher) checkKnownNode(p *peer, n *fetcherTreeNode) bool {
645
652
if td == nil {
646
653
return false
647
654
}
655
+ header := f .chain .GetHeader (n .hash , n .number )
656
+ // check the availability of both header and td because reads are not protected by chain db mutex
657
+ // Note: returning false is always safe here
658
+ if header == nil {
659
+ return false
660
+ }
648
661
649
662
fp := f .peers [p ]
650
663
if fp == nil {
651
664
p .Log ().Debug ("Unknown peer to check known nodes" )
652
665
return false
653
666
}
654
- header := f .chain .GetHeader (n .hash , n .number )
655
667
if ! f .checkAnnouncedHeaders (fp , []* types.Header {header }, []* big.Int {td }) {
656
668
p .Log ().Debug ("Inconsistent announcement" )
657
669
go f .pm .removePeer (p .id )
0 commit comments