forked from cerc-io/plugeth
Merge pull request #20204 from holiman/fix_downloader_race
eth/downloader: fix data race in downloader
This commit is contained in:
commit
e306304414
@ -1574,13 +1574,14 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error {
|
||||
func (d *Downloader) processFastSyncContent(latest *types.Header) error {
|
||||
// Start syncing state of the reported head block. This should get us most of
|
||||
// the state of the pivot block.
|
||||
stateSync := d.syncState(latest.Root)
|
||||
defer stateSync.Cancel()
|
||||
go func() {
|
||||
if err := stateSync.Wait(); err != nil && err != errCancelStateFetch && err != errCanceled {
|
||||
sync := d.syncState(latest.Root)
|
||||
defer sync.Cancel()
|
||||
closeOnErr := func(s *stateSync) {
|
||||
if err := s.Wait(); err != nil && err != errCancelStateFetch && err != errCanceled {
|
||||
d.queue.Close() // wake up Results
|
||||
}
|
||||
}()
|
||||
}
|
||||
go closeOnErr(sync)
|
||||
// Figure out the ideal pivot block. Note, that this goalpost may move if the
|
||||
// sync takes long enough for the chain head to move significantly.
|
||||
pivot := uint64(0)
|
||||
@ -1600,12 +1601,12 @@ func (d *Downloader) processFastSyncContent(latest *types.Header) error {
|
||||
if len(results) == 0 {
|
||||
// If pivot sync is done, stop
|
||||
if oldPivot == nil {
|
||||
return stateSync.Cancel()
|
||||
return sync.Cancel()
|
||||
}
|
||||
// If sync failed, stop
|
||||
select {
|
||||
case <-d.cancelCh:
|
||||
stateSync.Cancel()
|
||||
sync.Cancel()
|
||||
return errCanceled
|
||||
default:
|
||||
}
|
||||
@ -1625,28 +1626,24 @@ func (d *Downloader) processFastSyncContent(latest *types.Header) error {
|
||||
}
|
||||
}
|
||||
P, beforeP, afterP := splitAroundPivot(pivot, results)
|
||||
if err := d.commitFastSyncData(beforeP, stateSync); err != nil {
|
||||
if err := d.commitFastSyncData(beforeP, sync); err != nil {
|
||||
return err
|
||||
}
|
||||
if P != nil {
|
||||
// If new pivot block found, cancel old state retrieval and restart
|
||||
if oldPivot != P {
|
||||
stateSync.Cancel()
|
||||
sync.Cancel()
|
||||
|
||||
stateSync = d.syncState(P.Header.Root)
|
||||
defer stateSync.Cancel()
|
||||
go func() {
|
||||
if err := stateSync.Wait(); err != nil && err != errCancelStateFetch && err != errCanceled {
|
||||
d.queue.Close() // wake up Results
|
||||
}
|
||||
}()
|
||||
sync = d.syncState(P.Header.Root)
|
||||
defer sync.Cancel()
|
||||
go closeOnErr(sync)
|
||||
oldPivot = P
|
||||
}
|
||||
// Wait for completion, occasionally checking for pivot staleness
|
||||
select {
|
||||
case <-stateSync.done:
|
||||
if stateSync.err != nil {
|
||||
return stateSync.err
|
||||
case <-sync.done:
|
||||
if sync.err != nil {
|
||||
return sync.err
|
||||
}
|
||||
if err := d.commitPivotBlock(P); err != nil {
|
||||
return err
|
||||
|
Loading…
Reference in New Issue
Block a user