diff options
Diffstat (limited to 'les/fetcher.go')
-rw-r--r-- | les/fetcher.go | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/les/fetcher.go b/les/fetcher.go index cc539c42b..f0d3b188d 100644 --- a/les/fetcher.go +++ b/les/fetcher.go @@ -32,8 +32,9 @@ import ( ) const ( - blockDelayTimeout = time.Second * 10 // timeout for a peer to announce a head that has already been confirmed by others - maxNodeCount = 20 // maximum number of fetcherTreeNode entries remembered for each peer + blockDelayTimeout = time.Second * 10 // timeout for a peer to announce a head that has already been confirmed by others + maxNodeCount = 20 // maximum number of fetcherTreeNode entries remembered for each peer + serverStateAvailable = 100 // number of recent blocks where state availability is assumed ) // lightFetcher implements retrieval of newly announced headers. It also provides a peerHasBlock function for the @@ -215,8 +216,8 @@ func (f *lightFetcher) syncLoop() { // registerPeer adds a new peer to the fetcher's peer set func (f *lightFetcher) registerPeer(p *peer) { p.lock.Lock() - p.hasBlock = func(hash common.Hash, number uint64) bool { - return f.peerHasBlock(p, hash, number) + p.hasBlock = func(hash common.Hash, number uint64, hasState bool) bool { + return f.peerHasBlock(p, hash, number, hasState) } p.lock.Unlock() @@ -344,21 +345,27 @@ func (f *lightFetcher) announce(p *peer, head *announceData) { // peerHasBlock returns true if we can assume the peer knows the given block // based on its announcements -func (f *lightFetcher) peerHasBlock(p *peer, hash common.Hash, number uint64) bool { +func (f *lightFetcher) peerHasBlock(p *peer, hash common.Hash, number uint64, hasState bool) bool { f.lock.Lock() defer f.lock.Unlock() + fp := f.peers[p] + if fp == nil || fp.root == nil { + return false + } + + if hasState { + if fp.lastAnnounced == nil || fp.lastAnnounced.number > number+serverStateAvailable { + return false + } + } + if f.syncing { // always return true when syncing // false positives are acceptable, a more sophisticated condition can be implemented later return true } - fp := f.peers[p] - if fp == nil || fp.root == nil { - return false - } - if number >= fp.root.number { // it is recent enough that if it is known, is should be in the peer's block tree return fp.nodeByHash[hash] != nil |