Raft AppendEntries (Full)

hard · distributed-systems, consensus, raft

Raft AppendEntries (Full)

Implement the full Raft AppendEntries handling logic for a follower log. This version matches the Raft paper (conflicts only truncate when terms differ).

Types

type State struct {
    CurrentTerm int
    LogTerms    []int // 1-based indexing
    CommitIndex int   // 1-based
}

type AppendEntries struct {
    Term         int
    PrevLogIndex int
    PrevLogTerm  int
    Entries      []int // terms for new entries
    LeaderCommit int
}

type Response struct {
    Term       int
    Success    bool
    MatchIndex int
}

Function signature

func ApplyAppendEntries(state State, rpc AppendEntries) (State, Response)

Rules

  1. If rpc.Term < state.CurrentTerm, reject.
  2. If rpc.Term > state.CurrentTerm, update CurrentTerm.
  3. Reject if PrevLogIndex is past the end of the log, or if the term at PrevLogIndex does not match PrevLogTerm.
  4. On accept:
    • Starting at index PrevLogIndex + 1, compare incoming entries with existing log entries.
    • If an existing entry conflicts (same index, different term), delete that entry and all following entries, then append the remaining incoming entries.
    • If existing entry matches term, keep it and continue.
  5. Set CommitIndex = min(LeaderCommit, len(LogTerms)).
  6. On success, MatchIndex = PrevLogIndex + len(Entries).

Indices are 1-based. An empty log has length 0.

Example

LogTerms      = [1,1,2,2]
PrevLogIndex  = 2
PrevLogTerm   = 1
Entries       = [2,3]
LeaderCommit  = 4

Result LogTerms = [1,1,2,3]
CommitIndex     = 4

Constraints

  • 0 <= len(LogTerms) <= 100000
  • 0 <= PrevLogIndex <= len(LogTerms)
Run tests to see results
No issues detected