eth/downloader: termiante state sync cleanly

This commit is contained in:
Péter Szilágyi 2018-02-01 20:37:03 +02:00
parent 4aeed0753e
commit 92716ddb4b
No known key found for this signature in database
GPG key ID: E9AE538CEDF8293D
2 changed files with 18 additions and 5 deletions

View file

@ -1349,8 +1349,8 @@ func (d *Downloader) importBlockResults(results []*fetchResult) error {
// processFastSyncContent takes fetch results from the queue and writes them to the // processFastSyncContent takes fetch results from the queue and writes them to the
// database. It also controls the synchronisation of state nodes of the pivot block. // database. It also controls the synchronisation of state nodes of the pivot block.
func (d *Downloader) processFastSyncContent(latest *types.Header) error { func (d *Downloader) processFastSyncContent(latest *types.Header) error {
// Start syncing state of the reported head block. // Start syncing state of the reported head block. This should get us most of
// This should get us most of the state of the pivot block. // the state of the pivot block.
stateSync := d.syncState(latest.Root) stateSync := d.syncState(latest.Root)
defer stateSync.Cancel() defer stateSync.Cancel()
go func() { go func() {
@ -1372,10 +1372,19 @@ func (d *Downloader) processFastSyncContent(latest *types.Header) error {
) )
for { for {
// Wait for the next batch of downloaded data to be available, and if the pivot // Wait for the next batch of downloaded data to be available, and if the pivot
// block became stale, move the goalpost. // block became stale, move the goalpost
results := d.queue.Results(oldPivot == nil) // Block if we're not monitoring pivot staleness results := d.queue.Results(oldPivot == nil) // Block if we're not monitoring pivot staleness
if len(results) == 0 && oldPivot == nil { if len(results) == 0 {
return stateSync.Cancel() // If pivot sync is done, stop
if oldPivot == nil {
return stateSync.Cancel()
}
// If sync failed, stop
select {
case <-d.cancelCh:
return stateSync.Cancel()
default:
}
} }
if d.chainInsertHook != nil { if d.chainInsertHook != nil {
d.chainInsertHook(results) d.chainInsertHook(results)

View file

@ -293,6 +293,9 @@ func (s *stateSync) loop() error {
case <-s.cancel: case <-s.cancel:
return errCancelStateFetch return errCancelStateFetch
case <-s.d.cancelCh:
return errCancelStateFetch
case req := <-s.deliver: case req := <-s.deliver:
// Response, disconnect or timeout triggered, drop the peer if stalling // Response, disconnect or timeout triggered, drop the peer if stalling
log.Trace("Received node data response", "peer", req.peer.id, "count", len(req.response), "dropped", req.dropped, "timeout", !req.dropped && req.timedOut()) log.Trace("Received node data response", "peer", req.peer.id, "count", len(req.response), "dropped", req.dropped, "timeout", !req.dropped && req.timedOut())
@ -347,6 +350,7 @@ func (s *stateSync) assignTasks() {
case s.d.trackStateReq <- req: case s.d.trackStateReq <- req:
req.peer.FetchNodeData(req.items) req.peer.FetchNodeData(req.items)
case <-s.cancel: case <-s.cancel:
case <-s.d.cancelCh:
} }
} }
} }