Skip to content

Downloader.findAncestorBinarySearch

Source (upstream pre-purge) Current
File eth/downloader/downloader.go downloader_pow.go
Symbol Downloader.findAncestorBinarySearch Downloader.findAncestorBinarySearch
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 — see Downloader.findAncestorSpanSearch

3-way merge — purge → getc ← upstream

pre-purge≈ adapted (origin inferred by similarity)fork-only
// findAncestorBinarySearch searches for a common ancestor using binary search.
func (d *Downloader) findAncestorBinarySearch(p *peerConnection, mode SyncMode, remoteHeight uint64, floor int64) (uint64, error) {
hash := common.Hash{}
// Ancestor not found, we need to binary search over our chain
start, end := uint64(0), remoteHeight
if floor > 0 {
start = uint64(floor)
}
p.log.Trace("Binary searching for common ancestor", "start", start, "end", end)
for start+1 < end {
// Split our chain interval in two, and request the hash to cross check
check := (start + end) / 2
headers, hashes, err := d.fetchHeadersByNumber(p, check, 1, 0, false)
if err != nil {
return 0, err
}
// Make sure the peer actually gave something valid
if len(headers) != 1 {
p.log.Warn("Multiple headers for single request", "headers", len(headers))
return 0, fmt.Errorf("%w: multiple headers (%d) for single request", errBadPeer, len(headers))
}
// Modify the search interval based on the response
h := hashes[0]
n := headers[0].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 {
end = check
continue
}
header := d.blockchain.GetHeaderByHash(h) // Independent of sync mode, header surely exists
if header.Number.Uint64() != check {
p.log.Warn("Received non requested header", "number", header.Number, "hash", header.Hash(), "request", check)
return 0, fmt.Errorf("%w: non-requested header (%d)", errBadPeer, header.Number)
}
start = check
hash = h
}
// Ensure valid ancestry and return
if int64(start) <= floor {
p.log.Warn("Ancestor below allowance", "number", start, "hash", hash, "allowance", floor)
return 0, errInvalidAncestor
}
p.log.Debug("Found common ancestor", "number", start, "hash", hash)
return start, nil
}
core-geth validation — +5 -6 | | | |---|---| | File | [`downloader.go`](https://github.com/etclabscore/core-geth/blob/v1.12.20/eth/downloader/downloader.go) | | Symbol | `Downloader.findAncestorBinarySearch` | | Ref | `v1.12.20` |
--- a/core-geth/eth/downloader/downloader.go
+++ b/etc/eth/downloader/downloader_pow.go
@@ -1,3 +1,4 @@
+// findAncestorBinarySearch searches for a common ancestor using binary search.
 func (d *Downloader) findAncestorBinarySearch(p *peerConnection, mode SyncMode, remoteHeight uint64, floor int64) (uint64, error) {
    hash := common.Hash{}

@@ -27,20 +28,18 @@

        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 {
            end = check
            continue
        }
-       header := d.lightchain.GetHeaderByHash(h) // Independent of sync mode, header surely exists
+       header := d.blockchain.GetHeaderByHash(h) // Independent of sync mode, header surely exists
        if header.Number.Uint64() != check {
            p.log.Warn("Received non requested header", "number", header.Number, "hash", header.Hash(), "request", check)
            return 0, fmt.Errorf("%w: non-requested header (%d)", errBadPeer, header.Number)

← Sync & Downloader