Fixes the download of 1000s of NIP-65 relay lists because some relays consider empty lists as null and return everything.

This commit is contained in:
Vitor Pamplona
2024-08-22 12:24:45 -04:00
parent ae686671ba
commit 71b111ce8b
6 changed files with 38 additions and 8 deletions

View File

@@ -246,9 +246,10 @@ class Account(
) { nip65RelayList, dmRelayList, searchRelayList, privateOutBox, userProfile -> ) { nip65RelayList, dmRelayList, searchRelayList, privateOutBox, userProfile ->
checkNotInMainThread() checkNotInMainThread()
val baseRelaySet = activeRelays() ?: convertLocalRelays() val localRelays = convertLocalRelays()
val baseRelaySet = activeRelays() ?: localRelays
val newDMRelaySet = (dmRelayList.note.event as? ChatMessageRelayListEvent)?.relays()?.map { RelayUrlFormatter.normalize(it) }?.toSet() ?: emptySet() val newDMRelaySet = (dmRelayList.note.event as? ChatMessageRelayListEvent)?.relays()?.map { RelayUrlFormatter.normalize(it) }?.toSet() ?: emptySet()
val searchRelaySet = (searchRelayList.note.event as? SearchRelayListEvent)?.relays()?.map { RelayUrlFormatter.normalize(it) }?.toSet() ?: Constants.defaultSearchRelaySet val searchRelaySet = ((searchRelayList.note.event as? SearchRelayListEvent)?.relays() ?: Constants.defaultSearchRelaySet).map { RelayUrlFormatter.normalize(it) }.toSet()
val nip65RelaySet = val nip65RelaySet =
(nip65RelayList.note.event as? AdvertisedRelayListEvent)?.relays()?.map { (nip65RelayList.note.event as? AdvertisedRelayListEvent)?.relays()?.map {
AdvertisedRelayListEvent.AdvertisedRelayInfo( AdvertisedRelayListEvent.AdvertisedRelayInfo(
@@ -343,7 +344,7 @@ class Account(
} }
// -------------- // --------------
// PRIVATE OUTBOX // Local Storage
// -------------- // --------------
mappedRelaySet = mappedRelaySet =
@@ -2972,7 +2973,7 @@ class Account(
val localFeedTypes = val localFeedTypes =
localRelays.firstOrNull { localRelay -> RelayUrlFormatter.normalize(localRelay.url) == url }?.feedTypes?.minus(setOf(FeedType.SEARCH, FeedType.WALLET_CONNECT)) localRelays.firstOrNull { localRelay -> RelayUrlFormatter.normalize(localRelay.url) == url }?.feedTypes?.minus(setOf(FeedType.SEARCH, FeedType.WALLET_CONNECT))
?: Constants.defaultRelays ?: Constants.defaultRelays
.filter { defaultRelay -> defaultRelay.url == url } .filter { defaultRelay -> RelayUrlFormatter.normalize(defaultRelay.url) == url }
.firstOrNull() .firstOrNull()
?.feedTypes ?.feedTypes
?: Constants.activeTypesGlobalChats ?: Constants.activeTypesGlobalChats
@@ -2983,7 +2984,16 @@ class Account(
return usersRelayList.toTypedArray() return usersRelayList.toTypedArray()
} }
fun convertLocalRelays(): Array<RelaySetupInfo> = localRelays.map { RelaySetupInfo(RelayUrlFormatter.normalize(it.url), it.read, it.write, it.feedTypes.minus(setOf(FeedType.SEARCH, FeedType.WALLET_CONNECT))) }.toTypedArray() fun convertLocalRelays(): Array<RelaySetupInfo> =
localRelays
.map {
RelaySetupInfo(
RelayUrlFormatter.normalize(it.url),
it.read,
it.write,
it.feedTypes.minus(setOf(FeedType.SEARCH, FeedType.WALLET_CONNECT)),
)
}.toTypedArray()
fun activeGlobalRelays(): Array<String> = fun activeGlobalRelays(): Array<String> =
connectToRelays.value connectToRelays.value

View File

@@ -83,7 +83,7 @@ abstract class NostrDataSource(
eventCounter = eventCounter + Pair(key, Counter(subscriptionId, event.kind, 1)) eventCounter = eventCounter + Pair(key, Counter(subscriptionId, event.kind, 1))
} }
// Log.d(this@NostrDataSource.javaClass.simpleName, "Relay ${relay.url}: ${event.kind}") // Log.d(this@NostrDataSource.javaClass.simpleName, "Relay ${relay.url}: $subscriptionId ${event.kind} ")
consume(event, relay) consume(event, relay)
if (afterEOSE) { if (afterEOSE) {

View File

@@ -389,7 +389,7 @@ class Relay(
if (isReady) { if (isReady) {
val relayFilters = val relayFilters =
filters.filter { filter -> filters.filter { filter ->
activeTypes.any { it in filter.types } activeTypes.any { it in filter.types } && filter.filter.isValidFor(url)
} }
if (relayFilters.isNotEmpty()) { if (relayFilters.isNotEmpty()) {

View File

@@ -31,4 +31,7 @@ interface IPerRelayFilter {
): Boolean ): Boolean
fun toDebugJson(): String fun toDebugJson(): String
// This only exists because some relays confuse empty lists with null lists
fun isValidFor(url: String): Boolean
} }

View File

@@ -36,7 +36,22 @@ class SinceAuthorPerRelayFilter(
val limit: Int? = null, val limit: Int? = null,
val search: String? = null, val search: String? = null,
) : IPerRelayFilter { ) : IPerRelayFilter {
override fun toJson(forRelay: String) = FilterSerializer.toJson(ids, authors?.get(forRelay), kinds, tags, since?.get(forRelay)?.time, until, limit, search) // This only exists because some relays consider empty arrays as null and return everything.
// So, if there is an author list, but no list for the specific relay or if the list is empty
// don't send it.
override fun isValidFor(forRelay: String) = authors == null || !authors[forRelay].isNullOrEmpty()
override fun toJson(forRelay: String): String {
// if authors is empty, but not null
val authorsForThisRelay =
if (authors != null) {
authors[forRelay]?.ifEmpty { null }
} else {
null
}
return FilterSerializer.toJson(ids, authors?.get(forRelay), kinds, tags, since?.get(forRelay)?.time, until, limit, search)
}
override fun match( override fun match(
event: Event, event: Event,

View File

@@ -35,6 +35,8 @@ class SincePerRelayFilter(
val limit: Int? = null, val limit: Int? = null,
val search: String? = null, val search: String? = null,
) : IPerRelayFilter { ) : IPerRelayFilter {
override fun isValidFor(url: String) = true
override fun toJson(forRelay: String) = FilterSerializer.toJson(ids, authors, kinds, tags, since?.get(forRelay)?.time, until, limit, search) override fun toJson(forRelay: String) = FilterSerializer.toJson(ids, authors, kinds, tags, since?.get(forRelay)?.time, until, limit, search)
override fun match( override fun match(