Commit fe60545b authored by Willem Thiart's avatar Willem Thiart
Browse files

Fix: node voting for ID 0 breaking granting logic

A bug where if a node voted for node ID 0, it would continue to grant
vote requests. This could result in candidates or leaders voting
erroneously. This regression was caused by eefa3687.
parent 3ea545fe
...@@ -394,18 +394,26 @@ fail: ...@@ -394,18 +394,26 @@ fail:
return -1; return -1;
} }
int raft_already_voted(raft_server_t* me_)
{
raft_server_private_t* me = (raft_server_private_t*)me_;
return -1 != me->voted_for;
}
static int __should_grant_vote(raft_server_private_t* me, msg_requestvote_t* vr) static int __should_grant_vote(raft_server_private_t* me, msg_requestvote_t* vr)
{ {
if (vr->term < raft_get_current_term((void*)me)) if (vr->term < raft_get_current_term((void*)me))
return 0; return 0;
/* TODO: if voted for is candiate return 1 (if below checks pass) */ /* TODO: if voted for is candiate return 1 (if below checks pass) */
/* we've already voted */ if (raft_already_voted((void*)me))
if (0 < me->voted_for)
return 0; return 0;
/* Below we check if log is more up-to-date... */
int current_idx = raft_get_current_idx((void*)me); int current_idx = raft_get_current_idx((void*)me);
/* Our log is definitely not more up-to-date if it's empty! */
if (0 == current_idx) if (0 == current_idx)
return 1; return 1;
......
...@@ -666,18 +666,20 @@ void TestRaft_server_recv_requestvote_depends_on_candidate_id( ...@@ -666,18 +666,20 @@ void TestRaft_server_recv_requestvote_depends_on_candidate_id(
/* If votedFor is null or candidateId, and candidate's log is at /* If votedFor is null or candidateId, and candidate's log is at
* least as up-to-date as local log, grant vote (5.2, 5.4) */ * least as up-to-date as local log, grant vote (5.2, 5.4) */
void TestRaft_server_dont_grant_vote_if_we_didnt_vote_for_this_candidate( void TestRaft_server_recv_requestvote_dont_grant_vote_if_we_didnt_vote_for_this_candidate(
CuTest * tc CuTest * tc
) )
{ {
void *r = raft_new(); void *r = raft_new();
raft_add_node(r, NULL, 0, 0);
raft_add_node(r, NULL, 1, 1); raft_add_node(r, NULL, 1, 1);
raft_add_node(r, NULL, 2, 0); raft_add_node(r, NULL, 2, 0);
raft_set_current_term(r, 1); raft_set_current_term(r, 1);
raft_vote(r, raft_get_node(r, 1));
msg_requestvote_t rv; /* vote for self */
memset(&rv, 0, sizeof(msg_requestvote_t)); raft_vote_for_nodeid(r, 1);
msg_requestvote_t rv = {};
rv.term = 1; rv.term = 1;
rv.candidate_id = 1; rv.candidate_id = 1;
rv.last_log_idx = 1; rv.last_log_idx = 1;
...@@ -685,6 +687,11 @@ void TestRaft_server_dont_grant_vote_if_we_didnt_vote_for_this_candidate( ...@@ -685,6 +687,11 @@ void TestRaft_server_dont_grant_vote_if_we_didnt_vote_for_this_candidate(
msg_requestvote_response_t rvr; msg_requestvote_response_t rvr;
raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr); raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr);
CuAssertTrue(tc, 0 == rvr.vote_granted); CuAssertTrue(tc, 0 == rvr.vote_granted);
/* vote for ID 0 */
raft_vote_for_nodeid(r, 0);
raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr);
CuAssertTrue(tc, 0 == rvr.vote_granted);
} }
void TestRaft_follower_becomes_follower_is_follower(CuTest * tc) void TestRaft_follower_becomes_follower_is_follower(CuTest * tc)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment