feat(ha-repl-hardening): safe_committed_lsn from vote replies (task 4.1)

- Add ha_compute_safe_committed_lsn() in ha.c: collects LSNs from
  granted voters (self + peers), sorts descending, picks index
  floor(n_granted/2) for majority-threshold value
- Wire into raft_cb_become_leader: compute safe_lsn/safe_tag from
  ha->elect_ctx after winning election, call persist_truncate_wal_above
- Four unit tests in test_ha_evaluate_committing.c:
  voters [99,100]+self=100 → 100; voters [50,51]+self=100 → 51;
  single-node → 0; denied voter excluded → self-only
This commit is contained in:
Rongsong Shen 2026-06-05 02:41:22 +00:00
parent 18ad3e9c9f
commit e7919304c3
4 changed files with 314 additions and 1 deletions

View file

@ -289,6 +289,22 @@ int ha_apply_wal_catchup_entry(ha_state_t *ha, persist_t *p,
void ha_nop_reply_state_report(ha_state_t *ha, myconf_t *myconf,
state_report_t *sr, xce_reply_t *reply_out);
/* ── Task 4.1 (ha-repl-hardening): safe commit point computation ─────────────
*
* ha_compute_safe_committed_lsn: determine safe_committed_lsn and safe_config_tag
* from vote replies collected in ctx after winning an election.
*
* Collects LSNs from all granted voters (self + peers with vote_granted=1),
* sorts descending, and returns the majority-threshold element.
*
* single-node (n_peers=0): outputs 0 for both fields (no vote data available).
*
* Requirements: 2.3 (ha-repl-hardening spec)
*/
void ha_compute_safe_committed_lsn(ha_elect_ctx_t *ctx,
uint64_t *safe_lsn_out,
uint64_t *safe_tag_out);
/* ── Task 3.2: Unified replication decision enum and evaluator ────────────── */
/*