Repository navigation
Fix RequestVote freshness after full log compaction - #668
Merged
greensky00 merged 1 commit intoOct 8, 2026
Merged
Conversation
Contributor
|
@thweetkomputer |
greensky00
approved these changes
Oct 8, 2026
greensky00
approved these changes
Oct 8, 2026
greensky00
added a commit
to greensky00/NuRaft
that referenced
this pull request
Oct 8, 2026
* Replace the four vote log freshness tests with a single test. * Only the fully compacted case reproduces the bug fixed in eBay#668; the other three pass with or without the fix. * Drop unused setup: extra log appends, the stale follower log, and unrelated raft params. * Keep three vote checks: reject a shorter log, reject a lower term, and grant an equally up-to-date log.
greensky00
added a commit
that referenced
this pull request
Oct 8, 2026
* Replace the four vote log freshness tests with a single test. * Only the fully compacted case reproduces the bug fixed in #668; the other three pass with or without the fix. * Drop unused setup: extra log appends, the stale follower log, and unrelated raft params. * Keep three vote checks: reject a shorter log, reject a lower term, and grant an equally up-to-date log.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When a follower compacts its entire log into a snapshot,
handle_vote_req()can grant a vote to a candidate whose log is older than the follower's committed snapshot. Thelog_store::last_entry()contract requires an empty store to return a dummy entry with term zero, but the vote freshness comparison treats that dummy term as the follower's last log term.For example, a follower with snapshot
(last_log_term=1, last_log_idx=5)and no retained entries compares itself as(0, 5). It then accepts a candidate advertising(1, 3), even though that candidate lacks committed entries. This can allow an outdated candidate to become leader, violating leader completeness.Use
term_for_log(next_slot() - 1)for the receiver's last log term, matching the existing outgoing RequestVote path. This helper reads the retained log when present and otherwise reads the snapshot boundary. Use the same resolved term and index in the vote diagnostic.Four independent tests in
leader_election_testcover retained logs, fully compacted logs, reconstruction of the Raft server with the same snapshot/state/log store, and logs appended after the snapshot. Each checks rejection of older candidates, acceptance of equally or more up-to-date candidates, and the persistedvoted_forstate. They use NuRaft's existing fake network, state machine and in-memory log store. The reconstruction test does not simulate a disk or process restart.Validation on Linux arm64 with Clang 18, Debug, and
ENABLE_RAFT_STATS=1:leader_election_test13/13,snapshot_test8/8,learner_new_joiner_test4/4, andfailure_test7/7 pass with--abort-on-failure.ADDRESS_SANITIZER=1and no sanitizer findings.runtests.shrun stops at the existingfull consensus testassertion inraft_server_test.cxx:1898(expected committed index 15, actual 5). An isolated build of unmodified upstream0b01b185b46b8e482f6c384b636c35605121a41ereproduces the same failure with the same build settings. The full-consensus implementation and that test are unchanged.Additional suites run separately after the early exit:
timer_test3/3,asio_service_test37/37,req_resp_meta_test7/7,priority_based_election_test3/3,stream_transport_layer_test5/5, andraft_stream_mode_test6/6 pass. The remainingextended append_entries API testalso passes.custom_quorum_testinitially stops atstop, term increment, restart test(custom_quorum_test.cxx:525), where S2 is expected to become leader within 500 ms. The log shows S2 becoming leader approximately 50 ms after that assertion. The same case passes when run individually on both unmodified upstream and this branch. Consequently, these results do not claim a clean full-suite run.