upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/nostr/builder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/nostr/builder.rs')
-rw-r--r--src/nostr/builder.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/nostr/builder.rs b/src/nostr/builder.rs
index 939ccef..acaac71 100644
--- a/src/nostr/builder.rs
+++ b/src/nostr/builder.rs
@@ -102,6 +102,11 @@ impl Nip34WritePolicy {
102 } 102 }
103 103
104 tracing::debug!("Accepted repository announcement: {}", event_id_str); 104 tracing::debug!("Accepted repository announcement: {}", event_id_str);
105
106 // Check purgatory for state events that might now be authorized
107 self.check_purgatory_state_events_for_identifier(&announcement.identifier)
108 .await;
109
105 WritePolicyResult::Accept 110 WritePolicyResult::Accept
106 } 111 }
107 Err(e) => { 112 Err(e) => {
@@ -125,6 +130,11 @@ impl Nip34WritePolicy {
125 announcement.identifier 130 announcement.identifier
126 ); 131 );
127 // Don't create bare repository for external announcements 132 // Don't create bare repository for external announcements
133
134 // Check purgatory for state events that might now be authorized
135 self.check_purgatory_state_events_for_identifier(&announcement.identifier)
136 .await;
137
128 WritePolicyResult::Accept 138 WritePolicyResult::Accept
129 } 139 }
130 Err(e) => { 140 Err(e) => {
@@ -304,6 +314,68 @@ impl Nip34WritePolicy {
304 } 314 }
305 } 315 }
306 316
317 /// Check purgatory for state events that might now be authorized by a new announcement
318 ///
319 /// When an announcement is accepted, state events in purgatory that were previously
320 /// rejected due to missing announcements might now be authorized. This method:
321 /// 1. Finds all state events in purgatory for the identifier
322 /// 2. Re-evaluates authorization for each event
323 /// 3. Processes authorized events (releases from purgatory)
324 /// 4. Keeps unauthorized events in purgatory (will expire naturally)
325 async fn check_purgatory_state_events_for_identifier(&self, identifier: &str) {
326 let state_events = self.ctx.purgatory.find_state(identifier);
327
328 if state_events.is_empty() {
329 return;
330 }
331
332 tracing::debug!(
333 identifier = %identifier,
334 count = state_events.len(),
335 "Checking purgatory state events after announcement acceptance"
336 );
337
338 for entry in state_events {
339 // Re-evaluate authorization with the new announcement
340 match self.state_policy.process_state_event(&entry.event, false).await {
341 Ok(WritePolicyResult::Accept) => {
342 tracing::info!(
343 event_id = %entry.event.id,
344 identifier = %identifier,
345 "State event in purgatory now authorized, will be processed"
346 );
347 // Event will be automatically removed from purgatory by process_state_event
348 // and broadcast to subscribers
349 }
350 Ok(WritePolicyResult::Reject { message, .. }) => {
351 if message.contains("not authorized") {
352 tracing::debug!(
353 event_id = %entry.event.id,
354 identifier = %identifier,
355 "State event in purgatory still not authorized, keeping in purgatory"
356 );
357 // Keep in purgatory - will expire naturally after 30 minutes
358 } else {
359 tracing::debug!(
360 event_id = %entry.event.id,
361 identifier = %identifier,
362 reason = %message,
363 "State event in purgatory rejected for other reason"
364 );
365 }
366 }
367 Err(e) => {
368 tracing::warn!(
369 event_id = %entry.event.id,
370 identifier = %identifier,
371 error = %e,
372 "Error re-evaluating state event in purgatory"
373 );
374 }
375 }
376 }
377 }
378
307 /// Handle events that must reference accepted repositories or events 379 /// Handle events that must reference accepted repositories or events
308 async fn handle_related_event(&self, event: &Event, event_type: &str) -> WritePolicyResult { 380 async fn handle_related_event(&self, event: &Event, event_type: &str) -> WritePolicyResult {
309 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex()); 381 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex());