From c976ceb6c78d8aa3cf24647bc8455fa41ef675f2 Mon Sep 17 00:00:00 2001 From: cjen1 Date: Thu, 11 May 2023 14:58:26 +0100 Subject: [PATCH] Randomise lower bits of terms Signed-off-by: cjen1 --- raft.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/raft.go b/raft.go index d1048294..9a3608e6 100644 --- a/raft.go +++ b/raft.go @@ -838,13 +838,21 @@ func (r *raft) becomeFollower(term uint64, lead uint64) { r.logger.Infof("%x became follower at term %d", r.id, r.Term) } +func (r *raft) nextTerm() uint64 { + // Term = [epoch:48; rand:16] + var cepoch uint64 = (r.Term & 0xffff_ffff_ffff_0000) >> 16 + var tepoch uint64 = (cepoch + 1) << 16 + var trdm uint64 = uint64(globalRand.Intn(65536)) & 0xffff + return tepoch | trdm +} + func (r *raft) becomeCandidate() { // TODO(xiangli) remove the panic when the raft implementation is stable if r.state == StateLeader { panic("invalid transition [leader -> candidate]") } r.step = stepCandidate - r.reset(r.Term + 1) + r.reset(r.nextTerm()) r.tick = r.tickElection r.Vote = r.id r.state = StateCandidate @@ -943,7 +951,7 @@ func (r *raft) campaign(t CampaignType) { r.becomePreCandidate() voteMsg = pb.MsgPreVote // PreVote RPCs are sent for the next term before we've incremented r.Term. - term = r.Term + 1 + term = r.nextTerm() } else { r.becomeCandidate() voteMsg = pb.MsgVote