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 ->
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 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 =
(nip65RelayList.note.event as? AdvertisedRelayListEvent)?.relays()?.map {
AdvertisedRelayListEvent.AdvertisedRelayInfo(
@ -343,7 +344,7 @@ class Account(
}
// --------------
// PRIVATE OUTBOX
// Local Storage
// --------------
mappedRelaySet =
@ -2972,7 +2973,7 @@ class Account(
val localFeedTypes =
localRelays.firstOrNull { localRelay -> RelayUrlFormatter.normalize(localRelay.url) == url }?.feedTypes?.minus(setOf(FeedType.SEARCH, FeedType.WALLET_CONNECT))
?: Constants.defaultRelays
.filter { defaultRelay -> defaultRelay.url == url }
.filter { defaultRelay -> RelayUrlFormatter.normalize(defaultRelay.url) == url }
.firstOrNull()
?.feedTypes
?: Constants.activeTypesGlobalChats
@ -2983,7 +2984,16 @@ class Account(
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> =
connectToRelays.value

View File

@ -83,7 +83,7 @@ abstract class NostrDataSource(
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)
if (afterEOSE) {

View File

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

View File

@ -31,4 +31,7 @@ interface IPerRelayFilter {
): Boolean
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 search: String? = null,
) : 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(
event: Event,

View File

@ -35,6 +35,8 @@ class SincePerRelayFilter(
val limit: Int? = null,
val search: String? = null,
) : 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 match(