Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: message statuses for sending proxies #4161

Merged
merged 17 commits into from
May 15, 2024
Merged
2 changes: 1 addition & 1 deletion cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ constraints: zip +disable-bzip2 +disable-zstd
source-repository-package
type: git
location: https://github.com/simplex-chat/simplexmq.git
tag: f51cf1deacd14aced88652ccfa06a746999e2ac6
tag: 2d2cc86bd82a5c604901ae813a6cbcc21f3e2024

source-repository-package
type: git
Expand Down
2 changes: 1 addition & 1 deletion scripts/nix/sha256map.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"https://github.com/simplex-chat/simplexmq.git"."f51cf1deacd14aced88652ccfa06a746999e2ac6" = "1q1lcjbapq0mrz0z99shajn364jf7j2j6gm5qir2h230l5fg6mih";
"https://github.com/simplex-chat/simplexmq.git"."2d2cc86bd82a5c604901ae813a6cbcc21f3e2024" = "0gny4qywp2hda9fqs5gm3zkr8vd4jriy3iqp7ap7bwc12is6n8zw";
"https://github.com/simplex-chat/hs-socks.git"."a30cc7a79a08d8108316094f8f2f82a0c5e1ac51" = "0yasvnr7g91k76mjkamvzab2kvlb1g5pspjyjn2fr6v83swjhj38";
"https://github.com/simplex-chat/direct-sqlcipher.git"."f814ee68b16a9447fbb467ccc8f29bdd3546bfd9" = "1ql13f4kfwkbaq7nygkxgw84213i0zm7c1a8hwvramayxl38dq5d";
"https://github.com/simplex-chat/sqlcipher-simple.git"."a46bd361a19376c5211f1058908fc0ae6bf42446" = "1z0r78d8f0812kxbgsm735qf6xx8lvaz27k1a0b4a2m0sshpd5gl";
Expand Down
1 change: 1 addition & 0 deletions simplex-chat.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ library
Simplex.Chat.Migrations.M20240402_item_forwarded
Simplex.Chat.Migrations.M20240430_ui_theme
Simplex.Chat.Migrations.M20240501_chat_deleted
Simplex.Chat.Migrations.M20240510_chat_items_via_proxy
Simplex.Chat.Mobile
Simplex.Chat.Mobile.File
Simplex.Chat.Mobile.Shared
Expand Down
62 changes: 40 additions & 22 deletions src/Simplex/Chat.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -fno-warn-ambiguous-fields #-}

Check warning on line 14 in src/Simplex/Chat.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-8.10.7

unrecognised warning flag: -fno-warn-ambiguous-fields

Check warning on line 14 in src/Simplex/Chat.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-8.10.7

unrecognised warning flag: -fno-warn-ambiguous-fields

module Simplex.Chat where

Expand Down Expand Up @@ -100,7 +100,7 @@
import Simplex.Messaging.Agent.Store.SQLite.DB (SlowQueryStats (..))
import qualified Simplex.Messaging.Agent.Store.SQLite.DB as DB
import qualified Simplex.Messaging.Agent.Store.SQLite.Migrations as Migrations
import Simplex.Messaging.Client (defaultNetworkConfig)
import Simplex.Messaging.Client (ProxyClientError (..), defaultNetworkConfig)
import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Crypto.File (CryptoFile (..), CryptoFileArgs (..))
import qualified Simplex.Messaging.Crypto.File as CF
Expand All @@ -113,6 +113,7 @@
import qualified Simplex.Messaging.Protocol as SMP
import Simplex.Messaging.ServiceScheme (ServiceScheme (..))
import qualified Simplex.Messaging.TMap as TM
import Simplex.Messaging.Transport (TransportError (..))
import Simplex.Messaging.Transport.Client (defaultSocksProxy)
import Simplex.Messaging.Util
import Simplex.Messaging.Version
Expand Down Expand Up @@ -356,7 +357,7 @@
. map (\ServerCfg {server} -> server)
. filter (\ServerCfg {enabled} -> enabled)

cfgServers :: UserProtocol p => SProtocolType p -> (DefaultAgentServers -> NonEmpty (ProtoServerWithAuth p))

Check warning on line 360 in src/Simplex/Chat.hs

View workflow job for this annotation

GitHub Actions / build-windows-latest-9.6.3

Redundant constraint: UserProtocol p

Check warning on line 360 in src/Simplex/Chat.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-20.04-9.6.3

Redundant constraint: UserProtocol p

Check warning on line 360 in src/Simplex/Chat.hs

View workflow job for this annotation

GitHub Actions / build-ubuntu-22.04-9.6.3

Redundant constraint: UserProtocol p

Check warning on line 360 in src/Simplex/Chat.hs

View workflow job for this annotation

GitHub Actions / build-macos-latest-9.6.3

Redundant constraint: UserProtocol p

Check warning on line 360 in src/Simplex/Chat.hs

View workflow job for this annotation

GitHub Actions / build-macos-13-9.6.3

Redundant constraint: UserProtocol p
cfgServers p DefaultAgentServers {smp, xftp} = case p of
SPSMP -> smp
SPXFTP -> xftp
Expand Down Expand Up @@ -699,10 +700,7 @@
(,) <$> getAChatItem db vr user chatRef itemId <*> liftIO (getChatItemVersions db itemId)
let itemVersions = if null versions then maybeToList $ mkItemVersion ci else versions
memberDeliveryStatuses <- case (cType, dir) of
(SCTGroup, SMDSnd) -> do
withStore' (`getGroupSndStatuses` itemId) >>= \case
[] -> pure Nothing
memStatuses -> pure $ Just $ map (uncurry MemberDeliveryStatus) memStatuses
(SCTGroup, SMDSnd) -> L.nonEmpty <$> withStore' (`getGroupSndStatuses` itemId)
_ -> pure Nothing
forwardedFromChatItem <- getForwardedFromItem user ci
pure $ CRChatItemInfo user aci ChatItemInfo {itemVersions, memberDeliveryStatuses, forwardedFromChatItem}
Expand Down Expand Up @@ -3896,7 +3894,7 @@
withAckMessage' agentConnId meta $
void $
saveDirectRcvMSG conn meta msgBody
SENT msgId ->
SENT msgId _proxy ->
sentMsgDeliveryEvent conn msgId
OK ->
-- [async agent commands] continuation on receiving OK
Expand Down Expand Up @@ -4029,10 +4027,13 @@
notifyMemberConnected gInfo m $ Just ct
let connectedIncognito = contactConnIncognito ct || incognitoMembership gInfo
when (memberCategory m == GCPreMember) $ probeMatchingContactsAndMembers ct connectedIncognito True
SENT msgId -> do
SENT msgId proxy -> do
sentMsgDeliveryEvent conn msgId
checkSndInlineFTComplete conn msgId
updateDirectItemStatus ct conn msgId $ CISSndSent SSPComplete
ci_ <- withStore $ \db -> do
ci_ <- updateDirectItemStatus' db ct conn msgId (CISSndSent SSPComplete)
forM ci_ $ \ci -> liftIO $ setDirectSndChatItemViaProxy db user ct ci (isJust proxy)
forM_ ci_ $ \ci -> toView $ CRChatItemStatusUpdated user (AChatItem SCTDirect SMDSnd (DirectChat ct) ci)
SWITCH qd phase cStats -> do
toView $ CRContactSwitch user ct (SwitchProgress qd phase cStats)
when (phase `elem` [SPStarted, SPCompleted]) $ case qd of
Expand Down Expand Up @@ -4067,13 +4068,15 @@
OK ->
-- [async agent commands] continuation on receiving OK
when (corrId /= "") $ withCompletedCommand conn agentMsg $ \_cmdData -> pure ()
MWARN msgId err ->
updateDirectItemStatus ct conn msgId (CISSndWarning $ agentSndError err)
MERR msgId err -> do
updateDirectItemStatus ct conn msgId $ agentErrToItemStatus err
updateDirectItemStatus ct conn msgId (CISSndError $ agentSndError err)
toView $ CRChatError (Just user) (ChatErrorAgent err $ Just connEntity)
incAuthErrCounter connEntity conn err
MERRS msgIds err -> do
-- error cannot be AUTH error here
updateDirectItemsStatus ct conn (L.toList msgIds) $ agentErrToItemStatus err
updateDirectItemsStatus ct conn (L.toList msgIds) (CISSndError $ agentSndError err)
toView $ CRChatError (Just user) (ChatErrorAgent err $ Just connEntity)
ERR err -> do
toView $ CRChatError (Just user) (ChatErrorAgent err $ Just connEntity)
Expand Down Expand Up @@ -4411,10 +4414,10 @@
RCVD msgMeta msgRcpt ->
withAckMessage' agentConnId msgMeta $
groupMsgReceived gInfo m conn msgMeta msgRcpt
SENT msgId -> do
SENT msgId proxy -> do
sentMsgDeliveryEvent conn msgId
checkSndInlineFTComplete conn msgId
updateGroupItemStatus gInfo m conn msgId $ CISSndSent SSPComplete
updateGroupItemStatus gInfo m conn msgId (CISSndSent SSPComplete) (Just $ isJust proxy)
SWITCH qd phase cStats -> do
toView $ CRGroupMemberSwitch user gInfo m (SwitchProgress qd phase cStats)
when (phase `elem` [SPStarted, SPCompleted]) $ case qd of
Expand Down Expand Up @@ -4450,13 +4453,15 @@
OK ->
-- [async agent commands] continuation on receiving OK
when (corrId /= "") $ withCompletedCommand conn agentMsg $ \_cmdData -> pure ()
MWARN msgId err ->
withStore' $ \db -> updateGroupItemErrorStatus db msgId (groupMemberId' m) (CISSndWarning $ agentSndError err)
MERR msgId err -> do
withStore' $ \db -> updateGroupItemErrorStatus db msgId (groupMemberId' m) $ agentErrToItemStatus err
withStore' $ \db -> updateGroupItemErrorStatus db msgId (groupMemberId' m) (CISSndError $ agentSndError err)
-- group errors are silenced to reduce load on UI event log
-- toView $ CRChatError (Just user) (ChatErrorAgent err $ Just connEntity)
incAuthErrCounter connEntity conn err
MERRS msgIds err -> do
let newStatus = agentErrToItemStatus err
let newStatus = CISSndError $ agentSndError err
-- error cannot be AUTH error here
withStore' $ \db -> forM_ msgIds $ \msgId ->
updateGroupItemErrorStatus db msgId (groupMemberId' m) newStatus `catchAll_` pure ()
Expand Down Expand Up @@ -4517,7 +4522,7 @@
updateDirectCIFileStatus db vr user fileId $ CIFSSndTransfer 0 1
toView $ CRSndFileStart user ci ft
sendFileChunk user ft
SENT msgId -> do
SENT msgId _proxy -> do
withStore' $ \db -> updateSndFileChunkSent db ft msgId
unless (fileStatus == FSCancelled) $ sendFileChunk user ft
MERR _ err -> do
Expand Down Expand Up @@ -4729,9 +4734,21 @@
sentMsgDeliveryEvent Connection {connId} msgId =
withStore' $ \db -> updateSndMsgDeliveryStatus db connId msgId MDSSndSent

agentErrToItemStatus :: AgentErrorType -> CIStatus 'MDSnd
agentErrToItemStatus (SMP _ AUTH) = CISSndErrorAuth
agentErrToItemStatus err = CISSndError . T.unpack . safeDecodeUtf8 $ strEncode err
agentSndError :: AgentErrorType -> SndError
agentSndError = \case
SMP _ AUTH -> SndErrAuth
SMP _ QUOTA -> SndErrQuota
BROKER _ e -> brokerError SndErrRelay e
SMP proxySrv (SMP.PROXY (SMP.BROKER e)) -> brokerError (SndErrProxy proxySrv) e
AP.PROXY proxySrv _ (ProxyProtocolError (SMP.PROXY (SMP.BROKER e))) -> brokerError (SndErrProxyRelay proxySrv) e
e -> SndErrOther . safeDecodeUtf8 $ strEncode e
where
brokerError srvErr = \case
NETWORK -> SndErrExpired
TIMEOUT -> SndErrExpired
HOST -> srvErr SrvErrHost
SMP.TRANSPORT TEVersion -> srvErr SrvErrVersion
e -> srvErr . SrvErrOther . safeDecodeUtf8 $ strEncode e

badRcvFileChunk :: RcvFileTransfer -> String -> CM ()
badRcvFileChunk ft err =
Expand Down Expand Up @@ -6060,7 +6077,7 @@
checkIntegrityCreateItem (CDGroupRcv gInfo m) msgMeta `catchChatError` \_ -> pure ()
forM_ msgRcpts $ \MsgReceipt {agentMsgId, msgRcptStatus} -> do
withStore' $ \db -> updateSndMsgDeliveryStatus db connId agentMsgId $ MDSSndRcvd msgRcptStatus
updateGroupItemStatus gInfo m conn agentMsgId $ CISSndRcvd msgRcptStatus SSPComplete
updateGroupItemStatus gInfo m conn agentMsgId (CISSndRcvd msgRcptStatus SSPComplete) Nothing

updateDirectItemsStatus :: Contact -> Connection -> [AgentMsgId] -> CIStatus 'MDSnd -> CM ()
updateDirectItemsStatus ct conn msgIds newStatus = do
Expand Down Expand Up @@ -6097,11 +6114,12 @@
| otherwise -> updateGroupSndStatus db itemId groupMemberId newStatus $> True
_ -> pure False

updateGroupItemStatus :: GroupInfo -> GroupMember -> Connection -> AgentMsgId -> CIStatus 'MDSnd -> CM ()
updateGroupItemStatus gInfo@GroupInfo {groupId} GroupMember {groupMemberId} Connection {connId} msgId newMemStatus =
updateGroupItemStatus :: GroupInfo -> GroupMember -> Connection -> AgentMsgId -> CIStatus 'MDSnd -> Maybe Bool -> CM ()
updateGroupItemStatus gInfo@GroupInfo {groupId} GroupMember {groupMemberId} Connection {connId} msgId newMemStatus viaProxy_ =
withStore' (\db -> getGroupChatItemByAgentMsgId db user groupId connId msgId) >>= \case
Just (CChatItem SMDSnd ChatItem {meta = CIMeta {itemStatus = CISSndRcvd _ SSPComplete}}) -> pure ()
Just (CChatItem SMDSnd ChatItem {meta = CIMeta {itemId, itemStatus}}) -> do
forM_ viaProxy_ $ \viaProxy -> withStore' $ \db -> setGroupSndViaProxy db itemId groupMemberId viaProxy
memStatusChanged <- updateGroupMemSndStatus itemId groupMemberId newMemStatus
when memStatusChanged $ do
memStatusCounts <- withStore' (`getGroupSndStatusCounts` itemId)
Expand Down Expand Up @@ -6724,7 +6742,7 @@
mkChatItem cd ciId content file quotedItem sharedMsgId itemForwarded itemTimed live itemTs forwardedByMember currentTs =
let itemText = ciContentToText content
itemStatus = ciCreateStatus content
meta = mkCIMeta ciId content itemText itemStatus sharedMsgId itemForwarded Nothing False itemTimed (justTrue live) currentTs itemTs forwardedByMember currentTs currentTs
meta = mkCIMeta ciId content itemText itemStatus Nothing sharedMsgId itemForwarded Nothing False itemTimed (justTrue live) currentTs itemTs forwardedByMember currentTs currentTs
in ChatItem {chatDir = toCIDirection cd, meta, content, formattedText = parseMaybeMarkdownList itemText, quotedItem, reactions = [], file}

deleteDirectCI :: MsgDirectionI d => User -> Contact -> ChatItem 'CTDirect d -> Bool -> Bool -> CM ChatResponse
Expand Down