grpc: directory replication API for websites to mirror accounts/channels

Snapshot (full read) + Subscribe (live stream) over the same committed-entry
channel gossip uses. Identity and metadata only — password hashes, SCRAM
verifiers, cert fingerprints, and the finer channel-ops-list events never
cross this API. Bearer-token authenticated, optional server TLS. Verified
end-to-end against a live test-net registration, not just unit tests.
This commit is contained in:
Jean Chevronnet 2026-07-12 23:10:21 +00:00
parent bdcce01f11
commit e5a0d2acdf
No known key found for this signature in database
11 changed files with 1188 additions and 8 deletions

View file

@ -236,6 +236,24 @@ impl LogEntry {
}
}
// Read-only accessors for consumers outside this module (the gRPC replication
// layer subscribes to the same broadcast channel gossip does, and translates
// each entry to a wire message).
impl LogEntry {
pub fn origin(&self) -> &str {
&self.origin
}
pub fn seq(&self) -> u64 {
self.seq
}
pub fn lamport(&self) -> u64 {
self.lamport
}
pub fn event(&self) -> &Event {
&self.event
}
}
// Append-only log, the sole persistent source of truth: `open` replays it,
// `append` stamps and writes a locally-authored entry, and `ingest` folds in an
// entry authored by another node. The version vector (highest seq applied per
@ -886,6 +904,11 @@ impl Db {
self.channels.values()
}
/// All registered accounts, for a directory snapshot (see the gRPC layer).
pub fn accounts(&self) -> impl Iterator<Item = &Account> {
self.accounts.values()
}
/// Names of channels founded by `account` (case-insensitive).
pub fn channels_owned_by(&self, account: &str) -> Vec<String> {
self.channels