ZKAC/cli/zkac_cli/registry_log.py
2026-04-16 01:29:59 +02:00

60 lines
1.8 KiB
Python

"""Persist RegistryManager by replaying create/update events."""
from __future__ import annotations
import base64
import json
from pathlib import Path
from typing import Any
import zkac
def save_events(path: Path, events: list[dict[str, Any]]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps({"events": events}, indent=2), encoding="utf-8")
def load_events(path: Path) -> list[dict[str, Any]]:
if not path.is_file():
return []
data = json.loads(path.read_text(encoding="utf-8"))
return list(data.get("events", []))
def replay_manager(events: list[dict[str, Any]]) -> zkac.RegistryManager:
"""Rebuild manager from persisted events (multiple registries supported)."""
mgr = zkac.RegistryManager()
by_rid: dict[bytes, list[dict[str, Any]]] = {}
for e in events:
st = base64.b64decode(e["state_b64"])
st_obj = zkac.RegistryState.deserialize(st)
rid = st_obj.registry_id()
by_rid.setdefault(rid, []).append(e)
for rid, evs in by_rid.items():
evs.sort(
key=lambda e: zkac.RegistryState.deserialize(
base64.b64decode(e["state_b64"])
).version()
)
for i, e in enumerate(evs):
st = base64.b64decode(e["state_b64"])
cert = base64.b64decode(e["state_cert_b64"])
if i == 0:
mgr.create(st, cert)
else:
mgr.update(rid, st, cert)
return mgr
def append_event(path: Path, op: str, state_bytes: bytes, state_cert: bytes) -> None:
events = load_events(path)
events.append(
{
"op": op,
"state_b64": base64.b64encode(state_bytes).decode(),
"state_cert_b64": base64.b64encode(state_cert).decode(),
}
)
save_events(path, events)