diff --git a/hare3/hare.go b/hare3/hare.go index 01f0cfd0925..74250712f77 100644 --- a/hare3/hare.go +++ b/hare3/hare.go @@ -363,27 +363,35 @@ func (h *Hare) run(layer types.LayerID, beacon types.Beacon, proto *protocol) er activeLatency.Observe(time.Since(start).Seconds()) h.tracer.OnActive(vrf) - walltime := h.nodeclock.LayerToTime(layer).Add(h.config.PreroundDelay) + var ( + walltime = h.nodeclock.LayerToTime(layer).Add(h.config.PreroundDelay) + timer *clock.Timer + ) if vrf != nil { h.log.Debug("active in preround", zap.Uint32("lid", layer.Uint32())) // initial set is not needed if node is not active in preround + timer = h.wallclock.Timer(h.wallclock.Until(walltime)) select { - case <-h.wallclock.After(h.wallclock.Until(walltime)): + case <-timer.C: case <-h.ctx.Done(): return h.ctx.Err() } start := time.Now() proto.OnInitial(h.proposals(layer, beacon)) proposalsLatency.Observe(time.Since(start).Seconds()) + } else { + timer = h.wallclock.Timer(0) } + defer timer.Stop() if err := h.onOutput(layer, current, proto.Next(vrf != nil), vrf); err != nil { return err } - walltime = walltime.Add(h.config.RoundDuration) result := false for { + walltime = walltime.Add(h.config.RoundDuration) + timer.Reset(h.wallclock.Until(walltime)) select { - case <-h.wallclock.After(h.wallclock.Until(walltime)): + case <-timer.C: h.log.Debug("execute round", zap.Uint32("lid", layer.Uint32()), zap.Uint8("iter", proto.Iter), zap.Stringer("round", proto.Round), @@ -414,7 +422,6 @@ func (h *Hare) run(layer types.LayerID, beacon types.Beacon, proto *protocol) er return fmt.Errorf("hare failed to reach consensus in %d iterations", h.config.IterationsLimit) } - walltime = walltime.Add(h.config.RoundDuration) case <-h.ctx.Done(): return nil }