mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-10-12 02:22:45 +00:00
shrink diff
This commit is contained in:
@@ -890,24 +890,11 @@ def owned_by(address: str, offset: int = 0):
|
||||
"""Every name an address holds, across every configured TLD, with the
|
||||
account's on-chain footprint.
|
||||
|
||||
Read off the ERC-721 registrar rather than from logs: the token is the
|
||||
name, so `balanceOf` / `tokenOfOwnerByIndex` is the current answer and it
|
||||
includes names acquired by transfer, which a scan of registration events
|
||||
would miss. `labelOf` returns the plaintext label, recorded write-once at
|
||||
registration, so no off-chain index is needed to turn a token id back into
|
||||
a name.
|
||||
|
||||
Enumeration is deliberately not maintained on expiry, so a lapsed name
|
||||
stays in the list until someone re-registers it. That is reported rather
|
||||
than filtered: every entry carries `status`, using the same vocabulary as
|
||||
/resolve, and a caller scanning a recovered key is exactly the caller who
|
||||
needs to be told one of its names can still be renewed.
|
||||
|
||||
`inUse` answers the question a recovery scan actually asks - has this
|
||||
account ever been used - which holding a name is only one way to be. An
|
||||
account that was funded or ever sent a transaction is in use even with no
|
||||
name, so the nonce and balance it is derived from are reported too: a scan
|
||||
that gets this wrong hands out an account its owner is already using.
|
||||
Enumeration is read off the ERC-721 registrar, so a name acquired by
|
||||
transfer counts, and a lapsed one stays listed until re-registered - it is
|
||||
reported with its `status`, not filtered. `inUse` is what a recovery scan
|
||||
asks; holding a name is only one way to be in use, so the nonce and balance
|
||||
it is derived from are reported too.
|
||||
"""
|
||||
if not is_address(address):
|
||||
return 400, {
|
||||
|
||||
@@ -1281,12 +1281,12 @@ deleteLocalInvShortLink' c (CSLInvitation _ srv linkId _) = withStore' c $ \db -
|
||||
|
||||
ownedSimplexNames' :: AgentClient -> NetworkRequestMode -> UserId -> [SMPServer] -> Address -> Word32 -> AM (SMPServer, OwnedNames)
|
||||
ownedSimplexNames' c nm userId used addr offset = do
|
||||
srv <- getNextNameServerAvoiding c userId used
|
||||
srv <- getNextNameServer c userId used
|
||||
(srv,) <$> ownedNames c nm userId srv addr offset
|
||||
|
||||
resolveSimplexName' :: AgentClient -> NetworkRequestMode -> UserId -> SimplexDomain -> AM NameResponse
|
||||
resolveSimplexName' c nm userId domain = do
|
||||
resolverSrv <- getNextNameServer c userId
|
||||
resolverSrv <- getNextNameServer c userId []
|
||||
resolveName c nm userId resolverSrv domain
|
||||
|
||||
changeConnectionUser' :: AgentClient -> UserId -> ConnId -> UserId -> AM ()
|
||||
|
||||
@@ -71,7 +71,6 @@ module Simplex.Messaging.Agent.Client
|
||||
getQueueLink,
|
||||
resolveName,
|
||||
ownedNames,
|
||||
getNextNameServerAvoiding,
|
||||
getNextNameServer,
|
||||
enableQueueNotifications,
|
||||
EnableQueueNtfReq (..),
|
||||
@@ -260,9 +259,9 @@ import Simplex.Messaging.Crypto.BBS (BBSPresHeader (..), BBSPublicKey)
|
||||
import Simplex.Messaging.Crypto.Entitlement (EntitlementCredential, EntitlementProof, generateEntitlementProof)
|
||||
import Simplex.Messaging.Encoding
|
||||
import Simplex.Messaging.Encoding.String
|
||||
import Simplex.Messaging.Notifications.Client
|
||||
import Simplex.Messaging.Eth.Address (Address)
|
||||
import Simplex.Messaging.Names.Record (OwnedNames)
|
||||
import Simplex.Messaging.Notifications.Client
|
||||
import Simplex.Messaging.Notifications.Protocol
|
||||
import Simplex.Messaging.Notifications.Transport (NTFVersion)
|
||||
import Simplex.Messaging.Notifications.Types
|
||||
@@ -2042,32 +2041,20 @@ ownedNames c nm userId server addr offset =
|
||||
ownedViaProxy smp proxySess = proxyOwnedNames smp nm proxySess addr offset
|
||||
ownedDirectly smp = directOwnedNames smp nm addr offset
|
||||
|
||||
-- | A names-capable server the caller has not used yet. A scan asks about one
|
||||
-- account per relay, because sending the whole list to one relay would tell it
|
||||
-- those accounts belong to one wallet. With fewer relays than accounts the
|
||||
-- choice wraps onto used ones, which is the best the configured set allows.
|
||||
getNextNameServerAvoiding :: AgentClient -> UserId -> [SMPServer] -> AM SMPServer
|
||||
getNextNameServerAvoiding c userId used =
|
||||
liftIO (TM.lookupIO userId (userServers c :: TMap UserId (UserServers 'PSMP))) >>= \case
|
||||
Just UserServers {nameSrvs} ->
|
||||
let unused = filter ((`notElem` used) . protoServer . snd) nameSrvs
|
||||
in case L.nonEmpty unused of
|
||||
Just srvs -> protoServer <$> pickServer srvs
|
||||
Nothing -> case L.nonEmpty nameSrvs of
|
||||
Just srvs -> protoServer <$> pickServer srvs
|
||||
Nothing -> throwE NO_NAME_SERVERS
|
||||
Nothing -> throwE $ INTERNAL "unknown userId - no user servers"
|
||||
|
||||
-- | Pick a names-capable server for the user (the agent owns server selection,
|
||||
-- accounting for the names role). nameSrvs is opt-in (a plain list); empty means
|
||||
-- no server resolves names - a declared agent error, never a fallback.
|
||||
getNextNameServer :: AgentClient -> UserId -> AM SMPServer
|
||||
getNextNameServer c userId =
|
||||
-- Servers already used are avoided where the set allows: one relay asked about
|
||||
-- every account of a scan would learn they belong to one wallet.
|
||||
getNextNameServer :: AgentClient -> UserId -> [SMPServer] -> AM SMPServer
|
||||
getNextNameServer c userId usedSrvs =
|
||||
liftIO (TM.lookupIO userId (userServers c :: TMap UserId (UserServers 'PSMP))) >>= \case
|
||||
Just UserServers {nameSrvs} -> case L.nonEmpty nameSrvs of
|
||||
Just srvs -> protoServer <$> pickServer srvs
|
||||
Just srvs -> protoServer <$> pickServer (fromMaybe srvs $ L.nonEmpty $ L.filter (isUnusedServer usedHosts) srvs)
|
||||
Nothing -> throwE NO_NAME_SERVERS
|
||||
Nothing -> throwE $ INTERNAL "unknown userId - no user servers"
|
||||
where
|
||||
usedHosts = S.unions $ map serverHosts usedSrvs
|
||||
|
||||
enableQueueNotifications :: AgentClient -> RcvQueue -> SMP.NtfPublicAuthKey -> SMP.RcvNtfPublicDhKey -> AM (SMP.NotifierId, SMP.RcvNtfPublicDhKey)
|
||||
enableQueueNotifications c rq@RcvQueue {rcvId, rcvPrivateKey} notifierKey rcvNtfPublicDhKey =
|
||||
|
||||
@@ -68,6 +68,17 @@ pingEndpoint NamesEnv {resolverEnv, config} =
|
||||
resolveName :: NamesEnv -> NameQuery -> IO (Either NameErrorType NameResponse)
|
||||
resolveName env q = resolverCall env $ fetch env q
|
||||
|
||||
-- | Bound the call by the configured timeout, and report a raised exception as an error, leaving async exceptions alone.
|
||||
resolverCall :: NamesEnv -> IO (Either NameErrorType a) -> IO (Either NameErrorType a)
|
||||
resolverCall env a =
|
||||
E.try (timeout (resolverTimeoutMs (config env) * 1000) a) >>= \case
|
||||
Right result -> pure (fromMaybe (Left (RESOLVER "timeout")) result)
|
||||
Left e
|
||||
| Just (_ :: E.SomeAsyncException) <- E.fromException e -> E.throwIO e
|
||||
| otherwise -> do
|
||||
logError $ "[NAMES] resolver fetch raised " <> T.pack (E.displayException e)
|
||||
pure (Left (RESOLVER "resolver error"))
|
||||
|
||||
fetch :: NamesEnv -> NameQuery -> IO (Either NameErrorType NameResponse)
|
||||
fetch NamesEnv {resolverEnv} q =
|
||||
first mapResolverError <$> resolveHttp resolverEnv (decodeLatin1 $ smpEncode q)
|
||||
@@ -80,17 +91,6 @@ fetchOwned :: NamesEnv -> Address -> Word32 -> IO (Either NameErrorType OwnedNam
|
||||
fetchOwned NamesEnv {resolverEnv} addr offset =
|
||||
first mapResolverError <$> ownedByHttp resolverEnv (decodeLatin1 $ strEncode addr) offset
|
||||
|
||||
-- | Bound the call by the configured timeout, and report a raised exception as an error, leaving async exceptions alone.
|
||||
resolverCall :: NamesEnv -> IO (Either NameErrorType a) -> IO (Either NameErrorType a)
|
||||
resolverCall env a =
|
||||
E.try (timeout (resolverTimeoutMs (config env) * 1000) a) >>= \case
|
||||
Right result -> pure (fromMaybe (Left (RESOLVER "timeout")) result)
|
||||
Left e
|
||||
| Just (_ :: E.SomeAsyncException) <- E.fromException e -> E.throwIO e
|
||||
| otherwise -> do
|
||||
logError $ "[NAMES] resolver fetch raised " <> T.pack (E.displayException e)
|
||||
pure (Left (RESOLVER "resolver error"))
|
||||
|
||||
mapResolverError :: ResolverError -> NameErrorType
|
||||
mapResolverError = \case
|
||||
HttpStatusErr code -> RESOLVER ("HTTP " <> T.pack (show code))
|
||||
|
||||
Reference in New Issue
Block a user