|
|
|
@ -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 |
|
|
|
|
} |
|
|
|
|