Blocks the size of RelayAuthStatus arrays from growing forever with auth messages

This commit is contained in:
Vitor Pamplona
2026-03-02 17:09:52 -05:00
parent 399c9463bf
commit 7ed0909169
3 changed files with 13 additions and 15 deletions
@@ -152,8 +152,6 @@ class AccountFollowsLoaderSubAssembler(
if (users.isEmpty()) return null
println("AccountFollowNeeds ${users.size}")
val connectedRelays = client.connectedRelaysFlow().value
val perRelay = pickRelaysToLoadUsers(users, accounts, connectedRelays, failureTracker.cannotConnectRelays, hasTried)
@@ -20,16 +20,17 @@
*/
package com.vitorpamplona.quartz.nip01Core.relay.client.auth
import androidx.collection.LruCache
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip42RelayAuth.RelayAuthEvent
class RelayAuthStatus {
// Keeps track of auth responses to update the relay with all filters
// after the authentication happen
private val authResponseWatcher: MutableMap<HexKey, AuthEventReceiptStatus> = mutableMapOf()
private val authResponseWatcher: LruCache<HexKey, AuthEventReceiptStatus> = LruCache(10)
// Avoids sending multiple replies for each auth.
private val uniqueAuthChallengesSent: MutableSet<ChallengePair> = mutableSetOf()
private val uniqueAuthChallengesSent: LruCache<ChallengePair, ChallengePair> = LruCache(10)
enum class AuthEventReceiptStatus {
AUTHENTICATING,
@@ -43,15 +44,14 @@ class RelayAuthStatus {
)
fun saveAuthSubmission(authEvent: RelayAuthEvent): Boolean {
val challenge = authEvent.challenge()
if (challenge == null) return false
val challenge = authEvent.challenge() ?: return false
val challengePair = ChallengePair(authEvent.pubKey, challenge)
// only send replies to new challenges to avoid infinite loop:
return if (challengePair !in uniqueAuthChallengesSent) {
authResponseWatcher[authEvent.id] = AuthEventReceiptStatus.AUTHENTICATING
uniqueAuthChallengesSent.add(challengePair)
return if (uniqueAuthChallengesSent[challengePair] == null) {
authResponseWatcher.put(authEvent.id, AuthEventReceiptStatus.AUTHENTICATING)
uniqueAuthChallengesSent.put(challengePair, challengePair)
true
} else {
false
@@ -61,10 +61,9 @@ class RelayAuthStatus {
fun checkAuthResults(
eventId: HexKey,
success: Boolean,
): Boolean =
if (authResponseWatcher.containsKey(eventId)) {
val wasAlreadyAuthenticated = authResponseWatcher[eventId]
): Boolean {
val wasAlreadyAuthenticated = authResponseWatcher[eventId]
return if (wasAlreadyAuthenticated != null) {
if (success) {
authResponseWatcher.put(eventId, AuthEventReceiptStatus.AUTHENTICATED)
} else {
@@ -75,6 +74,7 @@ class RelayAuthStatus {
} else {
false
}
}
fun hasFinishedAllAuths() = authResponseWatcher.all { it.value != AuthEventReceiptStatus.AUTHENTICATING }
fun hasFinishedAllAuths() = authResponseWatcher.snapshot().all { it.value != AuthEventReceiptStatus.AUTHENTICATING }
}
@@ -66,7 +66,7 @@ class RelayAuthenticator(
}
override fun onConnecting(relay: IRelayClient) {
authStatus.put(relay.url, RelayAuthStatus())
authStatus[relay.url] = RelayAuthStatus()
}
override fun onDisconnected(relay: IRelayClient) {