consensus: change lock handling in reactor for RoundState (#7994)

This change updates the lock handling in the consensus reactor. The consensus reactor now periodically fetches the RoundState and the gossip routines operate on this fetched copy instead of fetching the latest copy in each iteration of the gossip routine.
This commit is contained in:
William Banfield
2022-03-09 17:38:57 -05:00
committed by GitHub
parent fd3bfb38e7
commit 4b5472c387

View File

@@ -46,6 +46,7 @@ type Reactor struct {
mtx tmsync.RWMutex
waitSync bool
eventBus *types.EventBus
rs *cstypes.RoundState
Metrics *Metrics
}
@@ -58,6 +59,7 @@ func NewReactor(consensusState *State, waitSync bool, options ...ReactorOption)
conR := &Reactor{
conS: consensusState,
waitSync: waitSync,
rs: consensusState.GetRoundState(),
Metrics: NopMetrics(),
}
conR.BaseReactor = *p2p.NewBaseReactor("Consensus", conR)
@@ -78,6 +80,7 @@ func (conR *Reactor) OnStart() error {
go conR.peerStatsRoutine()
conR.subscribeToBroadcastEvents()
go conR.updateRoundStateRoutine()
if !conR.WaitSync() {
err := conR.conS.Start()
@@ -482,11 +485,31 @@ func makeRoundStepMessage(rs *cstypes.RoundState) (nrsMsg *NewRoundStepMessage)
}
func (conR *Reactor) sendNewRoundStepMessage(peer p2p.Peer) {
rs := conR.conS.GetRoundState()
rs := conR.getRoundState()
nrsMsg := makeRoundStepMessage(rs)
peer.Send(StateChannel, MustEncode(nrsMsg))
}
func (conR *Reactor) updateRoundStateRoutine() {
t := time.NewTicker(100 * time.Microsecond)
defer t.Stop()
for range t.C {
if !conR.IsRunning() {
return
}
rs := conR.conS.GetRoundState()
conR.mtx.Lock()
conR.rs = rs
conR.mtx.Unlock()
}
}
func (conR *Reactor) getRoundState() *cstypes.RoundState {
conR.mtx.RLock()
defer conR.mtx.RUnlock()
return conR.rs
}
func (conR *Reactor) gossipDataRoutine(peer p2p.Peer, ps *PeerState) {
logger := conR.Logger.With("peer", peer)
@@ -496,7 +519,7 @@ OUTER_LOOP:
if !peer.IsRunning() || !conR.IsRunning() {
return
}
rs := conR.conS.GetRoundState()
rs := conR.getRoundState()
prs := ps.GetRoundState()
// Send proposal Block parts?
@@ -639,7 +662,7 @@ OUTER_LOOP:
if !peer.IsRunning() || !conR.IsRunning() {
return
}
rs := conR.conS.GetRoundState()
rs := conR.getRoundState()
prs := ps.GetRoundState()
switch sleeping {
@@ -771,7 +794,7 @@ OUTER_LOOP:
// Maybe send Height/Round/Prevotes
{
rs := conR.conS.GetRoundState()
rs := conR.getRoundState()
prs := ps.GetRoundState()
if rs.Height == prs.Height {
if maj23, ok := rs.Votes.Prevotes(prs.Round).TwoThirdsMajority(); ok {
@@ -788,7 +811,7 @@ OUTER_LOOP:
// Maybe send Height/Round/Precommits
{
rs := conR.conS.GetRoundState()
rs := conR.getRoundState()
prs := ps.GetRoundState()
if rs.Height == prs.Height {
if maj23, ok := rs.Votes.Precommits(prs.Round).TwoThirdsMajority(); ok {
@@ -805,7 +828,7 @@ OUTER_LOOP:
// Maybe send Height/Round/ProposalPOL
{
rs := conR.conS.GetRoundState()
rs := conR.getRoundState()
prs := ps.GetRoundState()
if rs.Height == prs.Height && prs.ProposalPOLRound >= 0 {
if maj23, ok := rs.Votes.Prevotes(prs.ProposalPOLRound).TwoThirdsMajority(); ok {