Raft Milestone: Follower RPC Handling

hard · distributed-systems, consensus, raft

Raft Milestone: Follower RPC Handling

Implement a simplified Raft follower that can handle RequestVote and AppendEntries RPCs. The follower maintains:

  • CurrentTerm
  • VotedFor (candidate ID or -1)
  • LogTerms (terms per entry, 1-based indexing)
  • CommitIndex (1-based)

You must update the follower state and return an RPC response.

Types

type State struct {
    CurrentTerm int
    VotedFor    int
    LogTerms    []int
    CommitIndex int
}

type RequestVote struct {
    Term          int
    CandidateID   int
    LastLogIndex  int
    LastLogTerm   int
}

type AppendEntries struct {
    Term         int
    LeaderID     int
    PrevLogIndex int
    PrevLogTerm  int
    Entries      []int
    LeaderCommit int
}

type RPC struct {
    Kind   string // "vote" or "append"
    Vote   RequestVote
    Append AppendEntries
}

type Response struct {
    Kind          string
    Term          int
    VoteGranted   bool
    AppendSuccess bool
    MatchIndex    int
}

Function signature

func HandleRPC(state State, rpc RPC) (State, Response)

Rules

Term handling

  • If rpc.Term > state.CurrentTerm, update CurrentTerm and set VotedFor = -1.

RequestVote Grant the vote iff:

  • rpc.Term >= state.CurrentTerm
  • state.VotedFor == -1 or state.VotedFor == rpc.CandidateID
  • Candidate log is at least as up-to-date as follower log:
    • candidateLastTerm > localLastTerm, or
    • terms equal and candidateLastIndex >= localLastIndex

If granted, set VotedFor = CandidateID.

AppendEntries Accept iff:

  • rpc.Term >= state.CurrentTerm
  • PrevLogIndex == 0, or PrevLogIndex <= len(LogTerms) and LogTerms[PrevLogIndex-1] == PrevLogTerm

On accept:

  • Truncate log to PrevLogIndex, then append Entries.
  • Set CommitIndex = min(LeaderCommit, len(LogTerms)).
  • Return AppendSuccess = true and MatchIndex = len(LogTerms).

On reject, the log must remain unchanged.

Notes

  • Indices are 1-based. If the log is empty, LastLogIndex=0, LastLogTerm=0.
Run tests to see results
No issues detected