forked from lei.chen/myxce
feat(raft-commit-safety): (lastLogTerm,lastLogIndex) vote+prevote freshness (tasks 1.3, 4.1-4.2, 5.1-5.2, 6.2)
logOk (raft.tla:285, closes G6): local_last_log_term = log_len>0 ? on_get_entry_term(log_len):0; logOk = cand_last_log_term > local || (== && cand_last_log_index >= log_len). Lexicographic: term dominates, tie decided by index. Shared raft_log_ok helper. Vote (4.2): logOk deny inserted after stale-term/UpdateTerm/role-gate/one-vote-per-term and BEFORE on_vote_eligible (denies even when the app gate would grant); persist-before-grant intact. PreVote (5.2): identical logOk, fully side-effect-free (no term/vote/role/commit mutation, no on_persist). Signatures extended (1.3) on raft_on_vote_request/pre_vote_request; all 39 lib call sites + sim routing updated; sim captures the candidate's send-time last-log tuple (raft_sim_rpc_t). Empty-log call sites pass (0,0) → logOk true → existing outcomes preserved. 9 freshness tests. NOTE: controller cluster.c vote callers still use the old signatures and will NOT compile — an accepted, design-documented revalidation trigger; the controller adapter plumbing is owned by the downstream ha-term-safety spec (to be implemented next). Library suite ASAN green (239 tests).
This commit is contained in:
parent
195f660f9a
commit
56485e2fa3
5 changed files with 449 additions and 62 deletions
|
|
@ -53,6 +53,14 @@ static int sim_send_vote_request(void *ctx, int peer_idx, uint64_t term)
|
|||
rpc->src = node->idx;
|
||||
rpc->dst = peer_idx;
|
||||
rpc->term = term;
|
||||
/* Capture the CANDIDATE's last-log tuple at SEND time from its own in-memory
|
||||
* log (the library holds no entry bytes): last_log_index == log_count,
|
||||
* last_log_term == term of the tail entry (0 when the log is empty). This
|
||||
* feeds the (lastLogTerm, lastLogIndex) freshness gate at delivery. */
|
||||
rpc->last_log_index = (uint64_t)node->log_count;
|
||||
rpc->last_log_term = (node->log_count > 0)
|
||||
? node->log[node->log_count - 1].term
|
||||
: 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -319,9 +327,12 @@ void raft_sim_deliver_pending(raft_sim_cluster_t *c)
|
|||
if (c->nodes[src].partition || c->nodes[dst].partition)
|
||||
continue;
|
||||
|
||||
/* Deliver vote request to dst */
|
||||
/* Deliver vote request to dst, passing the candidate's send-time last-log
|
||||
* tuple so dst evaluates the (lastLogTerm, lastLogIndex) freshness gate. */
|
||||
uint64_t reply_term = 0;
|
||||
int granted = raft_on_vote_request(&c->nodes[dst].state, src, term,
|
||||
rpc->last_log_term,
|
||||
rpc->last_log_index,
|
||||
&reply_term);
|
||||
|
||||
/* Route reply back to src */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue