eth/downloader: fix data race in downloader
This commit is contained in:
		
							parent
							
								
									db79143a13
								
							
						
					
					
						commit
						3eca7b5d27
					
				| @ -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 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user