Skip to content

Commit c4e4baf

Browse files
karalabeobscuren
authored andcommitted
[release/1.4.11] eth/downloader: fewer headers and futures too un ancestor lookup
(cherry picked from commit d68865f)
1 parent 86493f9 commit c4e4baf

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

eth/downloader/downloader.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -572,11 +572,17 @@ func (d *Downloader) findAncestor(p *peer, height uint64) (uint64, error) {
572572
if head > height {
573573
head = height
574574
}
575-
from := int64(head) - int64(MaxHeaderFetch) + 1
575+
from := int64(head) - int64(MaxHeaderFetch)
576576
if from < 0 {
577577
from = 0
578578
}
579-
go p.getAbsHeaders(uint64(from), MaxHeaderFetch, 0, false)
579+
// Span out with 15 block gaps into the future to catch bad head reports
580+
limit := 2 * MaxHeaderFetch / 16
581+
count := 1 + int((int64(ceil)-from)/16)
582+
if count > limit {
583+
count = limit
584+
}
585+
go p.getAbsHeaders(uint64(from), count, 15, false)
580586

581587
// Wait for the remote response to the head fetch
582588
number, hash := uint64(0), common.Hash{}
@@ -601,25 +607,27 @@ func (d *Downloader) findAncestor(p *peer, height uint64) (uint64, error) {
601607
}
602608
// Make sure the peer's reply conforms to the request
603609
for i := 0; i < len(headers); i++ {
604-
if number := headers[i].Number.Int64(); number != from+int64(i) {
605-
glog.V(logger.Warn).Infof("%v: head header set (item %d) broke chain ordering: requested %d, got %d", p, i, from+int64(i), number)
606-
return 0, errInvalidChain
607-
}
608-
if i > 0 && headers[i-1].Hash() != headers[i].ParentHash {
609-
glog.V(logger.Warn).Infof("%v: head header set (item %d) broke chain ancestry: expected [%x], got [%x]", p, i, headers[i-1].Hash().Bytes()[:4], headers[i].ParentHash[:4])
610+
if number := headers[i].Number.Int64(); number != from+int64(i)*16 {
611+
glog.V(logger.Warn).Infof("%v: head header set (item %d) broke chain ordering: requested %d, got %d", p, i, from+int64(i)*16, number)
610612
return 0, errInvalidChain
611613
}
612614
}
613615
// Check if a common ancestor was found
614616
finished = true
615617
for i := len(headers) - 1; i >= 0; i-- {
616618
// Skip any headers that underflow/overflow our requested set
617-
if headers[i].Number.Int64() < from || headers[i].Number.Uint64() > head {
619+
if headers[i].Number.Int64() < from || headers[i].Number.Uint64() > ceil {
618620
continue
619621
}
620622
// Otherwise check if we already know the header or not
621623
if (d.mode == FullSync && d.hasBlockAndState(headers[i].Hash())) || (d.mode != FullSync && d.hasHeader(headers[i].Hash())) {
622624
number, hash = headers[i].Number.Uint64(), headers[i].Hash()
625+
626+
// If every header is known, even future ones, the peer straight out lied about its head
627+
if number > height && i == limit-1 {
628+
glog.V(logger.Warn).Infof("%v: lied about chain head: reported %d, found above %d", p, height, number)
629+
return 0, errStallingPeer
630+
}
623631
break
624632
}
625633
}

0 commit comments

Comments
 (0)