diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-18 08:59:52 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2026-02-18 08:59:52 +0000 |
| commit | 467690f33bbbfd442852e61de221e4e5e161b878 (patch) | |
| tree | 2fc88bb35824143c6b670c0c4962a562d5816362 /src/nostr | |
| parent | cad58fccae7ed84bb033e56de0f1323b714a854d (diff) | |
fix: check purgatory in maintainer announcement lookup
is_maintainer_in_any_announcement only queried the database, missing
announcements still in purgatory. A maintainer's announcement (which
lists the recursive maintainer) may arrive and enter purgatory before
the recursive maintainer's announcement does, causing the maintainer
exception check to return false and reject the recursive maintainer's
announcement.
Diffstat (limited to 'src/nostr')
| -rw-r--r-- | src/nostr/policy/announcement.rs | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/nostr/policy/announcement.rs b/src/nostr/policy/announcement.rs index 1118497..abe9651 100644 --- a/src/nostr/policy/announcement.rs +++ b/src/nostr/policy/announcement.rs | |||
| @@ -222,6 +222,11 @@ impl AnnouncementPolicy { | |||
| 222 | /// | 222 | /// |
| 223 | /// This enables accepting announcements from maintainers even when they don't list | 223 | /// This enables accepting announcements from maintainers even when they don't list |
| 224 | /// this GRASP server, for maintainer chain discovery and GRASP-02 sync. | 224 | /// this GRASP server, for maintainer chain discovery and GRASP-02 sync. |
| 225 | /// | ||
| 226 | /// Checks both the database (promoted announcements) and purgatory (announcements | ||
| 227 | /// waiting for git data). This is necessary because a maintainer's announcement | ||
| 228 | /// (which lists the recursive maintainer) may still be in purgatory when the | ||
| 229 | /// recursive maintainer's announcement arrives. | ||
| 225 | async fn is_maintainer_in_any_announcement( | 230 | async fn is_maintainer_in_any_announcement( |
| 226 | &self, | 231 | &self, |
| 227 | identifier: &str, | 232 | identifier: &str, |
| @@ -233,12 +238,26 @@ impl AnnouncementPolicy { | |||
| 233 | identifier.to_string(), | 238 | identifier.to_string(), |
| 234 | ); | 239 | ); |
| 235 | 240 | ||
| 236 | let announcements: Vec<Event> = match self.ctx.database.query(filter).await { | 241 | let db_announcements: Vec<Event> = match self.ctx.database.query(filter).await { |
| 237 | Ok(events) => events.into_iter().collect(), | 242 | Ok(events) => events.into_iter().collect(), |
| 238 | Err(e) => return Err(format!("Database query failed: {}", e)), | 243 | Err(e) => return Err(format!("Database query failed: {}", e)), |
| 239 | }; | 244 | }; |
| 240 | 245 | ||
| 241 | if announcements.is_empty() { | 246 | // Also collect purgatory announcements for this identifier |
| 247 | let purgatory_announcements: Vec<Event> = self | ||
| 248 | .ctx | ||
| 249 | .purgatory | ||
| 250 | .get_announcements_by_identifier(identifier) | ||
| 251 | .into_iter() | ||
| 252 | .map(|entry| entry.event) | ||
| 253 | .collect(); | ||
| 254 | |||
| 255 | let all_announcements: Vec<&Event> = db_announcements | ||
| 256 | .iter() | ||
| 257 | .chain(purgatory_announcements.iter()) | ||
| 258 | .collect(); | ||
| 259 | |||
| 260 | if all_announcements.is_empty() { | ||
| 242 | // No existing announcements for this identifier - author cannot be a maintainer | 261 | // No existing announcements for this identifier - author cannot be a maintainer |
| 243 | return Ok(false); | 262 | return Ok(false); |
| 244 | } | 263 | } |
| @@ -246,14 +265,14 @@ impl AnnouncementPolicy { | |||
| 246 | let author_hex = author.to_hex(); | 265 | let author_hex = author.to_hex(); |
| 247 | 266 | ||
| 248 | // Check each announcement to see if author is listed as a maintainer | 267 | // Check each announcement to see if author is listed as a maintainer |
| 249 | for event in &announcements { | 268 | for event in &all_announcements { |
| 250 | // Check if author is the owner of this announcement | 269 | // Check if author is the owner of this announcement |
| 251 | if event.pubkey == *author { | 270 | if event.pubkey == *author { |
| 252 | return Ok(true); | 271 | return Ok(true); |
| 253 | } | 272 | } |
| 254 | 273 | ||
| 255 | // Check if author is listed in the maintainers tag | 274 | // Check if author is listed in the maintainers tag |
| 256 | if let Ok(announcement) = RepositoryAnnouncement::from_event(event.clone()) { | 275 | if let Ok(announcement) = RepositoryAnnouncement::from_event((*event).clone()) { |
| 257 | if announcement.maintainers.contains(&author_hex) { | 276 | if announcement.maintainers.contains(&author_hex) { |
| 258 | return Ok(true); | 277 | return Ok(true); |
| 259 | } | 278 | } |