feat(raft-commit-safety): raft_advance_commit Figure-8 current-term rule (tasks 3.1-3.3, 6.1)

AdvanceCommitIndex (raft.tla:259/270, closes G4): leader-only (-EPERM); Max(agreeIndexes)
= highest N with a quorum ((n_peers/2)+1) of match_index>=N, self counted as log_len;
scan log_len downward. CURRENT-TERM RULE: advance commit_index to N only when
on_get_entry_term(N)==s->term, else HOLD (Figure-8 safety — never commit a previous-term
entry on replication count alone; a later current-term commit indirectly commits it).
Monotonic; fires on_commit_advanced once per strict advance; commit_index<=log_len.

3.3: raft_on_append_entries_reply left untouched — verified it never advances commit
(separation, Req 2.6). 6.1: sim commit-driver helper raft_sim_advance_commit added.

Req 6.3 two-phase indirect-commit transition covered end-to-end by task 7.1 (sim).
ASAN green (230 tests).
This commit is contained in:
Rongsong Shen 2026-06-21 23:27:12 +00:00
parent 3ba6f03a9e
commit 195f660f9a
5 changed files with 350 additions and 4 deletions

View file

@ -565,6 +565,18 @@ void raft_sim_partition(raft_sim_cluster_t *c, int node_idx, int isolated);
*/
int raft_sim_check_log_matching(const raft_sim_cluster_t *c);
/*
* raft_sim_advance_commit: drive raft_advance_commit on node_idx (task 6.1).
*
* Recomputes the node's commit index from its current match_index[] / log_len /
* term (the leader-only AdvanceCommitIndex + current-term Figure-8 rule). On a
* strict advance the node's on_commit_advanced fires, updating the per-node
* commit_index mirror and commit_advanced_count. No-op if node_idx is out of
* range. Off-leader nodes return -EPERM internally (the return is discarded;
* tests read the per-node mirror).
*/
void raft_sim_advance_commit(raft_sim_cluster_t *c, int node_idx);
/*
* raft_sim_restart_node: model a process restart of node_idx (Req 8.3).
*