mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-10-12 02:22:45 +00:00
retry different relay upon failure
This commit is contained in:
@@ -17,7 +17,10 @@ ownedSimplexNames agent, over ownedNames in the server
|
||||
```
|
||||
|
||||
The agent returns the relay it used alongside the answer, so a caller can pass
|
||||
it back as used and ask the next account elsewhere. Sending every account of a
|
||||
it back as used and ask the next account elsewhere. A relay that cannot answer
|
||||
at all - too old for ROWN, unreachable, or with no resolver of its own behind it
|
||||
- is not the end of the lookup: it asks another, so a scan does not fail
|
||||
wholesale on the one relay it happened to draw during a version rollout. Sending every account of a
|
||||
seed to one relay would tell that relay the accounts belong to one wallet; the
|
||||
scan therefore asks one account per relay, and `getNextNameServer` avoids the
|
||||
hosts already used where the configured set allows. `proxiedSMPRelayVersion` is
|
||||
|
||||
@@ -228,7 +228,7 @@ import Simplex.Messaging.Parsers (defaultJSON, parse)
|
||||
import Simplex.Messaging.Protocol
|
||||
( BrokerMsg,
|
||||
Cmd (..),
|
||||
ErrorType (AUTH),
|
||||
ErrorType (AUTH, NAME),
|
||||
MsgBody,
|
||||
MsgFlags (..),
|
||||
NameResponse,
|
||||
@@ -1280,9 +1280,21 @@ deleteLocalInvShortLink' :: AgentClient -> ConnShortLink 'CMInvitation -> AM ()
|
||||
deleteLocalInvShortLink' c (CSLInvitation _ srv linkId _) = withStore' c $ \db -> deleteInvShortLink db srv linkId
|
||||
|
||||
ownedSimplexNames' :: AgentClient -> NetworkRequestMode -> UserId -> [SMPServer] -> Address -> Word32 -> AM (SMPServer, OwnedNames)
|
||||
ownedSimplexNames' c nm userId used addr offset = do
|
||||
srv <- getNextNameServer c userId used
|
||||
(srv,) <$> ownedNames c nm userId srv addr offset
|
||||
ownedSimplexNames' c nm userId used addr offset = tryRelays ownedNamesRelays used
|
||||
where
|
||||
tryRelays attempts tried = do
|
||||
srv <- getNextNameServer c userId tried
|
||||
((srv,) <$> ownedNames c nm userId srv addr offset) `catchError` \e ->
|
||||
if attempts > 1 && cannotAnswer e then tryRelays (attempts - 1) (srv : tried) else throwE e
|
||||
-- a relay that cannot answer, as against one that answers: too old for ROWN,
|
||||
-- unreachable, or with no resolver of its own behind it
|
||||
cannotAnswer e = temporaryOrHostError e || case e of
|
||||
SMP _ (NAME _) -> True
|
||||
_ -> False
|
||||
|
||||
-- | Relays one owned-names lookup asks before it gives up: during a version rollout the first one picked may have no ROWN.
|
||||
ownedNamesRelays :: Int
|
||||
ownedNamesRelays = 3
|
||||
|
||||
resolveSimplexName' :: AgentClient -> NetworkRequestMode -> UserId -> SimplexDomain -> AM NameResponse
|
||||
resolveSimplexName' c nm userId domain = do
|
||||
|
||||
@@ -15,6 +15,7 @@ module AgentTests.ResolveNameTests (resolveNameTests) where
|
||||
import AgentTests.FunctionalAPITests (withAgent)
|
||||
import Control.Monad.Except (runExceptT)
|
||||
import qualified Data.ByteString.Lazy as LB
|
||||
import Data.IORef (IORef, readIORef)
|
||||
import Data.List (isInfixOf)
|
||||
import Network.HTTP.Types (Status, status200, status404, status502)
|
||||
import NamesResolverServer (memCfg, memCfg2, memProxyCfg, withNames)
|
||||
@@ -22,7 +23,10 @@ import qualified NamesResolverServer as NRS
|
||||
import SMPAgentClient
|
||||
import SMPClient
|
||||
import SMPNamesTests (availableBody, registeredBody, testNameRecord)
|
||||
import Simplex.Messaging.Agent (resolveSimplexName)
|
||||
import Data.Text (Text)
|
||||
import Simplex.Messaging.Agent (ownedSimplexNames, resolveSimplexName)
|
||||
import Simplex.Messaging.Encoding.String (strDecode)
|
||||
import Simplex.Messaging.Eth.Address (Address)
|
||||
import Simplex.Messaging.Agent.Client (AgentClient)
|
||||
import Simplex.Messaging.Agent.Env.SQLite (InitialAgentServers (..), ServerCfg, ServerRoles (..), presetServerCfg)
|
||||
import Simplex.Messaging.Agent.Protocol (AgentErrorType (..))
|
||||
@@ -49,6 +53,13 @@ withDirectResolver (st, body) k =
|
||||
withSmpServerConfigOn (transport @TLS) (withNames port memCfg) testPort $ \_ ->
|
||||
withAgent 1 agentCfg (oneSrv (nameSrvCfg testSMPServer)) testDB k
|
||||
|
||||
-- | As 'withDirectResolver', with the requests the resolver was asked for.
|
||||
withDirectResolverReqs :: (Status, LB.ByteString) -> (AgentClient -> IORef [[Text]] -> IO a) -> IO a
|
||||
withDirectResolverReqs (st, body) k =
|
||||
NRS.withResolverServer (NRS.resolveResp st body) $ \port reqs ->
|
||||
withSmpServerConfigOn (transport @TLS) (withNames port memCfg) testPort $ \_ ->
|
||||
withAgent 1 agentCfg (oneSrv (nameSrvCfg testSMPServer)) testDB $ \c -> k c reqs
|
||||
|
||||
withProxyAndResolver :: (Status, LB.ByteString) -> (AgentClient -> IO a) -> IO a
|
||||
withProxyAndResolver (st, body) k =
|
||||
NRS.withResolverServer (NRS.resolveResp st body) $ \port _ ->
|
||||
@@ -87,6 +98,23 @@ resolveNameTests = do
|
||||
it "returns NameRecord" testDirectSuccess
|
||||
describe "name availability" $
|
||||
it "an unregistered name answers as available" testAvailSuccess
|
||||
describe "owned names" $
|
||||
it "a relay that cannot answer is not the end of the lookup" testOwnedRetriesRelays
|
||||
|
||||
-- | A relay too old for ROWN, unreachable, or with no resolver behind it must
|
||||
-- not end a recovery scan at the account it was asked about.
|
||||
testOwnedRetriesRelays :: HasCallStack => IO ()
|
||||
testOwnedRetriesRelays =
|
||||
withDirectResolverReqs (status502, "{}") $ \c reqs -> do
|
||||
r <- runExceptT $ ownedSimplexNames c NRMInteractive 1 [] testAddr 0
|
||||
case r of
|
||||
Left (SMP _ (SMP.NAME _)) -> pure ()
|
||||
_ -> expectationFailure $ "expected Left (SMP _ (NAME ..)), got: " <> show r
|
||||
asked <- readIORef reqs
|
||||
length [q | q@("v2" : "owned-by" : _) <- asked] `shouldBe` 3
|
||||
|
||||
testAddr :: Address
|
||||
testAddr = either error id $ strDecode "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"
|
||||
|
||||
testAvailSuccess :: HasCallStack => IO ()
|
||||
testAvailSuccess =
|
||||
|
||||
Reference in New Issue
Block a user