Patch for concurrent iterator & others (onto v1.11.6) #386
@ -23,6 +23,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
)
|
||||
@ -270,7 +271,8 @@ func (d *Downloader) findBeaconAncestor() (uint64, error) {
|
||||
// fetchBeaconHeaders feeds skeleton headers to the downloader queue for scheduling
|
||||
// until sync errors or is finished.
|
||||
func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
||||
head, tail, err := d.skeleton.Bounds()
|
||||
var head *types.Header
|
||||
_, tail, err := d.skeleton.Bounds()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -288,6 +290,47 @@ func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
||||
log.Warn("Retrieved beacon headers from local", "from", from, "count", count)
|
||||
}
|
||||
for {
|
||||
// Some beacon headers might have appeared since the last cycle, make
|
||||
// sure we're always syncing to all available ones
|
||||
head, _, err = d.skeleton.Bounds()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// If the pivot became stale (older than 2*64-8 (bit of wiggle room)),
|
||||
// move it ahead to HEAD-64
|
||||
d.pivotLock.Lock()
|
||||
if d.pivotHeader != nil {
|
||||
if head.Number.Uint64() > d.pivotHeader.Number.Uint64()+2*uint64(fsMinFullBlocks)-8 {
|
||||
// Retrieve the next pivot header, either from skeleton chain
|
||||
// or the filled chain
|
||||
number := head.Number.Uint64() - uint64(fsMinFullBlocks)
|
||||
|
||||
log.Warn("Pivot seemingly stale, moving", "old", d.pivotHeader.Number, "new", number)
|
||||
if d.pivotHeader = d.skeleton.Header(number); d.pivotHeader == nil {
|
||||
if number < tail.Number.Uint64() {
|
||||
dist := tail.Number.Uint64() - number
|
||||
if len(localHeaders) >= int(dist) {
|
||||
d.pivotHeader = localHeaders[dist-1]
|
||||
log.Warn("Retrieved pivot header from local", "number", d.pivotHeader.Number, "hash", d.pivotHeader.Hash(), "latest", head.Number, "oldest", tail.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
|
||||
// correctly with local chain.
|
||||
if d.pivotHeader == nil {
|
||||
log.Error("Pivot header is not found", "number", number)
|
||||
d.pivotLock.Unlock()
|
||||
return errNoPivotHeader
|
||||
}
|
||||
// Write out the pivot into the database so a rollback beyond
|
||||
// it will reenable snap sync and update the state root that
|
||||
// the state syncer will be downloading
|
||||
rawdb.WriteLastPivotNumber(d.stateDB, d.pivotHeader.Number.Uint64())
|
||||
}
|
||||
}
|
||||
d.pivotLock.Unlock()
|
||||
|
||||
// Retrieve a batch of headers and feed it to the header processor
|
||||
var (
|
||||
headers = make([]*types.Header, 0, maxHeadersProcess)
|
||||
@ -343,9 +386,5 @@ func (d *Downloader) fetchBeaconHeaders(from uint64) error {
|
||||
case <-d.cancelCh:
|
||||
return errCanceled
|
||||
}
|
||||
head, _, err = d.skeleton.Bounds()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user