upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2025-12-22 21:02:03 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2025-12-22 21:02:03 +0000
commit1df90c609399c675e629b97294aee81a0b1e66dd (patch)
tree8482cdd0ea87cc0df5a86672bf99399aa0aa1a3d /src
parent5d3d96c7f0397a079384b7291ff21df76029b126 (diff)
chore: bump rust-nostr to latest master
so we can more easily support grasp purgatory feature
Diffstat (limited to 'src')
-rw-r--r--src/main.rs2
-rw-r--r--src/nostr/builder.rs56
-rw-r--r--src/sync/mod.rs12
3 files changed, 36 insertions, 34 deletions
diff --git a/src/main.rs b/src/main.rs
index 6d8b4dd..ddb198e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -47,7 +47,7 @@ async fn main() -> Result<()> {
47 47
48 // Create Nostr relay with NIP-34 validation 48 // Create Nostr relay with NIP-34 validation
49 // Returns both the relay and database for direct queries in handlers 49 // Returns both the relay and database for direct queries in handlers
50 if let Ok(relay_with_db) = nostr::builder::create_relay(&config) { 50 if let Ok(relay_with_db) = nostr::builder::create_relay(&config).await {
51 info!( 51 info!(
52 "Relay created with NIP-34 validation for domain: {}", 52 "Relay created with NIP-34 validation for domain: {}",
53 config.domain 53 config.domain
diff --git a/src/nostr/builder.rs b/src/nostr/builder.rs
index 84d8ab4..8dd6291 100644
--- a/src/nostr/builder.rs
+++ b/src/nostr/builder.rs
@@ -3,11 +3,12 @@
3/// This module integrates nostr-relay-builder with NIP-34 validation logic 3/// This module integrates nostr-relay-builder with NIP-34 validation logic
4/// using modular sub-policies for each event type. 4/// using modular sub-policies for each event type.
5use std::net::SocketAddr; 5use std::net::SocketAddr;
6use std::num::NonZeroUsize;
6use std::path::Path; 7use std::path::Path;
7use std::sync::Arc; 8use std::sync::Arc;
8 9
9use nostr::nips::nip19::ToBech32; 10use nostr::nips::nip19::ToBech32;
10use nostr_lmdb::NostrLMDB; 11use nostr_lmdb::NostrLmdb;
11use nostr_relay_builder::prelude::*; 12use nostr_relay_builder::prelude::*;
12 13
13use crate::config::{Config, DatabaseBackend}; 14use crate::config::{Config, DatabaseBackend};
@@ -68,7 +69,7 @@ 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 async fn handle_announcement(&self, event: &Event) -> WritePolicyResult {
72 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex()); 73 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex());
73 74
74 match self.announcement_policy.validate(event).await { 75 match self.announcement_policy.validate(event).await {
@@ -90,7 +91,7 @@ impl Nip34WritePolicy {
90 } 91 }
91 92
92 tracing::debug!("Accepted repository announcement: {}", event_id_str); 93 tracing::debug!("Accepted repository announcement: {}", event_id_str);
93 PolicyResult::Accept 94 WritePolicyResult::Accept
94 } 95 }
95 Err(e) => { 96 Err(e) => {
96 tracing::warn!( 97 tracing::warn!(
@@ -98,7 +99,7 @@ impl Nip34WritePolicy {
98 event_id_str, 99 event_id_str,
99 e 100 e
100 ); 101 );
101 PolicyResult::Reject(format!("Failed to parse announcement: {}", e)) 102 WritePolicyResult::reject(format!("Failed to parse announcement: {}", e))
102 } 103 }
103 } 104 }
104 } 105 }
@@ -113,7 +114,7 @@ impl Nip34WritePolicy {
113 announcement.identifier 114 announcement.identifier
114 ); 115 );
115 // Don't create bare repository for external announcements 116 // Don't create bare repository for external announcements
116 PolicyResult::Accept 117 WritePolicyResult::Accept
117 } 118 }
118 Err(e) => { 119 Err(e) => {
119 tracing::warn!( 120 tracing::warn!(
@@ -121,7 +122,7 @@ impl Nip34WritePolicy {
121 event_id_str, 122 event_id_str,
122 e 123 e
123 ); 124 );
124 PolicyResult::Reject(format!("Failed to parse announcement: {}", e)) 125 WritePolicyResult::reject(format!("Failed to parse announcement: {}", e))
125 } 126 }
126 } 127 }
127 } 128 }
@@ -131,13 +132,13 @@ impl Nip34WritePolicy {
131 event_id_str, 132 event_id_str,
132 reason 133 reason
133 ); 134 );
134 PolicyResult::Reject(reason) 135 WritePolicyResult::reject(reason)
135 } 136 }
136 } 137 }
137 } 138 }
138 139
139 /// Handle repository state event 140 /// Handle repository state event
140 async fn handle_state(&self, event: &Event) -> PolicyResult { 141 async fn handle_state(&self, event: &Event) -> WritePolicyResult {
141 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex()); 142 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex());
142 143
143 match self.state_policy.validate(event) { 144 match self.state_policy.validate(event) {
@@ -151,25 +152,25 @@ impl Nip34WritePolicy {
151 } 152 }
152 153
153 tracing::debug!("Accepted repository state: {}", event_id_str); 154 tracing::debug!("Accepted repository state: {}", event_id_str);
154 PolicyResult::Accept 155 WritePolicyResult::Accept
155 } 156 }
156 Err(e) => { 157 Err(e) => {
157 tracing::warn!("Failed to parse repository state {}: {}", event_id_str, e); 158 tracing::warn!("Failed to parse repository state {}: {}", event_id_str, e);
158 // Still accept the event even if we can't parse it 159 // Still accept the event even if we can't parse it
159 // The validation passed, so it's structurally valid 160 // The validation passed, so it's structurally valid
160 PolicyResult::Accept 161 WritePolicyResult::Accept
161 } 162 }
162 } 163 }
163 } 164 }
164 StateResult::Reject(reason) => { 165 StateResult::Reject(reason) => {
165 tracing::warn!("Rejected repository state {}: {}", event_id_str, reason); 166 tracing::warn!("Rejected repository state {}: {}", event_id_str, reason);
166 PolicyResult::Reject(reason) 167 WritePolicyResult::reject(reason)
167 } 168 }
168 } 169 }
169 } 170 }
170 171
171 /// Handle PR or PR Update event 172 /// Handle PR or PR Update event
172 async fn handle_pr_event(&self, event: &Event) -> PolicyResult { 173 async fn handle_pr_event(&self, event: &Event) -> WritePolicyResult {
173 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex()); 174 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex());
174 175
175 // Validate refs/nostr refs for this PR event 176 // Validate refs/nostr refs for this PR event
@@ -188,7 +189,7 @@ impl Nip34WritePolicy {
188 } 189 }
189 190
190 /// Handle events that must reference accepted repositories or events 191 /// Handle events that must reference accepted repositories or events
191 async fn handle_related_event(&self, event: &Event, event_type: &str) -> PolicyResult { 192 async fn handle_related_event(&self, event: &Event, event_type: &str) -> WritePolicyResult {
192 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex()); 193 let event_id_str = event.id.to_bech32().unwrap_or_else(|_| event.id.to_hex());
193 194
194 match self.related_event_policy.check_references(event).await { 195 match self.related_event_policy.check_references(event).await {
@@ -199,7 +200,7 @@ impl Nip34WritePolicy {
199 event_id_str, 200 event_id_str,
200 addr_ref 201 addr_ref
201 ); 202 );
202 PolicyResult::Accept 203 WritePolicyResult::Accept
203 } 204 }
204 Ok(ReferenceResult::ReferencesEvent(event_ref)) => { 205 Ok(ReferenceResult::ReferencesEvent(event_ref)) => {
205 tracing::debug!( 206 tracing::debug!(
@@ -208,7 +209,7 @@ impl Nip34WritePolicy {
208 event_id_str, 209 event_id_str,
209 event_ref 210 event_ref
210 ); 211 );
211 PolicyResult::Accept 212 WritePolicyResult::Accept
212 } 213 }
213 Ok(ReferenceResult::ReferencedByAccepted) => { 214 Ok(ReferenceResult::ReferencedByAccepted) => {
214 tracing::debug!( 215 tracing::debug!(
@@ -216,7 +217,7 @@ impl Nip34WritePolicy {
216 event_type, 217 event_type,
217 event_id_str 218 event_id_str
218 ); 219 );
219 PolicyResult::Accept 220 WritePolicyResult::Accept
220 } 221 }
221 Ok(ReferenceResult::Orphan) => { 222 Ok(ReferenceResult::Orphan) => {
222 let (addressable_refs, event_refs) = 223 let (addressable_refs, event_refs) =
@@ -228,7 +229,7 @@ impl Nip34WritePolicy {
228 addressable_refs.len(), 229 addressable_refs.len(),
229 event_refs.len() 230 event_refs.len()
230 ); 231 );
231 PolicyResult::Reject(format!( 232 WritePolicyResult::reject(format!(
232 "{} event must reference an accepted repository or accepted event", 233 "{} event must reference an accepted repository or accepted event",
233 event_type 234 event_type
234 )) 235 ))
@@ -240,7 +241,7 @@ impl Nip34WritePolicy {
240 event_id_str, 241 event_id_str,
241 e 242 e
242 ); 243 );
243 PolicyResult::Reject(format!("Database query failed: {}", e)) 244 WritePolicyResult::reject(format!("Database query failed: {}", e))
244 } 245 }
245 } 246 }
246 } 247 }
@@ -251,7 +252,7 @@ impl WritePolicy for Nip34WritePolicy {
251 &'a self, 252 &'a self,
252 event: &'a nostr_relay_builder::prelude::Event, 253 event: &'a nostr_relay_builder::prelude::Event,
253 _addr: &'a SocketAddr, 254 _addr: &'a SocketAddr,
254 ) -> BoxedFuture<'a, PolicyResult> { 255 ) -> BoxedFuture<'a, WritePolicyResult> {
255 Box::pin(async move { 256 Box::pin(async move {
256 match event.kind.as_u16() { 257 match event.kind.as_u16() {
257 KIND_REPOSITORY_ANNOUNCEMENT => self.handle_announcement(event).await, 258 KIND_REPOSITORY_ANNOUNCEMENT => self.handle_announcement(event).await,
@@ -265,7 +266,7 @@ impl WritePolicy for Nip34WritePolicy {
265 author = %event.pubkey.to_hex(), 266 author = %event.pubkey.to_hex(),
266 "Accepted kind 10317 user grasp list" 267 "Accepted kind 10317 user grasp list"
267 ); 268 );
268 PolicyResult::Accept 269 WritePolicyResult::Accept
269 } 270 }
270 _ => self.handle_related_event(event, "Event").await, 271 _ => self.handle_related_event(event, "Event").await,
271 } 272 }
@@ -288,7 +289,7 @@ pub struct RelayWithDatabase {
288/// Returns a `RelayWithDatabase` struct containing: 289/// Returns a `RelayWithDatabase` struct containing:
289/// - The `LocalRelay` for handling WebSocket connections 290/// - The `LocalRelay` for handling WebSocket connections
290/// - The `SharedDatabase` for direct database queries (e.g., push authorization) 291/// - The `SharedDatabase` for direct database queries (e.g., push authorization)
291pub fn create_relay(config: &Config) -> Result<RelayWithDatabase> { 292pub async fn create_relay(config: &Config) -> Result<RelayWithDatabase> {
292 tracing::info!("Configuring nostr relay with GRASP-01 validation..."); 293 tracing::info!("Configuring nostr relay with GRASP-01 validation...");
293 294
294 // Determine database path 295 // Determine database path
@@ -300,7 +301,7 @@ pub fn create_relay(config: &Config) -> Result<RelayWithDatabase> {
300 tracing::info!("Using in-memory database (no persistence)"); 301 tracing::info!("Using in-memory database (no persistence)");
301 Arc::new(MemoryDatabase::with_opts(MemoryDatabaseOptions { 302 Arc::new(MemoryDatabase::with_opts(MemoryDatabaseOptions {
302 events: true, 303 events: true,
303 max_events: Some(100_000), 304 max_events: Some(NonZeroUsize::new(100_000).unwrap()),
304 })) 305 }))
305 } 306 }
306 DatabaseBackend::NostrDb => { 307 DatabaseBackend::NostrDb => {
@@ -310,7 +311,7 @@ pub fn create_relay(config: &Config) -> Result<RelayWithDatabase> {
310 tracing::warn!("NostrDB backend not yet implemented, using in-memory database"); 311 tracing::warn!("NostrDB backend not yet implemented, using in-memory database");
311 Arc::new(MemoryDatabase::with_opts(MemoryDatabaseOptions { 312 Arc::new(MemoryDatabase::with_opts(MemoryDatabaseOptions {
312 events: true, 313 events: true,
313 max_events: Some(100_000), 314 max_events: Some(NonZeroUsize::new(100_000).unwrap()),
314 })) 315 }))
315 } 316 }
316 DatabaseBackend::Lmdb => { 317 DatabaseBackend::Lmdb => {
@@ -323,7 +324,7 @@ pub fn create_relay(config: &Config) -> Result<RelayWithDatabase> {
323 e 324 e
324 ) 325 )
325 })?; 326 })?;
326 Arc::new(NostrLMDB::open(db_path).map_err(|e| { 327 Arc::new(NostrLmdb::open(db_path).await.map_err(|e| {
327 anyhow::anyhow!( 328 anyhow::anyhow!(
328 "Failed to open LMDB database at {}: {}", 329 "Failed to open LMDB database at {}: {}",
329 db_path.display(), 330 db_path.display(),
@@ -338,9 +339,10 @@ pub fn create_relay(config: &Config) -> Result<RelayWithDatabase> {
338 let git_data_path = config.effective_git_data_path(); 339 let git_data_path = config.effective_git_data_path();
339 let write_policy = Nip34WritePolicy::new(&config.domain, database.clone(), &git_data_path); 340 let write_policy = Nip34WritePolicy::new(&config.domain, database.clone(), &git_data_path);
340 341
341 let builder = RelayBuilder::default() 342 let relay = LocalRelayBuilder::default()
342 .database(database.clone()) 343 .database(database.clone())
343 .write_policy(write_policy.clone()); 344 .write_policy(write_policy.clone())
345 .build();
344 346
345 tracing::info!( 347 tracing::info!(
346 "Relay configured with GRASP-01 validation for domain: {}", 348 "Relay configured with GRASP-01 validation for domain: {}",
@@ -348,7 +350,7 @@ pub fn create_relay(config: &Config) -> Result<RelayWithDatabase> {
348 ); 350 );
349 351
350 Ok(RelayWithDatabase { 352 Ok(RelayWithDatabase {
351 relay: LocalRelay::new(builder), 353 relay,
352 database, 354 database,
353 write_policy, 355 write_policy,
354 }) 356 })
diff --git a/src/sync/mod.rs b/src/sync/mod.rs
index d315939..6ec39e8 100644
--- a/src/sync/mod.rs
+++ b/src/sync/mod.rs
@@ -260,11 +260,11 @@ async fn run_daily_timer(
260 sync_manager: Arc<Mutex<SyncManager>>, 260 sync_manager: Arc<Mutex<SyncManager>>,
261 mut shutdown_rx: broadcast::Receiver<()>, 261 mut shutdown_rx: broadcast::Receiver<()>,
262) { 262) {
263 use rand::Rng; 263 use ::rand::Rng;
264 264
265 loop { 265 loop {
266 // Random interval between 23-25 hours 266 // Random interval between 23-25 hours
267 let hours = 23.0 + rand::thread_rng().gen::<f64>() * 2.0; 267 let hours = 23.0 + ::rand::thread_rng().gen::<f64>() * 2.0;
268 let seconds = (hours * 3600.0) as u64; 268 let seconds = (hours * 3600.0) as u64;
269 269
270 tracing::info!( 270 tracing::info!(
@@ -1599,7 +1599,7 @@ impl SyncManager {
1599 write_policy: &Nip34WritePolicy, 1599 write_policy: &Nip34WritePolicy,
1600 local_relay: &LocalRelay, 1600 local_relay: &LocalRelay,
1601 ) -> ProcessResult { 1601 ) -> ProcessResult {
1602 use nostr_relay_builder::prelude::{PolicyResult, WritePolicy}; 1602 use nostr_relay_builder::prelude::{WritePolicyResult, WritePolicy};
1603 use std::net::{IpAddr, Ipv4Addr, SocketAddr}; 1603 use std::net::{IpAddr, Ipv4Addr, SocketAddr};
1604 // Check if event already exists 1604 // Check if event already exists
1605 match database.event_by_id(&event.id).await { 1605 match database.event_by_id(&event.id).await {
@@ -1619,7 +1619,7 @@ impl SyncManager {
1619 let result = write_policy.admit_event(event, &dummy_addr).await; 1619 let result = write_policy.admit_event(event, &dummy_addr).await;
1620 1620
1621 match result { 1621 match result {
1622 PolicyResult::Accept => { 1622 WritePolicyResult::Accept => {
1623 // Save event to database 1623 // Save event to database
1624 if let Err(e) = database.save_event(event).await { 1624 if let Err(e) = database.save_event(event).await {
1625 tracing::error!( 1625 tracing::error!(
@@ -1644,11 +1644,11 @@ impl SyncManager {
1644 ); 1644 );
1645 ProcessResult::Saved 1645 ProcessResult::Saved
1646 } 1646 }
1647 PolicyResult::Reject(reason) => { 1647 WritePolicyResult::Reject { message, .. } => {
1648 tracing::debug!( 1648 tracing::debug!(
1649 event_id = %event.id, 1649 event_id = %event.id,
1650 relay = %relay_url, 1650 relay = %relay_url,
1651 reason = %reason, 1651 reason = %message,
1652 "Event rejected by write policy" 1652 "Event rejected by write policy"
1653 ); 1653 );
1654 ProcessResult::Rejected 1654 ProcessResult::Rejected