mirror of
https://github.com/block/buzz.git
synced 2026-11-14 13:21:02 +00:00
Every reconnect refetches the community's identity archive list (kind 13535) so the agent pickers stay current. On Block's Builderlab that list is about 228 KB, and it is downloaded again on every resume even though it rarely changes. The provider now remembers the last verified list per community and relay authority, and asks the relay only for a newer one (`since` the known list's `created_at` plus one). When nothing newer exists it reuses the known list, as the same set instance so watchers (mention candidates, search, the Agents page, channel details, the members sheet) don't rebuild. A newer list replaces it after the same verification as before. A list that fails any check, including its signature, yields no archived identities and drops the remembered one. ### Validation Provider tests: a refresh with an unchanged list sends `since`, keeps the known set and leaves the hidden set's listeners untouched; a newer list replaces it and becomes the new baseline; every invalid list (wrong signer, missing `-` marker, bad signature) starting from a warm cache drops the remembered list, so a following empty answer hides nobody. Each new step fails with its fix reverted. The existing verification, community-switch and deadline tests pass with the relay fake now honoring `since`. Full mobile test suite (4803 passed) and `flutter analyze` pass. On an iPhone 12 mini signed in to Block's Builderlab (instrumented profile build), a resume after 60 s in the background downloaded the 228 KB list each time before this change. ### Regressions **Accepted tradeoff: a same-second list can be missed.** The cursor assumes each list the relay publishes is stamped strictly later than the previous one. The relay nearly always does this (`publish_nipia_archival_list` stamps past the current head and republishes on drift), but two lists published within one second can share a `created_at`, and NIP-IA then keeps the one with the lower id. If the app already holds the other one, it misses the replacement until a later list arrives (the next archive or unarchive) or the app restarts. Meanwhile a just-archived or just-unarchived agent can show wrongly in pickers and search, never in history. We accept this for the bandwidth and resume-time win; a relay follow-up that stamps each list under the replacement lock and makes the rule a NIP-IA MUST removes the case. The same bound applies if a relay's database is restored to an older list: the app keeps its newer one until the relay publishes a list newer than it, or the app restarts. A failed or timed-out fetch still hides nobody, as before. --------- Signed-off-by: Tom Brow <tomb@squareup.com> Co-authored-by: Tom Brow <tomb@squareup.com>