mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
eth/downloader: retry state requests on timeout
This commit is contained in:
parent
c7e5270c70
commit
420935469d
1 changed files with 11 additions and 1 deletions
|
|
@ -40,6 +40,10 @@ type stateReq struct {
|
||||||
response [][]byte // the response. this is nil for timed-out requests.
|
response [][]byte // the response. this is nil for timed-out requests.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (req *stateReq) timedOut() bool {
|
||||||
|
return req.response == nil
|
||||||
|
}
|
||||||
|
|
||||||
type stateSyncStats struct {
|
type stateSyncStats struct {
|
||||||
done uint64 // number of entries pulled
|
done uint64 // number of entries pulled
|
||||||
pending uint64 // number of pending entries
|
pending uint64 // number of pending entries
|
||||||
|
|
@ -219,6 +223,7 @@ func (s *stateSync) loop() error {
|
||||||
return errCancelStateFetch
|
return errCancelStateFetch
|
||||||
case req := <-s.deliver:
|
case req := <-s.deliver:
|
||||||
// response or timeout
|
// response or timeout
|
||||||
|
log.Trace("Received node data response", "peer", req.peer.id, "count", len(req.items), "timeout", req.timedOut())
|
||||||
req.peer.SetNodeDataIdle(len(req.response))
|
req.peer.SetNodeDataIdle(len(req.response))
|
||||||
procStart := time.Now()
|
procStart := time.Now()
|
||||||
n, err := s.process(req)
|
n, err := s.process(req)
|
||||||
|
|
@ -226,7 +231,7 @@ func (s *stateSync) loop() error {
|
||||||
log.Warn("Node data write error", "err", err)
|
log.Warn("Node data write error", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(req.items) == 1 && req.response == nil {
|
if len(req.items) == 1 && req.timedOut() {
|
||||||
log.Warn("Node data timeout, dropping peer", "peer", req.peer.id)
|
log.Warn("Node data timeout, dropping peer", "peer", req.peer.id)
|
||||||
s.d.dropPeer(req.peer.id)
|
s.d.dropPeer(req.peer.id)
|
||||||
}
|
}
|
||||||
|
|
@ -303,6 +308,11 @@ func (s *stateSync) process(req *stateReq) (nproc int, err error) {
|
||||||
}
|
}
|
||||||
// Put unfulfilled tasks back.
|
// Put unfulfilled tasks back.
|
||||||
for hash, task := range req.tasks {
|
for hash, task := range req.tasks {
|
||||||
|
if len(req.response) > 0 || req.timedOut() {
|
||||||
|
// Ensure that the item will be retried if the response contained some data or
|
||||||
|
// timed out.
|
||||||
|
delete(task.triedPeers, req.peer.id)
|
||||||
|
}
|
||||||
if npeers := s.d.peers.Len(); len(task.triedPeers) >= npeers {
|
if npeers := s.d.peers.Len(); len(task.triedPeers) >= npeers {
|
||||||
return nproc, fmt.Errorf("state node %s failed with all peers (%d tries, %d peers)", hash.TerminalString(), len(task.triedPeers), npeers)
|
return nproc, fmt.Errorf("state node %s failed with all peers (%d tries, %d peers)", hash.TerminalString(), len(task.triedPeers), npeers)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue