fix(raft): harden election transitions#2
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d0526314e9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let initial_contact = if leader.is_some() { | ||
| core.ticks | ||
| } else { | ||
| core.ticks.saturating_sub(core.config.election_timeout.0) | ||
| }; |
There was a problem hiding this comment.
Avoid marking leader contact before AppendEntries is validated
Follower::new now treats any transition with leader: Some(_) as a fresh leader heartbeat by setting last_contact_tick = core.ticks. In this patch, candidates/leaders step down on a higher-term AppendRequest before that request is processed for log consistency, so an unverified/stale Append can immediately activate recently_heard_from_leader() and cause subsequent VoteRequest/PreVoteRequest messages to be rejected without term update for up to an election timeout. This can delay or repeatedly stall leadership elections under stale or removed senders that emit higher-term appends.
Useful? React with 👍 / 👎.
d052631 to
d2ce1a7
Compare
3a9a6bf to
b2fb2de
Compare
d2ce1a7 to
aac29dc
Compare
aac29dc to
c64e06b
Compare
Pull Request
Summary
What: Harden Raft election transitions around leader contact, learner/non-voter elections, disruptive votes, and stale PreVote responses.
Why: The dissertation's safety arguments depend on only eligible voters participating in quorums and on followers not inflating term or granting votes while an active leader is maintaining heartbeats.
Lines added: +160
Thesis Cross-Reference
Candidate step-down on legitimate leader contact:
basicraft/consensus.tex#L194-L200
Key phrase: "returns to follower state".
Context: a candidate receiving same-or-higher-term AppendEntries recognizes that leader, but lower-term AppendEntries must be rejected.
RequestVote log freshness:
basicraft/consensus.tex#L500-L512
Key phrase: "denies its vote".
Context: voting is restricted to candidates whose logs are at least as up-to-date as the voter.
Non-voting members:
membership/availability.tex#L82-L87
Key phrase: "not yet counted towards majorities".
Context: learners receive replication but must not contribute votes or commitment quorum.
Removed/non-member election self-vote:
membership/availability.tex#L228-L238
Key phrase: "does not count its own vote".
Context: a server outside its latest config may start an election, but its own vote only counts if it is in that config.
Disruptive vote guard:
membership/availability.tex#L315-L323
Key phrase: "does not update its term".
Context: recent leader heartbeats make vote requests disruptive; the server may deny/drop/delay without adopting a higher term.
Test Plan
cargo test -p cloud9-raftTests Added
Notes for Reviewers
The subtle case is the candidate step-down path: returning follower state is correct, but sending a successful AppendResponse before the AppendEntries consistency check is not.