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 { | ||||
| 	// 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