upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/sync/relay_connection.rs
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-01-09 22:55:36 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-01-09 22:55:36 +0000
commit615bfa0e3e892a22f1691a6a1172ea755a7c3149 (patch)
tree2be46f2a647d5f9ba09d615dfd94c98ea6c9cfb0 /src/sync/relay_connection.rs
parent953a4be45dda7477d3db8099722856eb11eb6bb2 (diff)
improve: detect and skip negentropy for unsupported relays
- Upgrade NOTICE log level to INFO when relay rejects negentropy (envelope/NEG- errors) - Track NIP-77 support status per relay connection to avoid repeated failed attempts - Mark relay as unsupported when NOTICE rejection or timeout occurs - Skip negentropy on subsequent syncs during same connection session - Reset support status on reconnect to allow retry after relay upgrades This reduces log noise and eliminates 10-second timeout delays on each historic sync attempt for relays that don't support NIP-77 negentropy. Fixes negentropy-timeout-10-seconds issue by learning from relay behavior.
Diffstat (limited to 'src/sync/relay_connection.rs')
-rw-r--r--src/sync/relay_connection.rs49
1 files changed, 44 insertions, 5 deletions
diff --git a/src/sync/relay_connection.rs b/src/sync/relay_connection.rs
index e57e06c..5fabd10 100644
--- a/src/sync/relay_connection.rs
+++ b/src/sync/relay_connection.rs
@@ -76,6 +76,8 @@ pub struct RelayConnection {
76 database: Option<SharedDatabase>, 76 database: Option<SharedDatabase>,
77 /// Whether we've logged NIP-77 not supported for this relay (log once) 77 /// Whether we've logged NIP-77 not supported for this relay (log once)
78 nip77_warning_logged: std::sync::Arc<std::sync::atomic::AtomicBool>, 78 nip77_warning_logged: std::sync::Arc<std::sync::atomic::AtomicBool>,
79 /// Whether this relay supports NIP-77 negentropy (None = unknown, Some(false) = confirmed not supported)
80 nip77_supported: std::sync::Arc<std::sync::atomic::AtomicU8>,
79} 81}
80 82
81impl RelayConnection { 83impl RelayConnection {
@@ -115,6 +117,7 @@ impl RelayConnection {
115 client, 117 client,
116 database: None, 118 database: None,
117 nip77_warning_logged: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)), 119 nip77_warning_logged: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)),
120 nip77_supported: std::sync::Arc::new(std::sync::atomic::AtomicU8::new(0)),
118 } 121 }
119 } 122 }
120 123
@@ -132,6 +135,7 @@ impl RelayConnection {
132 client, 135 client,
133 database: Some(database), 136 database: Some(database),
134 nip77_warning_logged: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)), 137 nip77_warning_logged: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)),
138 nip77_supported: std::sync::Arc::new(std::sync::atomic::AtomicU8::new(0)),
135 } 139 }
136 } 140 }
137 141
@@ -272,7 +276,25 @@ impl RelayConnection {
272 } 276 }
273 } 277 }
274 RelayMessage::Notice(msg) => { 278 RelayMessage::Notice(msg) => {
275 tracing::debug!(relay = %url, message = %msg, "Received NOTICE"); 279 // Check if this is a negentropy-related notice
280 let is_negentropy_notice = msg.contains("envelope")
281 || msg.contains("NEG-")
282 || msg.contains("negentropy");
283
284 if is_negentropy_notice {
285 // Mark relay as not supporting NIP-77
286 self.nip77_supported
287 .store(2, std::sync::atomic::Ordering::Relaxed);
288
289 tracing::info!(
290 relay = %url,
291 notice = %msg,
292 "Relay does not support NIP-77 (negentropy)"
293 );
294 } else {
295 tracing::debug!(relay = %url, message = %msg, "Received NOTICE");
296 }
297
276 let _ = 298 let _ =
277 event_sender.send(RelayEvent::Notice(msg.to_string())).await; 299 event_sender.send(RelayEvent::Notice(msg.to_string())).await;
278 // Don't break - continue processing events 300 // Don't break - continue processing events
@@ -427,7 +449,7 @@ impl RelayConnection {
427 449
428 /// Check if negentropy sync should be attempted 450 /// Check if negentropy sync should be attempted
429 /// 451 ///
430 /// Rather than relying on NIP-11 document detection (which can be unreliable), 452 /// For simplicity and robustness, we always try negentropy first. If it fails,
431 /// this returns true to indicate we should try negentropy sync. The actual 453 /// this returns true to indicate we should try negentropy sync. The actual
432 /// sync will handle failures gracefully with fallback to REQ+EOSE. 454 /// sync will handle failures gracefully with fallback to REQ+EOSE.
433 /// 455 ///
@@ -436,10 +458,23 @@ impl RelayConnection {
436 /// - Some relays support NIP-77 but don't advertise it in NIP-11 458 /// - Some relays support NIP-77 but don't advertise it in NIP-11
437 /// - Some relays claim NIP-77 support but have bugs 459 /// - Some relays claim NIP-77 support but have bugs
438 /// - The nostr-sdk 0.44 API for relay document access varies 460 /// - The nostr-sdk 0.44 API for relay document access varies
461 ///
462 /// # Returns
463 /// * `false` if we've confirmed this relay doesn't support NIP-77
464 /// * `true` if unknown or supported (will attempt and handle failure)
439 pub async fn supports_negentropy(&self) -> bool { 465 pub async fn supports_negentropy(&self) -> bool {
440 // Always return true to attempt negentropy - we handle failure gracefully 466 // 0 = unknown (try it), 1 = supported, 2 = confirmed not supported
441 // in negentropy_sync_filter() which logs a warning and returns an error 467 let status = self
442 // that the caller can use to fall back to REQ+EOSE 468 .nip77_supported
469 .load(std::sync::atomic::Ordering::Relaxed);
470
471 if status == 2 {
472 // We've already confirmed this relay doesn't support NIP-77
473 tracing::trace!(relay = %self.url, "Skipping negentropy - relay confirmed not to support NIP-77");
474 return false;
475 }
476
477 // Unknown or supported - try it
443 true 478 true
444 } 479 }
445 480
@@ -488,6 +523,10 @@ impl RelayConnection {
488 // Check for any failures 523 // Check for any failures
489 // Note: Timeouts are common for relays without NIP-77 support 524 // Note: Timeouts are common for relays without NIP-77 support
490 if !output.failed.is_empty() { 525 if !output.failed.is_empty() {
526 // Mark relay as not supporting NIP-77 (timeout typically means no support)
527 self.nip77_supported
528 .store(2, std::sync::atomic::Ordering::Relaxed);
529
491 tracing::debug!( 530 tracing::debug!(
492 relay = %self.url, 531 relay = %self.url,
493 failures = ?output.failed, 532 failures = ?output.failed,