# Architecture: hyper-p2p-bloom-gossip **Category:** indexes-search **Protocol:** `bloom-gossip/v1` ## Purpose Replicate “seen key” hints across a Hyperswarm topic using a compact bloom filter plus incremental `bloom-add` gossip, avoiding full filter snapshots on every insert. ## Component diagram ``` Application │ ▼ HyperP2PBloomGossip ├── Uint8Array bit field (_bits) ├── Set _keys (exact membership for stats) └── initModuleSwarm → Protomux JSON channel ``` ## Wire messages | type | direction | fields | behavior | |------|-----------|--------|----------| | `bloom-add` | outbound / inbound | `key`, `peer`, `at` | Set bloom bits for `key` if not already in `_keys`; emit `remote-add` on inbound | Ignored: messages with missing `type`, wrong `type`, or missing `key`. ## State model | Field | Role | |-------|------| | `_bits` | Packed bloom array, length `ceil(_size / 8)` | | `_keys` | Exact keys seen (local + remote) | | `_stats` | Counters: `added`, `queries`, `gossipIn`, `gossipOut` | | `peerHex` | Local public key hex on gossip payloads | ## Introspection - `listKeys()` — exact key set (for debugging; Bloom `mightContain` remains probabilistic for unknown keys) - `clear()` — zero bits and keys - `exportBits()` / `importBits()` — hand off filter state to new peers ## Lifecycle 1. Construct with optional `topic` and `bits` 2. `await ready()` — joins swarm when `topic` set 3. `add` / `mightContain` / `exportBits` 4. `await close()` — zero filter, tear down swarm ## Composition Uses `../../_shared/p2p-bare.js` (`initModuleSwarm`, `gossipSend`) and `../../_shared/lib/errors.js` (`assertNonEmpty`). ## Trade-offs - **Pros:** Low bandwidth per new key; fast negative lookups - **Cons:** False positives; `importBits` does not sync `_keys`; no delete gossip