diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-23 15:41:32 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-23 15:41:32 +0000 |
| commit | c54ce061d6d278cce8362d5af085808ca60c239b (patch) | |
| tree | ec967d6195d9f7ec4f061449596611afe3a0950f /src/nostr/policy/related.rs | |
| parent | e0ad39a489b3398f8208713bf728db0cb11475b0 (diff) | |
| parent | 113928aa84894ea8f65c247d9987527e792b32a9 (diff) | |
feat: announcement purgatory
Extends purgatory to hold repository announcements until git data arrives,
preventing empty repositories from being served to clients.
When an announcement is received, a bare repo is created immediately and the
announcement is held in purgatory. It is only promoted and served once a git
push confirms real content exists. If no push arrives before expiry, the bare
repo is deleted and the announcement is silently discarded.
Key behaviours:
- Soft expiry: announcements are hidden from clients but kept alive while git
pushes are in progress, reviving on successful push
- Expiry is extended when a matching state event or git push is observed
- NIP-09 deletion events remove announcements from purgatory
- Purgatory state (announcements, state events, PR events, expired set) is
persisted to disk on graceful shutdown and restored on startup, with elapsed
downtime subtracted from expiry deadlines
- Purgatory announcements drive StateOnly sync in the sync system so state
events are fetched from listed relays before promotion
- SyncLevel added to RepoSyncIndex to distinguish purgatory repos (StateOnly)
from promoted repos (Full L2+L3 sync)
Diffstat (limited to 'src/nostr/policy/related.rs')
| -rw-r--r-- | src/nostr/policy/related.rs | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/src/nostr/policy/related.rs b/src/nostr/policy/related.rs index 7ce87db..cfe04a7 100644 --- a/src/nostr/policy/related.rs +++ b/src/nostr/policy/related.rs | |||
| @@ -139,6 +139,11 @@ impl RelatedEventPolicy { | |||
| 139 | .push((addr, pubkey, identifier)); | 139 | .push((addr, pubkey, identifier)); |
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | // NOTE: Intentionally only checks the database (promoted announcements), not purgatory. | ||
| 143 | // Related events should only be accepted once the repository announcement has been | ||
| 144 | // validated (promoted via git data). Events referencing purgatory-only repositories | ||
| 145 | // are correctly rejected as orphans and can be re-submitted after promotion. | ||
| 146 | |||
| 142 | // Query each kind group | 147 | // Query each kind group |
| 143 | for (kind, refs) in by_kind { | 148 | for (kind, refs) in by_kind { |
| 144 | let authors: Vec<PublicKey> = refs.iter().map(|(_, pk, _)| *pk).collect(); | 149 | let authors: Vec<PublicKey> = refs.iter().map(|(_, pk, _)| *pk).collect(); |