diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-04-10 18:20:23 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-04-10 18:20:23 +0000 |
| commit | 2161e3c0a8169a85111cd6dc01ffe2b0fed1493f (patch) | |
| tree | 92684ae1521ab470ef0d9a59b2bb0530c8ed5367 | |
| parent | dfd20a39a7ddaea07103cac45d4d79bc7e6ce0d7 (diff) | |
fix: purgatory replacement announcements leaked into DB without git data
When a replacement 30617 announcement arrived for an entry already in
purgatory (e.g. the same event fetched from a second relay during sync,
or a user re-submitting a slightly updated announcement), the policy
returned Accept instead of AcceptPurgatory. This caused the event to be
saved to the database immediately, bypassing the purgatory gate, without
the corresponding git data or state events ever arriving.
Fix: return AcceptPurgatory when replacing a purgatory entry so the
updated event stays in purgatory until git data arrives. The purgatory
entry is still updated with the newer event via replace_purgatory_announcement
before the return.
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | src/nostr/policy/announcement.rs | 6 |
2 files changed, 6 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 633ddbf..7a6498b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md | |||
| @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| 9 | 9 | ||
| 10 | ### Fixed | 10 | ### Fixed |
| 11 | 11 | ||
| 12 | - Replacement announcements (kind 30617) for a purgatory entry were being saved to the database immediately, bypassing the purgatory gate. When a second copy of the same announcement arrived (e.g. via sync from another relay) while the original was still in purgatory awaiting git data, the policy returned `Accept` instead of `AcceptPurgatory`, causing the event to be stored without the corresponding git data or state events ever arriving. The fix returns `AcceptPurgatory` for replacements of purgatory entries so the updated event is held in purgatory until git data arrives. | ||
| 13 | |||
| 12 | - Repository identifiers containing characters that require percent-encoding in URLs (e.g. spaces, emoji) are now accepted and served correctly. NIP-01 places no restriction on `d` tag values and NIP-34 only recommends kebab-case without mandating it, so rejecting non-kebab identifiers was overly strict. Identifiers are stored verbatim on disk and percent-encoded when used in URLs, per the `nostr://` clone URL spec formalised in [NIP-34 PR #2312](https://github.com/nostr-protocol/nips/pull/2312) and the GRASP-01 HTTP path spec. The landing page clone URL now also correctly percent-encodes the identifier. | 14 | - Repository identifiers containing characters that require percent-encoding in URLs (e.g. spaces, emoji) are now accepted and served correctly. NIP-01 places no restriction on `d` tag values and NIP-34 only recommends kebab-case without mandating it, so rejecting non-kebab identifiers was overly strict. Identifiers are stored verbatim on disk and percent-encoded when used in URLs, per the `nostr://` clone URL spec formalised in [NIP-34 PR #2312](https://github.com/nostr-protocol/nips/pull/2312) and the GRASP-01 HTTP path spec. The landing page clone URL now also correctly percent-encodes the identifier. |
| 13 | 15 | ||
| 14 | ### Changed | 16 | ### Changed |
diff --git a/src/nostr/policy/announcement.rs b/src/nostr/policy/announcement.rs index aba5181..b474fbb 100644 --- a/src/nostr/policy/announcement.rs +++ b/src/nostr/policy/announcement.rs | |||
| @@ -137,8 +137,10 @@ impl AnnouncementPolicy { | |||
| 137 | "Replacement announcement (purgatory) - replacing purgatory entry" | 137 | "Replacement announcement (purgatory) - replacing purgatory entry" |
| 138 | ); | 138 | ); |
| 139 | self.replace_purgatory_announcement(event, &announcement); | 139 | self.replace_purgatory_announcement(event, &announcement); |
| 140 | // Return Accept (not AcceptPurgatory) - this is a replacement, not new | 140 | // Return AcceptPurgatory - git data hasn't arrived yet so the |
| 141 | return validation_result; | 141 | // announcement must NOT be saved to the database. The purgatory |
| 142 | // entry has already been updated above with the newer event. | ||
| 143 | return AnnouncementResult::AcceptPurgatory; | ||
| 142 | } | 144 | } |
| 143 | 145 | ||
| 144 | // No existing announcement - route to purgatory | 146 | // No existing announcement - route to purgatory |