|
@ -126,13 +126,6 @@ type Reactor struct { |
|
|
voteCh *p2p.Channel |
|
|
voteCh *p2p.Channel |
|
|
voteSetBitsCh *p2p.Channel |
|
|
voteSetBitsCh *p2p.Channel |
|
|
peerUpdates *p2p.PeerUpdates |
|
|
peerUpdates *p2p.PeerUpdates |
|
|
|
|
|
|
|
|
// NOTE: We need a dedicated stateCloseCh channel for signaling closure of
|
|
|
|
|
|
// the StateChannel due to the fact that the StateChannel message handler
|
|
|
|
|
|
// performs a send on the VoteSetBitsChannel. This is an antipattern, so having
|
|
|
|
|
|
// this dedicated channel,stateCloseCh, is necessary in order to avoid data races.
|
|
|
|
|
|
stateCloseCh chan struct{} |
|
|
|
|
|
closeCh chan struct{} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// NewReactor returns a reference to a new consensus reactor, which implements
|
|
|
// NewReactor returns a reference to a new consensus reactor, which implements
|
|
@ -162,8 +155,6 @@ func NewReactor( |
|
|
voteCh: voteCh, |
|
|
voteCh: voteCh, |
|
|
voteSetBitsCh: voteSetBitsCh, |
|
|
voteSetBitsCh: voteSetBitsCh, |
|
|
peerUpdates: peerUpdates, |
|
|
peerUpdates: peerUpdates, |
|
|
stateCloseCh: make(chan struct{}), |
|
|
|
|
|
closeCh: make(chan struct{}), |
|
|
|
|
|
} |
|
|
} |
|
|
r.BaseService = *service.NewBaseService(logger, "Consensus", r) |
|
|
r.BaseService = *service.NewBaseService(logger, "Consensus", r) |
|
|
|
|
|
|
|
@ -230,14 +221,6 @@ func (r *Reactor) OnStop() { |
|
|
} |
|
|
} |
|
|
r.mtx.Unlock() |
|
|
r.mtx.Unlock() |
|
|
|
|
|
|
|
|
// Close the StateChannel goroutine separately since it uses its own channel
|
|
|
|
|
|
// to signal closure.
|
|
|
|
|
|
close(r.stateCloseCh) |
|
|
|
|
|
|
|
|
|
|
|
// Close closeCh to signal to all spawned goroutines to gracefully exit. All
|
|
|
|
|
|
// p2p Channels should execute Close().
|
|
|
|
|
|
close(r.closeCh) |
|
|
|
|
|
|
|
|
|
|
|
<-r.peerUpdates.Done() |
|
|
<-r.peerUpdates.Done() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -993,8 +976,7 @@ func (r *Reactor) processPeerUpdate(ctx context.Context, peerUpdate p2p.PeerUpda |
|
|
case p2p.PeerStatusUp: |
|
|
case p2p.PeerStatusUp: |
|
|
// Do not allow starting new broadcasting goroutines after reactor shutdown
|
|
|
// Do not allow starting new broadcasting goroutines after reactor shutdown
|
|
|
// has been initiated. This can happen after we've manually closed all
|
|
|
// has been initiated. This can happen after we've manually closed all
|
|
|
// peer goroutines and closed r.closeCh, but the router still sends in-flight
|
|
|
|
|
|
// peer updates.
|
|
|
|
|
|
|
|
|
// peer goroutines, but the router still sends in-flight peer updates.
|
|
|
if !r.IsRunning() { |
|
|
if !r.IsRunning() { |
|
|
return |
|
|
return |
|
|
} |
|
|
} |
|
@ -1337,6 +1319,7 @@ func (r *Reactor) processStateCh(ctx context.Context) { |
|
|
for { |
|
|
for { |
|
|
select { |
|
|
select { |
|
|
case <-ctx.Done(): |
|
|
case <-ctx.Done(): |
|
|
|
|
|
r.logger.Debug("stopped listening on StateChannel; closing...") |
|
|
return |
|
|
return |
|
|
case envelope := <-r.stateCh.In: |
|
|
case envelope := <-r.stateCh.In: |
|
|
if err := r.handleMessage(r.stateCh.ID, envelope); err != nil { |
|
|
if err := r.handleMessage(r.stateCh.ID, envelope); err != nil { |
|
@ -1346,10 +1329,6 @@ func (r *Reactor) processStateCh(ctx context.Context) { |
|
|
Err: err, |
|
|
Err: err, |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
case <-r.stateCloseCh: |
|
|
|
|
|
r.logger.Debug("stopped listening on StateChannel; closing...") |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -1363,6 +1342,7 @@ func (r *Reactor) processDataCh(ctx context.Context) { |
|
|
for { |
|
|
for { |
|
|
select { |
|
|
select { |
|
|
case <-ctx.Done(): |
|
|
case <-ctx.Done(): |
|
|
|
|
|
r.logger.Debug("stopped listening on DataChannel; closing...") |
|
|
return |
|
|
return |
|
|
case envelope := <-r.dataCh.In: |
|
|
case envelope := <-r.dataCh.In: |
|
|
if err := r.handleMessage(r.dataCh.ID, envelope); err != nil { |
|
|
if err := r.handleMessage(r.dataCh.ID, envelope); err != nil { |
|
@ -1372,10 +1352,6 @@ func (r *Reactor) processDataCh(ctx context.Context) { |
|
|
Err: err, |
|
|
Err: err, |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
case <-r.closeCh: |
|
|
|
|
|
r.logger.Debug("stopped listening on DataChannel; closing...") |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -1389,6 +1365,7 @@ func (r *Reactor) processVoteCh(ctx context.Context) { |
|
|
for { |
|
|
for { |
|
|
select { |
|
|
select { |
|
|
case <-ctx.Done(): |
|
|
case <-ctx.Done(): |
|
|
|
|
|
r.logger.Debug("stopped listening on VoteChannel; closing...") |
|
|
return |
|
|
return |
|
|
case envelope := <-r.voteCh.In: |
|
|
case envelope := <-r.voteCh.In: |
|
|
if err := r.handleMessage(r.voteCh.ID, envelope); err != nil { |
|
|
if err := r.handleMessage(r.voteCh.ID, envelope); err != nil { |
|
@ -1398,10 +1375,6 @@ func (r *Reactor) processVoteCh(ctx context.Context) { |
|
|
Err: err, |
|
|
Err: err, |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
case <-r.closeCh: |
|
|
|
|
|
r.logger.Debug("stopped listening on VoteChannel; closing...") |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -1415,6 +1388,7 @@ func (r *Reactor) processVoteSetBitsCh(ctx context.Context) { |
|
|
for { |
|
|
for { |
|
|
select { |
|
|
select { |
|
|
case <-ctx.Done(): |
|
|
case <-ctx.Done(): |
|
|
|
|
|
r.logger.Debug("stopped listening on VoteSetBitsChannel; closing...") |
|
|
return |
|
|
return |
|
|
case envelope := <-r.voteSetBitsCh.In: |
|
|
case envelope := <-r.voteSetBitsCh.In: |
|
|
if err := r.handleMessage(r.voteSetBitsCh.ID, envelope); err != nil { |
|
|
if err := r.handleMessage(r.voteSetBitsCh.ID, envelope); err != nil { |
|
@ -1424,10 +1398,6 @@ func (r *Reactor) processVoteSetBitsCh(ctx context.Context) { |
|
|
Err: err, |
|
|
Err: err, |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
case <-r.closeCh: |
|
|
|
|
|
r.logger.Debug("stopped listening on VoteSetBitsChannel; closing...") |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -1441,13 +1411,10 @@ func (r *Reactor) processPeerUpdates(ctx context.Context) { |
|
|
for { |
|
|
for { |
|
|
select { |
|
|
select { |
|
|
case <-ctx.Done(): |
|
|
case <-ctx.Done(): |
|
|
|
|
|
r.logger.Debug("stopped listening on peer updates channel; closing...") |
|
|
return |
|
|
return |
|
|
case peerUpdate := <-r.peerUpdates.Updates(): |
|
|
case peerUpdate := <-r.peerUpdates.Updates(): |
|
|
r.processPeerUpdate(ctx, peerUpdate) |
|
|
r.processPeerUpdate(ctx, peerUpdate) |
|
|
|
|
|
|
|
|
case <-r.closeCh: |
|
|
|
|
|
r.logger.Debug("stopped listening on peer updates channel; closing...") |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -1486,8 +1453,6 @@ func (r *Reactor) peerStatsRoutine(ctx context.Context) { |
|
|
} |
|
|
} |
|
|
case <-ctx.Done(): |
|
|
case <-ctx.Done(): |
|
|
return |
|
|
return |
|
|
case <-r.closeCh: |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|