diff --git a/internal/consensus/reactor.go b/internal/consensus/reactor.go index 3ea3531f6..a842f1a1f 100644 --- a/internal/consensus/reactor.go +++ b/internal/consensus/reactor.go @@ -229,23 +229,6 @@ func (r *Reactor) OnStop() { r.state.Wait() } - // Close closeCh to signal to all spawned goroutines to gracefully exit. All - // p2p Channels should execute Close(). - close(r.closeCh) - - // Close the StateChannel goroutine separately since it uses its own channel - // to signal closure. - close(r.stateCloseCh) - <-r.stateCh.Done() - - // Wait for all p2p Channels to be closed before returning. This ensures we - // can easily reason about synchronization of all p2p Channels and ensure no - // panics will occur. - <-r.voteSetBitsCh.Done() - <-r.dataCh.Done() - <-r.voteCh.Done() - <-r.peerUpdates.Done() - peers := make(map[types.NodeID]*PeerState) r.mtx.Lock() @@ -266,6 +249,23 @@ func (r *Reactor) OnStop() { for _, ps := range peers { ps.broadcastWG.Wait() } + + // Close the StateChannel goroutine separately since it uses its own channel + // to signal closure. + close(r.stateCloseCh) + <-r.stateCh.Done() + + // Close closeCh to signal to all spawned goroutines to gracefully exit. All + // p2p Channels should execute Close(). + close(r.closeCh) + + // Wait for all p2p Channels to be closed before returning. This ensures we + // can easily reason about synchronization of all p2p Channels and ensure no + // panics will occur. + <-r.voteSetBitsCh.Done() + <-r.dataCh.Done() + <-r.voteCh.Done() + <-r.peerUpdates.Done() } // SetEventBus sets the reactor's event bus.