diff --git a/src/raft.cpp b/src/raft.cpp index d069580..ea20d6f 100644 --- a/src/raft.cpp +++ b/src/raft.cpp @@ -67,6 +67,40 @@ TRaft::TRaft(int node, const TNodeDict& nodes, const std::shared_ptr TRaft::OnRequestVote(TMessageHolder message) { + if (message->Term < State->CurrentTerm) { + auto reply = NewHoldedMessage(static_cast(EMessageType::REQUEST_VOTE_RESPONSE), sizeof(TRequestVoteResponse)); + reply->Src = Id; + reply->Dst = message->Src; + reply->Term = State->CurrentTerm; + reply->VoteGranted = false; + return std::make_unique(TResult { + .Message = reply + }); + } else if (message->Term == State->CurrentTerm) { + bool accept = false; + if (State->VotedFor == 0) { + accept = true; + } else if (State->VotedFor == message->CandidateId && message->LastLogTerm > State->LogTerm()) { + accept = true; + } else if (State->VotedFor == message->CandidateId && message->LastLogTerm == State->LogTerm() && message->LastLogIndex >= State->Log.size()) { + accept = true; + } + + auto reply = NewHoldedMessage(static_cast(EMessageType::REQUEST_VOTE_RESPONSE), sizeof(TRequestVoteResponse)); + reply->Src = Id; + reply->Dst = message->Src; + reply->Term = message->Term; + reply->VoteGranted = accept; + + return std::make_unique(TResult { + .NextState = std::make_unique(TState{ + .CurrentTerm = message->Term, + .VotedFor = message->CandidateId + }), + .Message = reply, + }); + } + return nullptr; } diff --git a/src/raft.h b/src/raft.h index fe16c2b..6893edb 100644 --- a/src/raft.h +++ b/src/raft.h @@ -33,8 +33,8 @@ class TNode: public INode { }; struct TState { - int CurrentTerm = 1; - int VotedFor = 0; + uint64_t CurrentTerm = 1; + uint32_t VotedFor = 0; std::vector> Log; int LogTerm(int index = -1) const { @@ -105,7 +105,7 @@ class TRaft { TMessageHolder CreateVote(); std::vector> CreateAppendEntries(); - int Id; + uint32_t Id; TNodeDict Nodes; std::shared_ptr TimeSource; int MinVotes;