From 87a2c3600b946835e77e4d18535fc1ad7e6c7141 Mon Sep 17 00:00:00 2001 From: "pip.zhang" Date: Mon, 13 Jan 2020 16:38:14 +0800 Subject: [PATCH] eth/downloader: avoid node data with zero length 1.sending nodedata with zero length may cause the requesting peer retrieve this GetNodeDataMsg again and again, and can block block synchronise. Warn this case in log for attention 2.to handle this case at client peer just avoid deliver such node data Depends-On: N/A --- eth/downloader/statesync.go | 1 + eth/handler.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+) 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)