// lesson: leader-election
Leader Election
When a candidate starts an election it sends a RequestVote RPC to every other server in parallel. Figure 2 gives the arguments:
// RequestVote RPC (Figure 2)
// Arguments:
// term candidate's term
// candidateId candidate requesting vote
// lastLogIndex index of candidate's last log entry (§5.4)
// lastLogTerm term of candidate's last log entry (§5.4)
// Results:
// term currentTerm, for candidate to update itself
// voteGranted true means candidate received vote
The receiver's side is what you implement in this challenge. Figure 2's "RequestVote RPC, Receiver implementation" is only two lines, but every clause matters:
- Reply false if
term < currentTerm(§5.1). - If
votedForis null orcandidateId, and candidate's log is at least as up-to-date as receiver's log, grant vote (§5.2, §5.4).
At most one vote per term
votedFor records who this server voted for in the current term. Each server
gives out at most one vote per term, first-come-first-served, which is what
makes two leaders in one term impossible: two candidates would each need a
majority, and majorities overlap. Note the "or candidateId" clause — if the
same candidate asks twice (a retransmitted RPC), the vote is granted again.
Granting a vote is idempotent, not a second vote.
Whenever currentTerm changes (rule "All Servers" from lesson 1), votedFor
resets to none: a new term is a fresh ballot.
In the paper currentTerm, votedFor, and the log are persistent state —
a real server must fsync them before answering an RPC, or a reboot could let it
vote twice in one term. Our in-memory structs stand in for that durable state.
The up-to-dateness check (§5.4.1)
The log check is Raft's election-time safety filter: a candidate cannot win unless its log is at least as up-to-date as a majority of voters, which guarantees the winner already holds every committed entry (the Leader Completeness Property). "Up-to-date" is defined precisely:
If the logs have last entries with different terms, then the log with the later term is more up-to-date. If the logs end with the same term, then whichever log is longer is more up-to-date.
Compare last log term first, then last log index. A short log ending in a high term beats a long log ending in a low term.
Indexing convention
The paper numbers log entries from 1. We keep that: Raft index i lives at
Log[i-1], the last index is len(Log), and an empty log has last index 0 and
last term 0. This convention holds for the rest of the course.
› Handle RequestVote
30 ptsImplement HandleRequestVote exactly per Figure 2. It mutates the receiver's
state in place and returns the reply.
Order of operations:
- If
args.Term > s.CurrentTerm: setCurrentTerm = args.Term, becomeFollower, resetVotedFor = -1. This happens even if the vote is then refused for log reasons. - Reply false if
args.Term < s.CurrentTerm. The reply'sTermis always the (possibly just-updated)CurrentTerm. - Grant the vote only if
VotedForis-1or alreadyargs.CandidateID, and the candidate's log is at least as up-to-date as ours: compareargs.LastLogTermagainst our last log term, breaking ties withargs.LastLogIndexagainst our last log index (candidate wins ties). - On granting, record
VotedFor = args.CandidateID.
HandleRequestVote never modifies the log.
Log in to submit a solution and earn points.