From fbcf2e3896b008f15f02a0df804405a346fd3656 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Wed, 21 Jan 2026 13:20:14 +0000 Subject: fix: fall back to REQ+EOSE when negentropy retry fails When negentropy retry makes no progress (relay returns zero events), this indicates the relay's negentropy implementation is broken. Instead of marking the batch as failed, we now: 1. Mark the relay as not supporting NIP-77 so future batches skip negentropy and use REQ+EOSE directly 2. Fall back to REQ+EOSE using semantic filters (kind/author/tags) for the current batch, which may succeed where ID-based queries fail This addresses the issue where some relays (e.g., azzamo.net, snort.social) return event IDs during negentropy diff but fail to serve those events when requested by ID. --- src/sync/relay_connection.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/sync/relay_connection.rs') diff --git a/src/sync/relay_connection.rs b/src/sync/relay_connection.rs index 99fc4ea..82e85ee 100644 --- a/src/sync/relay_connection.rs +++ b/src/sync/relay_connection.rs @@ -478,6 +478,18 @@ impl RelayConnection { true } + /// Mark this relay as not supporting NIP-77 negentropy (for external callers) + /// + /// This is called by SyncManager when negentropy retry returns zero events, + /// indicating the relay's negentropy implementation is broken. Future batches + /// will skip negentropy and use REQ+EOSE directly. + /// + /// Note: Internal code in this struct uses direct field access instead. + pub fn mark_negentropy_unsupported(&self) { + self.nip77_supported + .store(2, std::sync::atomic::Ordering::Relaxed); + } + /// Perform a negentropy sync diff (dry run) to identify missing events /// /// This method performs NIP-77 negentropy reconciliation without downloading events. -- cgit v1.2.3 From 214fa5cbb7dacedfb3227e623e0542351c7d7956 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Wed, 21 Jan 2026 13:23:41 +0000 Subject: refactor: use mark_negentropy_unsupported() consistently Refactor internal code to use the mark_negentropy_unsupported() method instead of direct field access for improved readability. --- src/sync/relay_connection.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'src/sync/relay_connection.rs') diff --git a/src/sync/relay_connection.rs b/src/sync/relay_connection.rs index 82e85ee..5bc0fa3 100644 --- a/src/sync/relay_connection.rs +++ b/src/sync/relay_connection.rs @@ -282,9 +282,7 @@ impl RelayConnection { || msg.contains("negentropy"); if is_negentropy_notice { - // Mark relay as not supporting NIP-77 - self.nip77_supported - .store(2, std::sync::atomic::Ordering::Relaxed); + self.mark_negentropy_unsupported(); tracing::info!( relay = %url, @@ -478,13 +476,14 @@ impl RelayConnection { true } - /// Mark this relay as not supporting NIP-77 negentropy (for external callers) + /// Mark this relay as not supporting NIP-77 negentropy /// - /// This is called by SyncManager when negentropy retry returns zero events, - /// indicating the relay's negentropy implementation is broken. Future batches - /// will skip negentropy and use REQ+EOSE directly. + /// Called when we detect negentropy isn't working for this relay: + /// - NOTICE message contains negentropy-related error + /// - negentropy_sync_diff() fails + /// - Negentropy retry returns zero events /// - /// Note: Internal code in this struct uses direct field access instead. + /// Future batches will skip negentropy and use REQ+EOSE directly. pub fn mark_negentropy_unsupported(&self) { self.nip77_supported .store(2, std::sync::atomic::Ordering::Relaxed); @@ -576,9 +575,7 @@ impl RelayConnection { Ok(reconciliation) } Err(e) => { - // Mark relay as not supporting NIP-77 - self.nip77_supported - .store(2, std::sync::atomic::Ordering::Relaxed); + self.mark_negentropy_unsupported(); // Log warning only once per relay to avoid spam if !self -- cgit v1.2.3