Skip to main content

fold_roster

Function fold_roster 

Source
pub fn fold_roster(
    inner_editions: &[Event],
    community_id: &CommunityId,
    floors: &HashMap<String, (u64, [u8; 32])>,
) -> FoldedRoster
Expand description

Fold a set of (already-decrypted) inner edition events into the current roster.

Each edition’s inner Schnorr signature is verified (the authorship proof); editions are grouped per entity and version-folded to a head (from scratch, floor 0). A head is folded into the trusted roster ONLY if it is chain-anchored (not gapped — fail closed on withheld history) AND its entity_id binds to its content (a Role lives at entity_id == role_id, a Grant at entity_id == grant_locator(community_id, member)) — so a signed edition can’t relabel itself to a different role/member. Anything else is dropped and counted in skipped. The grant binding is keyed by the community id (stable across a base rotation), so a re-anchored grant folds under any epoch’s root — the keystone for re-anchoring.

floors is each entity’s persisted head (entity_hex → (version, self_hash), from crate::db::community::get_all_edition_heads) — the refuse-downgrade FLOOR. Each entity’s chain is folded from ITS held floor, not from scratch, so a withholding relay serving editions below what we already hold can’t roll an authority chain back (the attack: resurrecting a since-revoked admin’s old grant by withholding the revocation). An entity absent from floors (a bootstrapping joiner) folds from genesis (floor 0); an empty map = a fresh joiner. A relay that serves only below-floor editions for an entity yields no head for it → that entity is simply absent from this fold (fail closed: it is not re-authorized off a rolled-back view; it self-heals when a relay serves ≥ floor).

This does NOT apply delegation-chain authorization — the signature proves WHO; deciding WHETHER they were allowed (rank + chain to the owner) is a separate, later layer.