Compare commits

..

1 commit

Author SHA1 Message Date
8d6f482de0 Fix critical filter logic bugs preventing event propagation in Nostr relay
Some checks failed
CI / lint (push) Waiting to run
CI / tests (push) Blocked by required conditions
/ release (push) Has been cancelled
/ pullrequest (push) Has been cancelled
- Fix inverted logic in _can_add_filter() method that was preventing new
subscription filters from being added
  - Fix REQ message handling to properly clear existing filters before
adding new ones
  - Fix inverted condition check when validating filter addition
capacity
  - Add debug logging to track filter matching and broadcast failures

  These bugs were causing customer order events (NIP-15) to be received
by the relay but not
  forwarded to nostrclient/nostrmarket, requiring server restarts or
manual refresh to process orders.
  The fix ensures proper event propagation: Customer → Relay →
nostrclient → nostrmarket → Invoice.

  Root cause: The _can_add_filter() method returned true when filters >=
max instead of when
  filters < max, and the validation check used the wrong conditional,
effectively blocking all
  new filter subscriptions after initial connection.
2026-01-06 23:05:22 +01:00

View file

@ -77,6 +77,10 @@ class NostrClientConnection:
resp = event.serialize_response(nostr_filter.subscription_id)
await self._send_msg(resp)
return True
else:
logger.info(
f"[NOSTRRELAY CLIENT] ❌ Filter didn't match for event {event.id}"
)
return False
def _is_direct_message_for_other(self, event: NostrEvent) -> bool:
@ -98,6 +102,10 @@ class NostrClientConnection:
async def _broadcast_event(self, e: NostrEvent):
if self.broadcast_event:
await self.broadcast_event(self, e)
else:
logger.warning(
f"[NOSTRRELAY CLIENT] ❌ No broadcast_event callback available for event {e.id}"
)
async def _handle_message(self, data: list) -> list:
if len(data) < 2:
@ -120,6 +128,8 @@ class NostrClientConnection:
return []
subscription_id = data[1]
# Handle multiple filters in REQ message
# First remove existing filters for this subscription_id
self._remove_filter(subscription_id)
responses = []
for filter_data in data[2:]:
response = await self._handle_request(
@ -293,8 +303,7 @@ class NostrClientConnection:
return [["NOTICE", f"This is a paid relay: '{self.relay_id}'"]]
nostr_filter.subscription_id = subscription_id
self._remove_filter(subscription_id)
if self._can_add_filter():
if not self._can_add_filter():
max_filters = self.config.max_client_filters
return [
[
@ -325,8 +334,8 @@ class NostrClientConnection:
def _can_add_filter(self) -> bool:
return (
self.config.max_client_filters != 0
and len(self.filters) >= self.config.max_client_filters
self.config.max_client_filters == 0
or len(self.filters) < self.config.max_client_filters
)
def _auth_challenge_expired(self):