From 4b5472c3873aa1cce784ee87822a287dd9320c15 Mon Sep 17 00:00:00 2001 From: William Banfield <4561443+williambanfield@users.noreply.github.com> Date: Wed, 9 Mar 2022 17:38:57 -0500 Subject: [PATCH] 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. --- consensus/reactor.go | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/consensus/reactor.go b/consensus/reactor.go index 0a7c590be..73f190394 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -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 {