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

@ -9,6 +9,7 @@
#include "clusterconfig.h"
#include "netio.h"
#include "request.h"
#include "wal_types.h" /* WAL_CONFIG_MARKER, WAL_CONFIG_MARKER_PAYLOAD_LEN */
/* Max config blob size — reject before allocating */
#define CONF_MAX_SIZE (1 * 1024 * 1024) /* 1 MiB */
@ -29,6 +30,49 @@
/* Certificate expiry warning threshold (days) */
#define CERT_WARN_DAYS 30
/* ── WAL_CONFIG_MARKER codec (ha-term-safety task 4.1) ───────────────
*
* A config-change 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 bytes always travel out-of-band on the config-push
* transport; they are never placed in a WAL payload. This codec produces the
* fixed, padding-independent on-wire form (big-endian version_tag + raw 32-byte
* sha256) that rides inside the raft_entry_blob_t envelope as the payload of a
* WAL_CONFIG_MARKER entry.
*/
/*
* config_marker_encode: serialize a {version_tag, sha256} config-change marker
* into a fixed WAL_CONFIG_MARKER_PAYLOAD_LEN-byte buffer. NO config bytes are
* ever written. version_tag is emitted big-endian; sha256 is the raw 32 bytes.
*
* buf — output buffer (must be >= WAL_CONFIG_MARKER_PAYLOAD_LEN)
* bufsz — capacity of buf
* out_len — receives the number of bytes written (always
* WAL_CONFIG_MARKER_PAYLOAD_LEN on success); untouched on failure
*
* Returns 0 on success; -EINVAL if sha256/buf/out_len is NULL;
* -ENOSPC if bufsz < WAL_CONFIG_MARKER_PAYLOAD_LEN.
*/
int config_marker_encode(uint64_t version_tag, const uint8_t sha256[32],
uint8_t *buf, size_t bufsz, size_t *out_len);
/*
* config_marker_decode: deserialize a WAL_CONFIG_MARKER payload produced by
* config_marker_encode. Reads exactly WAL_CONFIG_MARKER_PAYLOAD_LEN bytes; a
* shorter buffer is rejected without any out-of-bounds read.
*
* buf — input buffer
* len — bytes available in buf
* version_tag — receives the host-order version tag (may be NULL to skip)
* sha256_out — receives the raw 32-byte content hash (may be NULL to skip)
*
* Returns 0 on success; -EINVAL if buf is NULL or len <
* WAL_CONFIG_MARKER_PAYLOAD_LEN.
*/
int config_marker_decode(const uint8_t *buf, size_t len,
uint64_t *version_tag, uint8_t sha256_out[32]);
/* ── Phase 1: Storage ────────────────────────────────────────── */
/*