diff --git a/eth/downloader/statesync.go b/eth/downloader/statesync.go index f875b3a84c..84317b2dc3 100644 --- a/eth/downloader/statesync.go +++ b/eth/downloader/statesync.go @@ -150,6 +150,7 @@ func (d *Downloader) runStateSync(s *stateSync) *stateSync { req.timer.Stop() req.response = pack.(*statePack).states + log.Debug("Received node data", "len", len(req.response)) finished = append(finished, req) delete(active, pack.PeerId()) diff --git a/eth/handler.go b/eth/handler.go index d2355a8768..78522dc93c 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -601,6 +601,12 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { bytes += len(entry) } } + log.Debug("Sending node data", "len", len(data)) + if len(data) == 0 { + // in this case, sending node data with len=0 may cause the requesting peer retrieve this GetNodeDataMsg + // again and again, and can block block synchronise. + log.Warn("Sending node data is invalid", "len", len(data)) + } return p.SendNodeData(data) case p.version >= eth63 && msg.Code == NodeDataMsg: @@ -609,6 +615,15 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { if err := msg.Decode(&data); err != nil { return errResp(ErrDecode, "msg %v: %v", msg, err) } + // to make peer compatible with old peer sending zero node data, just avoid deliver this node data. + // Why: + // deliver zero node data will cause statesync failing before other fetchers which interrupts all other + // fetchers, then all fetchers including statesync fetcher will run again and again until blocks from other + // peers were inserted + if len(data) == 0 { + log.Warn("No need to deliver zero len data") + return nil + } // Deliver all to the downloader if err := pm.downloader.DeliverNodeData(p.id, data); err != nil { log.Debug("Failed to deliver node state data", "err", err)