eth/downloader: resolve local header by hash for beacon sync (#24691)
* eth/downlaoder: resolve local header by hash for beacon sync * eth/downloader: fix error message * eth/downloader: cap the reverse header resolving * eth/downloader: re-enable tests * eth/downloader: add warning logs
This commit is contained in:
@ -159,9 +159,6 @@ type LightChain interface {
|
||||
// GetHeaderByHash retrieves a header from the local chain.
|
||||
GetHeaderByHash(common.Hash) *types.Header
|
||||
|
||||
// GetHeaderByNumber retrieves a block header from the local chain by number.
|
||||
GetHeaderByNumber(number uint64) *types.Header
|
||||
|
||||
// CurrentHeader retrieves the head header from the local chain.
|
||||
CurrentHeader() *types.Header
|
||||
|
||||
@ -486,7 +483,15 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td, ttd *
|
||||
// Retrieve the pivot header from the skeleton chain segment but
|
||||
// fallback to local chain if it's not found in skeleton space.
|
||||
if pivot = d.skeleton.Header(number); pivot == nil {
|
||||
pivot = d.lightchain.GetHeaderByNumber(number)
|
||||
_, oldest, _ := d.skeleton.Bounds() // error is already checked
|
||||
if number < oldest.Number.Uint64() {
|
||||
count := int(oldest.Number.Uint64() - number) // it's capped by fsMinFullBlocks
|
||||
headers := d.readHeaderRange(oldest, count)
|
||||
if len(headers) == count {
|
||||
pivot = headers[len(headers)-1]
|
||||
log.Warn("Retrieved pivot header from local", "number", pivot.Number, "hash", pivot.Hash(), "latest", latest.Number, "oldest", oldest.Number)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Print an error log and return directly in case the pivot header
|
||||
// is still not found. It means the skeleton chain is not linked
|
||||
@ -1772,3 +1777,25 @@ func (d *Downloader) DeliverSnapPacket(peer *snap.Peer, packet snap.Packet) erro
|
||||
return fmt.Errorf("unexpected snap packet type: %T", packet)
|
||||
}
|
||||
}
|
||||
|
||||
// readHeaderRange returns a list of headers, using the given last header as the base,
|
||||
// and going backwards towards genesis. This method assumes that the caller already has
|
||||
// placed a reasonable cap on count.
|
||||
func (d *Downloader) readHeaderRange(last *types.Header, count int) []*types.Header {
|
||||
var (
|
||||
current = last
|
||||
headers []*types.Header
|
||||
)
|
||||
for {
|
||||
parent := d.lightchain.GetHeaderByHash(current.ParentHash)
|
||||
if parent == nil {
|
||||
break // The chain is not continuous, or the chain is exhausted
|
||||
}
|
||||
headers = append(headers, parent)
|
||||
if len(headers) >= count {
|
||||
break
|
||||
}
|
||||
current = parent
|
||||
}
|
||||
return headers
|
||||
}
|
||||
|
Reference in New Issue
Block a user