core: chat relays protocol (#6383)

* core: chat relays protocol wip

* types, notes

* remove file

* removal protocol

* schema

* status

* update

* recovery

* update

* formatting

* rename

* more types

* comment

* more docs

* decrease number of steps

* format

* correct

* update

* update protocol

* update

* typo

* todo

* update doc

* update

* update

* remove added

* update

* update

* XGrpRelayReady

* link to chat relays

* update

* remove from protocol

* update

* json

* wip

* remove comment

* wip

* update

* wip

* wip

* update

* wip

* wip

* plans

* better view

* fix

* fix

* relay acceptance

* rework api

* add relays to link

* comment

* active on con, fix send

* comments

* direct in group plan

* prepare

* member connection wip

* comments

* member connection wip

* fix forwarding

* introduce moderators to new member

* enable relay tests

* plans

* security objectives

* refactor

* add to threat model

* stress test wip

* stress test wip

* Revert "stress test wip"

This reverts commit acde8a1fb3.

* Revert "stress test wip"

This reverts commit 6435808438.

* remove stress test

* improve output

* invert relay fkey

* postgres schema

* comments

* group in progress, remove auto-select relays commented code

* comments

* corrections

* comment

* lint

* redundant import

* core: chat relay request worker (#6509)

* update plans

* strict tables

* core: update group link asynchronously with relay link (#6548)

* update simplexmq

* docs: connection to chat relays rfc (#6554)

* add test for 2 relays (doesn't pass)

* create unknown member in same transaction as checking

* fix relays choosing different memberId (XContactRelay)

* plans, api

* use same incognito profile for relays, connect concurrently, save correct link for plan

* test

* don't duplicate items on group connection

* check relay record exists when joining

* use mapConcurrently when adding relays, update schemas

* fix multi-relay join for postgres (savepoint)

* core: async retry connection to chat relays (#6584)

* update simplexmq

* fix api tests

* prefer throwing temp error on connection

* check group relays when deleting from configuration

* relay_request_err_reason

* relay role

* rename, fix syntax

* plans

* rename, style

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
spaced4ndyandEvgeny Poberezkin authored and GitHub committed 2026-01-21 13:19:06 +00:00
1 parent 2f1816ca32
commit bd8ba4d5c6
46 files changed
+3198 -739

No files matched your search

+13 -4
View File
@@ -248,9 +248,11 @@ data ChatController = ChatController
filesFolder :: TVar (Maybe FilePath), -- path to files folder for mobile apps,
deliveryTaskWorkers :: TMap DeliveryWorkerKey Worker,
deliveryJobWorkers :: TMap DeliveryWorkerKey Worker,
relayRequestWorkers :: TMap Int Worker, -- single global worker with key 1 is used to fit into existing worker management framework
expireCIThreads :: TMap UserId (Maybe (Async ())),
expireCIFlags :: TMap UserId Bool,
cleanupManagerAsync :: TVar (Maybe (Async ())),
relayGroupLinkChecksAsync :: TVar (Maybe (Async ())),
chatActivated :: TVar Bool,
timedItemThreads :: TMap (ChatRef, ChatItemId) (TVar (Maybe (Weak ThreadId))),
showLiveItems :: TVar Bool,
@@ -393,7 +395,7 @@ data ChatCommand
| TestProtoServer AProtoServerWithAuth
| GetUserChatRelays
| SetUserChatRelays [CLINewRelay]
-- TODO [chat relays] commands to test chat relay
-- TODO [relays] commands to test chat relay
-- | APITestChatRelay UserId ConnLinkContact
-- | TestChatRelay ConnLinkContact
| APIGetServerOperators
@@ -465,7 +467,7 @@ data ChatCommand
| APIChangeConnectionUser Int64 UserId -- new user id to switch connection to
| APIConnectPlan {userId :: UserId, connectionLink :: Maybe AConnectionLink} -- Maybe is used to report link parsing failure as special error
| APIPrepareContact UserId ACreatedConnLink ContactShortLinkData
| APIPrepareGroup UserId CreatedLinkContact GroupShortLinkData
| APIPrepareGroup UserId CreatedLinkContact DirectLink GroupShortLinkData
| APIChangePreparedContactUser ContactId UserId
| APIChangePreparedGroupUser GroupId UserId
| APIConnectPreparedContact {contactId :: ContactId, incognito :: IncognitoEnabled, msgContent_ :: Maybe MsgContent}
@@ -507,6 +509,9 @@ data ChatCommand
| ReactToMessage {add :: Bool, reaction :: MsgReaction, chatName :: ChatName, reactToMessage :: Text}
| APINewGroup {userId :: UserId, incognito :: IncognitoEnabled, groupProfile :: GroupProfile}
| NewGroup IncognitoEnabled GroupProfile
-- TODO [relays] owner: TBC group link's default member role for APINewPublicGroup
| APINewPublicGroup {userId :: UserId, incognito :: IncognitoEnabled, relayIds :: NonEmpty Int64, groupProfile :: GroupProfile}
| NewPublicGroup IncognitoEnabled (NonEmpty Int64) GroupProfile
| AddMember GroupName ContactName GroupMemberRole
| JoinGroup {groupName :: GroupName, enableNtfs :: MsgFilter}
| AcceptMember GroupName ContactName GroupMemberRole
@@ -681,6 +686,7 @@ data ChatResponse
| CRChatHelp {helpSection :: HelpSection}
| CRWelcome {user :: User}
| CRGroupCreated {user :: User, groupInfo :: GroupInfo}
| CRPublicGroupCreated {user :: User, groupInfo :: GroupInfo, groupLink :: GroupLink, groupRelays :: [GroupRelay]}
| CRGroupMembers {user :: User, group :: Group}
| CRMemberSupportChats {user :: User, groupInfo :: GroupInfo, members :: [GroupMember]}
-- | CRGroupConversationsArchived {user :: User, groupInfo :: GroupInfo, archivedGroupConversations :: [GroupConversation]}
@@ -839,6 +845,7 @@ data ChatEvent
| CEvtHostDisconnected {protocol :: AProtocolType, transportHost :: TransportHost}
| CEvtReceivedGroupInvitation {user :: User, groupInfo :: GroupInfo, contact :: Contact, fromMemberRole :: GroupMemberRole, memberRole :: GroupMemberRole}
| CEvtUserJoinedGroup {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember}
| CEvtGroupLinkRelaysUpdated {user :: User, groupInfo :: GroupInfo, groupLink :: GroupLink, groupRelays :: [GroupRelay]}
| CEvtJoinedGroupMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember} -- there is the same command response
| CEvtJoinedGroupMemberConnecting {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember, member :: GroupMember}
| CEvtMemberAcceptedByOther {user :: User, groupInfo :: GroupInfo, acceptingMember :: GroupMember, member :: GroupMember}
@@ -987,13 +994,15 @@ data ContactAddressPlan
deriving (Show)
data GroupLinkPlan
= GLPOk {groupSLinkData_ :: Maybe GroupShortLinkData}
= GLPOk {direct :: DirectLink, groupSLinkData_ :: Maybe GroupShortLinkData}
| GLPOwnLink {groupInfo :: GroupInfo}
| GLPConnectingConfirmReconnect
| GLPConnectingProhibit {groupInfo_ :: Maybe GroupInfo}
| GLPKnown {groupInfo :: GroupInfo}
deriving (Show)
type DirectLink = Bool
connectionPlanProceed :: ConnectionPlan -> Bool
connectionPlanProceed = \case
CPInvitationLink ilp -> case ilp of
@@ -1007,7 +1016,7 @@ connectionPlanProceed = \case
CAPContactViaAddress _ -> True
_ -> False
CPGroupLink glp -> case glp of
GLPOk _ -> True
GLPOk _direct _ -> True
GLPOwnLink _ -> True
GLPConnectingConfirmReconnect -> True
_ -> False