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:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-12-04 17:49:05 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-12-04 17:49:05 +0000
commitbf558b0dc17e14f96eea624ea5591315a2909154 (patch)
treef36a9250ad329a933949c842414c3455e4679326 /src/nostr/builder.rs
parentb167f1b2ae7edbcab95554b5203d22d9e372c8b5 (diff)
feat(sync): Phase 2 - multi-relay and complete filters
- Add relay discovery from stored announcements - Implement FilterService with three-layer strategy - Support multiple simultaneous relay connections - Filter batching for large tag sets
Diffstat (limited to 'src/nostr/builder.rs')
-rw-r--r--src/nostr/builder.rs41
1 files changed, 38 insertions, 3 deletions
diff --git a/src/nostr/builder.rs b/src/nostr/builder.rs
index 2284c18..732fd9d 100644
--- a/src/nostr/builder.rs
+++ b/src/nostr/builder.rs
@@ -19,6 +19,7 @@ use crate::nostr::policy::{
19 AnnouncementPolicy, AnnouncementResult, PolicyContext, PrEventPolicy, RelatedEventPolicy, 19 AnnouncementPolicy, AnnouncementResult, PolicyContext, PrEventPolicy, RelatedEventPolicy,
20 ReferenceResult, StatePolicy, StateResult, 20 ReferenceResult, StatePolicy, StateResult,
21}; 21};
22use crate::sync::SYNC_SOURCE_ADDR;
22 23
23/// Type alias for the shared database used by the relay 24/// Type alias for the shared database used by the relay
24pub type SharedDatabase = Arc<dyn NostrDatabase>; 25pub type SharedDatabase = Arc<dyn NostrDatabase>;
@@ -68,9 +69,39 @@ impl Nip34WritePolicy {
68 } 69 }
69 70
70 /// Handle repository announcement event 71 /// Handle repository announcement event
71 async fn handle_announcement(&self, event: &Event) -> PolicyResult { 72 ///
73 /// # Arguments
74 /// * `event` - The announcement event to validate
75 /// * `from_sync` - Whether this event came from GRASP-02 sync (bypasses domain validation)
76 async fn handle_announcement(&self, event: &Event, from_sync: bool) -> PolicyResult {
72 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex()); 77 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex());
73 78
79 // GRASP-02: Accept Layer 1 events from sync without domain validation
80 // This enables relay discovery chain - synced announcements are stored
81 // for relay URL extraction even if they don't list our domain
82 if from_sync {
83 // Still validate basic structure
84 match RepositoryAnnouncement::from_event(event.clone()) {
85 Ok(_announcement) => {
86 tracing::debug!(
87 "Accepted synced repository announcement: {} (domain validation bypassed)",
88 event_id_str
89 );
90 // Don't create bare repository for external announcements
91 return PolicyResult::Accept;
92 }
93 Err(e) => {
94 tracing::warn!(
95 "Rejected malformed synced announcement {}: {}",
96 event_id_str,
97 e
98 );
99 return PolicyResult::Reject(format!("Failed to parse announcement: {}", e));
100 }
101 }
102 }
103
104 // Normal validation path - requires domain to be listed
74 match self.announcement_policy.validate(event).await { 105 match self.announcement_policy.validate(event).await {
75 AnnouncementResult::Accept => { 106 AnnouncementResult::Accept => {
76 // Parse announcement to get repository details 107 // Parse announcement to get repository details
@@ -256,11 +287,15 @@ impl WritePolicy for Nip34WritePolicy {
256 fn admit_event<'a>( 287 fn admit_event<'a>(
257 &'a self, 288 &'a self,
258 event: &'a nostr_relay_builder::prelude::Event, 289 event: &'a nostr_relay_builder::prelude::Event,
259 _addr: &'a SocketAddr, 290 addr: &'a SocketAddr,
260 ) -> BoxedFuture<'a, PolicyResult> { 291 ) -> BoxedFuture<'a, PolicyResult> {
261 Box::pin(async move { 292 Box::pin(async move {
293 // GRASP-02: Detect sync source for Layer 1 domain validation bypass
294 // Synced events use SYNC_SOURCE_ADDR (127.0.0.2:0) to identify them
295 let from_sync = *addr == SYNC_SOURCE_ADDR;
296
262 match event.kind.as_u16() { 297 match event.kind.as_u16() {
263 KIND_REPOSITORY_ANNOUNCEMENT => self.handle_announcement(event).await, 298 KIND_REPOSITORY_ANNOUNCEMENT => self.handle_announcement(event, from_sync).await,
264 KIND_REPOSITORY_STATE => self.handle_state(event).await, 299 KIND_REPOSITORY_STATE => self.handle_state(event).await,
265 KIND_PR | KIND_PR_UPDATE => self.handle_pr_event(event).await, 300 KIND_PR | KIND_PR_UPDATE => self.handle_pr_event(event).await,
266 _ => self.handle_related_event(event, "Event").await, 301 _ => self.handle_related_event(event, "Event").await,