diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index a79321574d..6d5d159631 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -122,7 +122,7 @@ func (dl *downloadTester) dropPeer(id string) { type downloadTesterPeer struct { dl *downloadTester withholdBodies map[common.Hash]struct{} - corruptBodies bool + corruptBodies bool // if set, the peer serves incorrect blocks id string chain *core.BlockChain diff --git a/eth/downloader/fetchers_concurrent.go b/eth/downloader/fetchers_concurrent.go index e01b8df048..51bf3404bd 100644 --- a/eth/downloader/fetchers_concurrent.go +++ b/eth/downloader/fetchers_concurrent.go @@ -339,9 +339,15 @@ func (d *Downloader) concurrentFetch(queue typedQueue) error { if !errors.Is(err, errStaleDelivery) { queue.updateCapacity(peer, accepted, res.Time) } - res.Done <- errorOfRequest(err) + res.Done <- validityErrorOfRequest(err) res.Req.Close() + if errors.Is(err, errInvalidChain) { + // errInvalidChain is the signal that processing of items failed internally, + // even though the items were validly encoded. + // + // This can be due to invalid blocks, or a database error. + // The sync cycle should be aborted for such errors, so we return it here. return err } @@ -354,7 +360,8 @@ func (d *Downloader) concurrentFetch(queue typedQueue) error { } } -func errorOfRequest(err error) error { +// validityErrorOfRequest returns err if it is related to block validity, and nil otherwise. +func validityErrorOfRequest(err error) error { if errors.Is(err, errInvalidBody) || errors.Is(err, errInvalidReceipt) { return err }