Skip to content

Downloader.findAncestorSpanSearch

Source (upstream pre-purge) Current
File eth/downloader/downloader.go downloader_pow.go
Symbol Downloader.findAncestorSpanSearch Downloader.findAncestorSpanSearch
Ref 45baf2111~1 etc/v1.17.3-full-node

d.lightchain replaced with d.blockchain — semantically identical since BlockChain embeds LightChain; LightSync removed upstream in #29711

3-way merge — purge → getc ← upstream

pre-purge≈ adapted (origin inferred by similarity)fork-only
// findAncestorSpanSearch searches for a common ancestor using a span search.
func (d *Downloader) findAncestorSpanSearch(p *peerConnection, mode SyncMode, remoteHeight, localHeight uint64, floor int64) (uint64, error) {
from, count, skip, max := calculateRequestSpan(remoteHeight, localHeight)
p.log.Trace("Span searching for common ancestor", "count", count, "from", from, "skip", skip)
headers, hashes, err := d.fetchHeadersByNumber(p, uint64(from), count, skip, false)
if err != nil {
return 0, err
}
// Wait for the remote response to the head fetch
number, hash := uint64(0), common.Hash{}
// Make sure the peer actually gave something valid
if len(headers) == 0 {
p.log.Warn("Empty head header set")
return 0, errEmptyHeaderSet
}
// Make sure the peer's reply conforms to the request
for i, header := range headers {
expectNumber := from + int64(i)*int64(skip+1)
if number := header.Number.Int64(); number != expectNumber {
p.log.Warn("Head headers broke chain ordering", "index", i, "requested", expectNumber, "received", number)
return 0, fmt.Errorf("%w: %v", errInvalidChain, errors.New("head headers broke chain ordering"))
}
}
// Check if a common ancestor was found
for i := len(headers) - 1; i >= 0; i-- {
// Skip any headers that underflow/overflow our requested set
if headers[i].Number.Int64() < from || headers[i].Number.Uint64() > max {
continue
}
// Otherwise check if we already know the header or not
h := hashes[i]
n := headers[i].Number.Uint64()
var known bool
switch mode {
case ethconfig.FullSync:
known = d.blockchain.HasBlock(h, n)
case ethconfig.SnapSync:
known = d.blockchain.HasFastBlock(h, n)
default:
known = d.blockchain.HasHeader(h, n)
}
if known {
number, hash = n, h
break
}
}
// If the head fetch already found an ancestor, return
if hash != (common.Hash{}) {
if int64(number) <= floor {
p.log.Warn("Ancestor below allowance", "number", number, "hash", hash, "allowance", floor)
return 0, errInvalidAncestor
}
p.log.Debug("Found common ancestor", "number", number, "hash", hash)
return number, nil
}
return 0, errNoAncestorFound
}
core-geth validation — +4 -5 | | | |---|---| | File | [`downloader.go`](https://github.com/etclabscore/core-geth/blob/v1.12.20/eth/downloader/downloader.go) | | Symbol | `Downloader.findAncestorSpanSearch` | | Ref | `v1.12.20` |
--- a/core-geth/eth/downloader/downloader.go
+++ b/etc/eth/downloader/downloader_pow.go
@@ -1,3 +1,4 @@
+// findAncestorSpanSearch searches for a common ancestor using a span search.
 func (d *Downloader) findAncestorSpanSearch(p *peerConnection, mode SyncMode, remoteHeight, localHeight uint64, floor int64) (uint64, error) {
    from, count, skip, max := calculateRequestSpan(remoteHeight, localHeight)

@@ -34,14 +35,12 @@

        var known bool
        switch mode {
-       case FullSync:
+       case ethconfig.FullSync:
            known = d.blockchain.HasBlock(h, n)
-       case SnapSync:
+       case ethconfig.SnapSync:
            known = d.blockchain.HasFastBlock(h, n)
-       case LightSync:
-           known = d.lightchain.HasHeader(h, n)
        default:
-           log.Crit("unknown sync mode", "mode", mode)
+           known = d.blockchain.HasHeader(h, n)
        }
        if known {
            number, hash = n, h

← Sync & Downloader