fix(ha-bootstrap): wire OP_requestVote RPC through standard Request envelope

The vote_request_thread was sending raw capnp(RequestVoteRequest) bytes
but the server-side iomgr decodes every incoming packet as a Request
struct. This caused the term field (uint64) to be misread as the opcode
field (uint16), so vote RPCs were silently misrouted (term=1 → OPCode_reply,
term=2 → OPCode_hello) and no node ever got a vote from its peers.

Fix:
- controller.capnp: add requestvotemsg @27 to Request.body and
  requestvotereplymsg @14 to RequestReply.data
- typemap.h: move request_vote_req_t/reply_t before xce_request_t;
  add requestvotemsg/requestvotereplymsg to body/data unions
- ha.c: rewrite vote_request_thread send/recv to use xce_encode()
  wrapper and decode outer Request→inner RequestReply on receive
- cluster.c: add case OPCode_requestVote handler calling
  handle_request_vote() and replying via xce_reply()

All 188 unit tests pass.
This commit is contained in:
Rongsong Shen 2026-05-29 17:01:59 +00:00
parent e25d2cc645
commit 6753b364c8
4 changed files with 100 additions and 58 deletions

View file

@ -172,6 +172,20 @@ typedef struct {
} data;
} xce_update_data_t;
typedef struct {
uint64_t term;
char *candidate_id;
uint64_t config_tag;
uint64_t last_log_lsn;
} request_vote_req_t;
typedef struct {
uint64_t term;
int vote_granted;
uint64_t peer_config_tag;
uint64_t peer_last_log_lsn;
} request_vote_reply_t;
typedef struct {
uint64_t seq;
uint32_t opcode;
@ -186,6 +200,7 @@ typedef struct {
repl_config_push_reply_t* replconfigpushreplymsg;
upgrade_config_reply_t* upgradeconfigreplymsg;
ctrl_hello_reply_t* ctrlhelloreplymsg;
request_vote_reply_t* requestvotereplymsg;
} data;
/* Req 7: standby redirect fields — populated when status == XCE_ERR_STANDBY */
char *redirect_host;
@ -221,6 +236,7 @@ typedef struct {
upgrade_config_req_t* upgradeconfigrequestmsg;
heartbeat_msg_t* heartbeatmsg;
ctrl_hello_req_t* ctrlhellomsg;
request_vote_req_t* requestvotemsg;
void* walcatchupentrymsg; /* wal_catchup_entry_t* */
void* snapshottransfermsg; /* snapshot_transfer_t* */
} body;
@ -229,21 +245,9 @@ typedef struct {
/* ── HA election and replication Cap'n Proto mapped types ────────────────
* C-side counterparts for the HA protocol capnp structs added in the
* ha-config-bootstrap spec (controller.capnp structs with $C.mapname).
* Must be declared here so controller.capnp.h can reference them. */
typedef struct {
uint64_t term;
char *candidate_id;
uint64_t config_tag;
uint64_t last_log_lsn;
} request_vote_req_t;
typedef struct {
uint64_t term;
int vote_granted;
uint64_t peer_config_tag;
uint64_t peer_last_log_lsn;
} request_vote_reply_t;
* Must be declared here so controller.capnp.h can reference them.
* request_vote_req_t and request_vote_reply_t are defined above
* xce_reply_t so they can be used in the xce_request_t body union. */
typedef struct {
char *name;