core: align resolver docs/tests with RSLV errors

This commit is contained in:
shum
2026-06-11 14:51:56 +00:00
parent ae42ab130c
commit 7836f71d7a
2 changed files with 42 additions and 19 deletions
+23 -18
View File
@@ -4633,11 +4633,12 @@ processChatCommand cxt nm = \case
-- | Failure modes for 'resolveOnUserServers' / 'iterateResolvers'.
data ResolveError
= -- | No enabled server can resolve: every candidate answered CMD UNKNOWN /
-- PROHIBITED (does not speak RSLV), or none were configured / reachable.
-- Iterating across unsupported servers is privacy-safe -- the client degrades
-- RSLV to a no-op for relays below namesSMPVersion (see Protocol.hs), so an
-- unsupported relay never receives the queried name.
= -- | No enabled server can resolve: every candidate answered CMD UNKNOWN
-- (predates RSLV) or CMD PROHIBITED (speaks RSLV but has no resolver
-- configured), or none were configured / reachable. Iterating across these is
-- safe: a CMD UNKNOWN relay never received the name (the client degrades RSLV
-- to a no-op below namesSMPVersion, see Protocol.hs); a CMD PROHIBITED relay
-- did receive it but is one the user already trusts as an SMP server.
ResolverUnavailable
| -- | AUTH from a name-capable server. Every name server reads the same on-chain state, so we trust the first one's no.
NameNotRegistered
@@ -4664,13 +4665,15 @@ enabledSMPServersForUser user = do
| otherwise = Nothing
-- | Resolve a SimpleX name by trying the user's enabled SMP servers in order.
-- Transport-level failures (NETWORK, TIMEOUT, host-unreachable) and unsupported
-- servers (CMD UNKNOWN / PROHIBITED, i.e. relays that don't speak RSLV) both fall
-- through to the next server. Skipping an unsupported relay discloses nothing:
-- the client degrades RSLV to a no-op below namesSMPVersion, so the name is never
-- sent to it. A definitive answer from a name-capable relay terminates iteration:
-- AUTH is definitive NotFound (every name server reads the same on-chain state);
-- any other definite error surfaces as ResolverTransport.
-- Transport-level failures (NETWORK, TIMEOUT, host-unreachable) and servers that
-- cannot resolve (CMD UNKNOWN -- predates RSLV; or CMD PROHIBITED -- speaks RSLV
-- but has no resolver configured) all fall through to the next server. A CMD
-- UNKNOWN relay never received the name (the client degrades RSLV below
-- namesSMPVersion); a CMD PROHIBITED relay did, but it is one the user already
-- trusts as an SMP server. A definitive answer from a name-capable relay
-- terminates iteration: AUTH is definitive NotFound (every name server reads the
-- same on-chain state); any other definite error (e.g. INTERNAL on a resolver
-- backend failure) surfaces as ResolverTransport.
-- Privacy: a name-capable relay does see the queried name, so once one has
-- answered we do not broadcast the miss to every other operator the user has.
resolveOnUserServers :: User -> SimplexNameDomain -> CM (Either ResolveError NameRecord)
@@ -4858,12 +4861,14 @@ iterateResolvers servers resolve = go servers
isNotRegistered = \case
SMP _ SMP.AUTH -> True
_ -> False
-- A server that doesn't speak RSLV answers CMD UNKNOWN (predates the
-- command, e.g. the official servers) or CMD PROHIBITED (knows it but gates
-- on namesSMPVersion) -- directly, or wrapped by a proxy. We skip it and try
-- the next server: the client degrades RSLV to a no-op below namesSMPVersion
-- (Protocol.hs), so an unsupported relay never received the queried name.
-- ResolverUnavailable is returned only when no server can resolve.
-- A server that cannot resolve answers CMD UNKNOWN -- it predates RSLV (e.g.
-- an old official server), and the client degraded RSLV to a no-op below
-- namesSMPVersion so it never received the name -- or CMD PROHIBITED -- it
-- speaks RSLV but has no resolver configured (names role off), so it did
-- receive the name but cannot help. Either form may arrive directly or wrapped
-- by a proxy. We skip it and try the next server; ResolverUnavailable is
-- returned only when no server can resolve. A resolver-backed server's
-- transient failure is INTERNAL (-> ResolverTransport), not handled here.
isUnsupported = \case
SMP _ (SMP.CMD SMP.UNKNOWN) -> True
SMP _ (SMP.CMD SMP.PROHIBITED) -> True