Merge pull request #20204 from holiman/fix_downloader_race

eth/downloader: fix data race in downloader
This commit is contained in:
Péter Szilágyi 2019-10-29 17:10:44 +02:00 committed by GitHub
commit e306304414
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1574,13 +1574,14 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error {
func (d *Downloader) processFastSyncContent(latest *types.Header) error { func (d *Downloader) processFastSyncContent(latest *types.Header) error {
// Start syncing state of the reported head block. This should get us most of // Start syncing state of the reported head block. This should get us most of
// the state of the pivot block. // the state of the pivot block.
stateSync := d.syncState(latest.Root) sync := d.syncState(latest.Root)
defer stateSync.Cancel() defer sync.Cancel()
go func() { closeOnErr := func(s *stateSync) {
if err := stateSync.Wait(); err != nil && err != errCancelStateFetch && err != errCanceled { if err := s.Wait(); err != nil && err != errCancelStateFetch && err != errCanceled {
d.queue.Close() // wake up Results d.queue.Close() // wake up Results
} }
}() }
go closeOnErr(sync)
// Figure out the ideal pivot block. Note, that this goalpost may move if the // 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. // sync takes long enough for the chain head to move significantly.
pivot := uint64(0) pivot := uint64(0)
@ -1600,12 +1601,12 @@ func (d *Downloader) processFastSyncContent(latest *types.Header) error {
if len(results) == 0 { if len(results) == 0 {
// If pivot sync is done, stop // If pivot sync is done, stop
if oldPivot == nil { if oldPivot == nil {
return stateSync.Cancel() return sync.Cancel()
} }
// If sync failed, stop // If sync failed, stop
select { select {
case <-d.cancelCh: case <-d.cancelCh:
stateSync.Cancel() sync.Cancel()
return errCanceled return errCanceled
default: default:
} }
@ -1625,28 +1626,24 @@ func (d *Downloader) processFastSyncContent(latest *types.Header) error {
} }
} }
P, beforeP, afterP := splitAroundPivot(pivot, results) P, beforeP, afterP := splitAroundPivot(pivot, results)
if err := d.commitFastSyncData(beforeP, stateSync); err != nil { if err := d.commitFastSyncData(beforeP, sync); err != nil {
return err return err
} }
if P != nil { if P != nil {
// If new pivot block found, cancel old state retrieval and restart // If new pivot block found, cancel old state retrieval and restart
if oldPivot != P { if oldPivot != P {
stateSync.Cancel() sync.Cancel()
stateSync = d.syncState(P.Header.Root) sync = d.syncState(P.Header.Root)
defer stateSync.Cancel() defer sync.Cancel()
go func() { go closeOnErr(sync)
if err := stateSync.Wait(); err != nil && err != errCancelStateFetch && err != errCanceled {
d.queue.Close() // wake up Results
}
}()
oldPivot = P oldPivot = P
} }
// Wait for completion, occasionally checking for pivot staleness // Wait for completion, occasionally checking for pivot staleness
select { select {
case <-stateSync.done: case <-sync.done:
if stateSync.err != nil { if sync.err != nil {
return stateSync.err return sync.err
} }
if err := d.commitPivotBlock(P); err != nil { if err := d.commitPivotBlock(P); err != nil {
return err return err