Downloader.findAncestor¶
| Source (upstream pre-purge) | Current | |
|---|---|---|
| File | eth/downloader/downloader.go |
downloader_pow.go |
| Symbol | Downloader.findAncestor |
Downloader.findAncestor |
| Ref | 45baf2111~1 |
etc/v1.17.3-full-node |
Diffs: lightMaxForkAncestry + CHT floor block removed, d.lightchain→d.blockchain (LightSync was dead code — #29711)
3-way merge — purge → getc ← upstream¶
pre-purge≈ adapted (origin inferred by similarity)
↗// findAncestor tries to locate the common ancestor link of the local chain and
// a remote peers blockchain. In the general case when our node was in sync and
// on the correct chain, checking the top N links should already get us a match.
// In the rare scenario when we ended up on a long reorganisation (i.e. none of
// the head links match), we do a binary search to find the common ancestor.
func (d *Downloader) findAncestor(p *peerConnection, remoteHeader *types.Header) (uint64, error) {
// Figure out the valid ancestor range to prevent rewrite attacks
var (
floor = int64(-1)
localHeight uint64
remoteHeight = remoteHeader.Number.Uint64()
)
mode := d.getMode()
switch mode {
≈ case ethconfig.FullSync:
↗ localHeight = d.blockchain.CurrentBlock().Number.Uint64()
≈ case ethconfig.SnapSync:
↗ localHeight = d.blockchain.CurrentSnapBlock().Number.Uint64()
default:
≈ localHeight = d.blockchain.CurrentHeader().Number.Uint64()
↗ }
p.log.Debug("Looking for common ancestor", "local", localHeight, "remote", remoteHeight)
↗ // Recap floor value for binary search
maxForkAncestry := fullMaxForkAncestry
↗ if localHeight >= maxForkAncestry {
// We're above the max reorg threshold, find the earliest fork point
floor = int64(localHeight - maxForkAncestry)
}
↗ ancestor, err := d.findAncestorSpanSearch(p, mode, remoteHeight, localHeight, floor)
if err == nil {
return ancestor, nil
}
// The returned error was not nil.
// If the error returned does not reflect that a common ancestor was not found, return it.
// If the error reflects that a common ancestor was not found, continue to binary search,
// where the error value will be reassigned.
if !errors.Is(err, errNoAncestorFound) {
return 0, err
}
↗ ancestor, err = d.findAncestorBinarySearch(p, mode, remoteHeight, floor)
if err != nil {
return 0, err
}
return ancestor, nil
}
core-geth validation — +3 -27
| | | |---|---| | File | [`downloader.go`](https://github.com/etclabscore/core-geth/blob/v1.12.20/eth/downloader/downloader.go) | | Symbol | `Downloader.findAncestor` | | Ref | `v1.12.20` |--- a/core-geth/eth/downloader/downloader.go
+++ b/etc/eth/downloader/downloader_pow.go
@@ -12,45 +12,21 @@
)
mode := d.getMode()
switch mode {
- case FullSync:
+ case ethconfig.FullSync:
localHeight = d.blockchain.CurrentBlock().Number.Uint64()
- case SnapSync:
+ case ethconfig.SnapSync:
localHeight = d.blockchain.CurrentSnapBlock().Number.Uint64()
- case LightSync:
- localHeight = d.lightchain.CurrentHeader().Number.Uint64()
default:
- log.Crit("unknown sync mode", "mode", mode)
+ localHeight = d.blockchain.CurrentHeader().Number.Uint64()
}
p.log.Debug("Looking for common ancestor", "local", localHeight, "remote", remoteHeight)
// Recap floor value for binary search
maxForkAncestry := fullMaxForkAncestry
- if d.getMode() == LightSync {
- maxForkAncestry = lightMaxForkAncestry
- }
if localHeight >= maxForkAncestry {
// We're above the max reorg threshold, find the earliest fork point
floor = int64(localHeight - maxForkAncestry)
}
- // If we're doing a light sync, ensure the floor doesn't go below the CHT, as
- // all headers before that point will be missing.
- if mode == LightSync {
- // If we don't know the current CHT position, find it
- if d.genesis == 0 {
- header := d.lightchain.CurrentHeader()
- for header != nil {
- d.genesis = header.Number.Uint64()
- if floor >= int64(d.genesis)-1 {
- break
- }
- header = d.lightchain.GetHeaderByHash(header.ParentHash)
- }
- }
- // We already know the "genesis" block number, cap floor to that
- if floor < int64(d.genesis)-1 {
- floor = int64(d.genesis) - 1
- }
- }
ancestor, err := d.findAncestorSpanSearch(p, mode, remoteHeight, localHeight, floor)
if err == nil {