feat(ha-term-safety): add WAL_CONFIG_MARKER entry type + reference payload codec (task 4.1)

This commit is contained in:
Rongsong Shen 2026-06-22 09:37:23 +00:00
parent f1783f7952
commit f447ad4183
5 changed files with 215 additions and 1 deletions

View file

@ -76,5 +76,30 @@ typedef enum {
WAL_QUEUE_CTRL = 20,
WAL_WORKER_CTRL = 30,
WAL_NOOP = 40, /* Internal: empty payload, replay no-op; appended only at promotion */
WAL_CONFIG_MARKER = 50, /* Config-change marker: {version_tag, sha256} reference only —
* NEVER the config bytes (R7.2/R7.4). Ordered + committed through
* the same (term,lsn) log as job state (ha-term-safety). */
WAL_CHECKPOINT = 100, /* Local WAL marker only — never replicated */
} wal_entry_type;
/* ── WAL_CONFIG_MARKER payload (ha-term-safety task 4.1) ────────────────────
* The marker payload is a *reference* to a configuration — its version tag and
* full SHA-256 content hash — and carries NO configuration bytes (R7.2/R7.4).
* The configuration bytes always travel out-of-band on the existing config-push
* transport (OPCode_replConfigPush), keyed to {version_tag, sha256}; they are
* NEVER placed in a WAL payload.
*
* This struct rides INSIDE the raft_entry_blob_t envelope with
* type == WAL_CONFIG_MARKER; on persist it lands as the WAL entry payload. The
* 40-byte wal_entry_hdr_t is unchanged (R1.7) — this is a payload, not a header.
* Use config_marker_encode / config_marker_decode (config_repl.c) for a fixed,
* padding-independent on-wire form. */
typedef struct {
uint64_t version_tag; /* first 8 bytes of the config SHA-256, host order */
uint8_t sha256[32]; /* full SHA-256 of the config bytes (the reference) */
} wal_config_marker_t;
/* Fixed serialized size of a WAL_CONFIG_MARKER payload: 8-byte version_tag +
* 32-byte sha256, with NO config bytes ever appended. This is the exact byte
* count config_marker_encode emits and config_marker_decode requires. */
#define WAL_CONFIG_MARKER_PAYLOAD_LEN (8u + 32u)