Skip to content

fix(relay): force monotonic created_at on NIP-IA archive snapshots (#3848) - #3954

Open
iroiro147 wants to merge 1 commit into
block:mainfrom
iroiro147:claude/issue3848-20260731
Open

fix(relay): force monotonic created_at on NIP-IA archive snapshots (#3848)#3954
iroiro147 wants to merge 1 commit into
block:mainfrom
iroiro147:claude/issue3848-20260731

Conversation

@iroiro147

Copy link
Copy Markdown

Problem

Rapid NIP-IA archive operations within one wall-clock second produce multiple kind:13535 snapshots with identical created_at. Under NIP-01, same-second replaceable events resolve by lowest event id, and since ids are randomly signed, an intermediate snapshot can win over a newer accepted delta — stranding the authoritative replaceable slot on stale data.

Closes #3848.

Fix

Mirror the guard already used by publish_dm_visibility_snapshot and emit_addressable_discovery_event: before signing, query the prior stored kind:13535 snapshot and force the new event's created_at to max(prior.created_at + 1, now). Six rapid same-second publishes now yield T..=T+5 — strictly increasing, so NIP-01 replacement ordering is deterministic and always favors the latest.

  • crates/buzz-relay/src/handlers/side_effects.rs :: publish_nipia_archival_list

Test

New regression test nipia_archival_list_snapshots_are_monotonic_through_same_second in identity_archive.rs: publishes six same-second snapshots and asserts six distinct, strictly-increasing created_at values. DB-gated; skips gracefully without a local Postgres (matches the existing harness pattern).

cargo check -p buzz-relay --all-targets warning-clean. Full lib suite: the only failures are 9 pre-existing api::media/api::admin failures that reproduce identically on clean main (verified via git stash), unrelated to this change.

Rapid NIP-IA archive operations within one wall-clock second produce
kind:13535 snapshots with identical created_at. NIP-01 resolves
same-second replaceable events by lowest event id (randomly signed),
so an intermediate snapshot can win over a newer accepted delta,
stranding the authoritative slot on stale data.

Add a pre-sign query for the prior kind:13535 snapshot and force
created_at to max(prior + 1, now), mirroring the guard already used
by publish_dm_visibility_snapshot and emit_addressable_discovery_event.

Includes a regression test (DB-gated, skips gracefully without Postgres).

Closes block#3848

Signed-off-by: iroiro147 <sarthak.singh@juspay.in>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NIP-IA archive snapshot can lose rapid same-second updates

1 participant