diff --git a/eth/downloader/skeleton.go b/eth/downloader/skeleton.go index 2cf9c4672b1..509a7fd0361 100644 --- a/eth/downloader/skeleton.go +++ b/eth/downloader/skeleton.go @@ -812,8 +812,14 @@ func (s *skeleton) executeTask(peer *peerConnection, req *headerRequest) { case headers[0].Number.Uint64() != req.head: // Header batch anchored at non-requested number - peer.log.Debug("Invalid header response head", "have", headers[0].Number, "want", req.head) - res.Done <- errors.New("invalid header batch anchor") + if peerHeader := headers[0].Number.Uint64(); peerHeader > req.head { + peer.log.Debug("Invalid header response head", "have", peerHeader, "want", req.head) + res.Done <- errors.New("invalid header batch anchor") + } else { + peer.log.Debug("Peer behind requested head, rescheduling", "have", peerHeader, "want", req.head) + // Do not penalize the peer if it is behind our requested head + res.Done <- nil + } s.scheduleRevertRequest(req) case req.head >= requestHeaders && len(headers) != requestHeaders: diff --git a/eth/downloader/skeleton_test.go b/eth/downloader/skeleton_test.go index 4aa97cf1f79..454f375a906 100644 --- a/eth/downloader/skeleton_test.go +++ b/eth/downloader/skeleton_test.go @@ -609,14 +609,14 @@ func TestSkeletonSyncRetrievals(t *testing.T) { mid: skeletonExpect{ state: []*subchain{{Head: requestHeaders + 100, Tail: 100}}, serve: requestHeaders + 101 - 3, // len - head - genesis - missing - drop: 1, // penalize shortened header deliveries + drop: 0, // do not penalize in relaxed mode }, newPeer: newSkeletonTestPeer("good-peer", chain), end: skeletonExpect{ state: []*subchain{{Head: requestHeaders + 100, Tail: 1}}, serve: (requestHeaders + 101 - 3) + (100 - 1), // midserve + lenrest - genesis - drop: 1, // no new drops + drop: 0, // relaxed: no drops }, }, // This test checks if a peer tries to withhold a header - *off* the sync @@ -655,14 +655,14 @@ func TestSkeletonSyncRetrievals(t *testing.T) { mid: skeletonExpect{ state: []*subchain{{Head: requestHeaders + 100, Tail: 100}}, serve: requestHeaders + 101 - 2, // len - head - genesis - drop: 1, // penalize invalid header sequences + drop: 0, // do not penalize in relaxed mode }, newPeer: newSkeletonTestPeer("good-peer", chain), end: skeletonExpect{ state: []*subchain{{Head: requestHeaders + 100, Tail: 1}}, serve: (requestHeaders + 101 - 2) + (100 - 1), // midserve + lenrest - genesis - drop: 1, // no new drops + drop: 0, // relaxed: no drops }, }, // This test checks if a peer tries to duplicate a header - *off* the sync