core: simplify feature versions (#3879)

* core: simplify feature versions

* update version agreement

* fix

* remove EmptyCase
This commit is contained in:
Evgeny Poberezkin
2024-03-08 13:36:09 +00:00
committed by GitHub
parent 405348732b
commit 1f93d91af5
8 changed files with 83 additions and 96 deletions
+18 -22
View File
@@ -52,7 +52,7 @@ import Simplex.Messaging.Encoding
import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, fromTextField_, fstToLower, parseAll, sumTypeJSON, taggedObjectJSON)
import Simplex.Messaging.Protocol (MsgBody)
import Simplex.Messaging.Util (eitherToMaybe, safeDecodeUtf8, (<$$>), (<$?>))
import Simplex.Messaging.Util (eitherToMaybe, safeDecodeUtf8, (<$?>))
import Simplex.Messaging.Version hiding (version)
-- This should not be used directly in code, instead use `maxVersion chatVRange` from ChatConfig.
@@ -65,41 +65,37 @@ currentChatVersion = VersionChat 7
-- TODO remove parameterization in 5.7
supportedChatVRange :: PQSupport -> VersionRangeChat
supportedChatVRange pq = mkVersionRange (VersionChat 1) $ case pq of
PQSupportOn -> compressedBatchingVersion
PQSupportOn -> pqEncryptionCompressionVersion
PQSupportOff -> currentChatVersion
{-# INLINE supportedChatVRange #-}
-- version range that supports skipping establishing direct connections in a group
groupNoDirectVRange :: VersionRangeChat
groupNoDirectVRange = mkVersionRange (VersionChat 2) currentChatVersion
-- version range that supports establishing direct connection via x.grp.direct.inv with a group member
xGrpDirectInvVRange :: VersionRangeChat
xGrpDirectInvVRange = mkVersionRange (VersionChat 2) currentChatVersion
-- version range that supports skipping establishing direct connections in a group and establishing direct connection via x.grp.direct.inv
groupDirectInvVersion :: VersionChat
groupDirectInvVersion = VersionChat 2
-- version range that supports joining group via group link without creating direct contact
groupLinkNoContactVRange :: VersionRangeChat
groupLinkNoContactVRange = mkVersionRange (VersionChat 3) currentChatVersion
groupFastLinkJoinVersion :: VersionChat
groupFastLinkJoinVersion = VersionChat 3
-- version range that supports group forwarding
groupForwardVRange :: VersionRangeChat
groupForwardVRange = mkVersionRange (VersionChat 4) currentChatVersion
groupForwardVersion :: VersionChat
groupForwardVersion = VersionChat 4
-- version range that supports batch sending in groups
batchSendVRange :: VersionRangeChat
batchSendVRange = mkVersionRange (VersionChat 5) currentChatVersion
batchSendVersion :: VersionChat
batchSendVersion = VersionChat 5
-- version range that supports sending group welcome message in group history
groupHistoryIncludeWelcomeVRange :: VersionRangeChat
groupHistoryIncludeWelcomeVRange = mkVersionRange (VersionChat 6) currentChatVersion
groupHistoryIncludeWelcomeVersion :: VersionChat
groupHistoryIncludeWelcomeVersion = VersionChat 6
-- version range that supports sending member profile updates to groups
memberProfileUpdateVRange :: VersionRangeChat
memberProfileUpdateVRange = mkVersionRange (VersionChat 7) currentChatVersion
memberProfileUpdateVersion :: VersionChat
memberProfileUpdateVersion = VersionChat 7
-- version range that supports compressing messages
compressedBatchingVersion :: VersionChat
compressedBatchingVersion = VersionChat 8
-- version range that supports compressing messages and PQ e2e encryption
pqEncryptionCompressionVersion :: VersionChat
pqEncryptionCompressionVersion = VersionChat 8
data ConnectionEntity
= RcvDirectMsgConnection {entityConnection :: Connection, contact :: Maybe Contact}
+16 -16
View File
@@ -133,7 +133,7 @@ import Data.Time.Clock (UTCTime (..), getCurrentTime)
import Database.SQLite.Simple (NamedParam (..), Only (..), Query (..), (:.) (..))
import Database.SQLite.Simple.QQ (sql)
import Simplex.Chat.Messages
import Simplex.Chat.Protocol (groupForwardVRange)
import Simplex.Chat.Protocol (groupForwardVersion)
import Simplex.Chat.Store.Direct
import Simplex.Chat.Store.Shared
import Simplex.Chat.Types
@@ -156,7 +156,7 @@ type MaybeGroupMemberRow = ((Maybe Int64, Maybe Int64, Maybe MemberId, Maybe Ver
toGroupInfo :: VersionRangeChat -> Int64 -> GroupInfoRow -> GroupInfo
toGroupInfo vr userContactId ((groupId, localDisplayName, displayName, fullName, description, image, hostConnCustomUserProfileId, enableNtfs_, sendRcpts, favorite, groupPreferences) :. (createdAt, updatedAt, chatTs, userMemberProfileSentAt) :. userMemberRow) =
let membership = (toGroupMember userContactId userMemberRow) {memberChatVRange = JVersionRange vr}
let membership = (toGroupMember userContactId userMemberRow) {memberChatVRange = vr}
chatSettings = ChatSettings {enableNtfs = fromMaybe MFAll enableNtfs_, sendRcpts, favorite}
fullGroupPreferences = mergeGroupPreferences groupPreferences
groupProfile = GroupProfile {displayName, fullName, description, image, groupPreferences}
@@ -169,7 +169,7 @@ toGroupMember userContactId ((groupMemberId, groupId, memberId, minVer, maxVer,
blockedByAdmin = maybe False mrsBlocked memberRestriction_
invitedBy = toInvitedBy userContactId invitedById
activeConn = Nothing
memberChatVRange = JVersionRange $ fromMaybe (versionToRange maxVer) $ safeVersionRange minVer maxVer
memberChatVRange = fromMaybe (versionToRange maxVer) $ safeVersionRange minVer maxVer
in GroupMember {..}
toMaybeGroupMember :: Int64 -> MaybeGroupMemberRow -> Maybe GroupMember
@@ -393,7 +393,7 @@ createGroupInvitation db vr user@User {userId} contact@Contact {contactId, activ
|]
(profileId, localDisplayName, connRequest, customUserProfileId, userId, True, currentTs, currentTs, currentTs, currentTs)
insertedRowId db
let JVersionRange hostVRange = peerChatVRange
let hostVRange = peerChatVRange
GroupMember {groupMemberId} <- createContactMemberInv_ db user groupId Nothing contact fromMember GCHostMember GSMemInvited IBUnknown Nothing currentTs hostVRange
membership <- createContactMemberInv_ db user groupId (Just groupMemberId) user invitedMember GCUserMember GSMemInvited (IBContact contactId) incognitoProfileId currentTs vr
let chatSettings = ChatSettings {enableNtfs = MFAll, sendRcpts = Nothing, favorite = False}
@@ -444,7 +444,7 @@ createContactMemberInv_ db User {userId, userContactId} groupId invitedByGroupMe
memberContactId = Just $ contactId' userOrContact,
memberContactProfileId = localProfileId (profile' userOrContact),
activeConn = Nothing,
memberChatVRange = JVersionRange memberChatVRange
memberChatVRange
}
where
insertMember_ :: IO ContactName
@@ -789,10 +789,10 @@ createNewContactMember db gVar User {userId, userContactId} GroupInfo {groupId,
createWithRandomId gVar $ \memId -> do
createdAt <- liftIO getCurrentTime
member@GroupMember {groupMemberId} <- createMember_ (MemberId memId) createdAt
void $ createMemberConnection_ db userId groupMemberId agentConnId (fromJVersionRange peerChatVRange) Nothing 0 createdAt subMode
void $ createMemberConnection_ db userId groupMemberId agentConnId peerChatVRange Nothing 0 createdAt subMode
pure member
where
JVersionRange (VersionRange minV maxV) = peerChatVRange
VersionRange minV maxV = peerChatVRange
invitedByGroupMemberId = groupMemberId' membership
createMember_ memberId createdAt = do
insertMember_
@@ -873,7 +873,7 @@ createAcceptedMember
groupMemberId <- liftIO $ insertedRowId db
pure (groupMemberId, MemberId memId)
where
JVersionRange (VersionRange minV maxV) = cReqChatVRange
VersionRange minV maxV = cReqChatVRange
insertMember_ memberId createdAt =
DB.execute
db
@@ -898,7 +898,7 @@ createAcceptedMemberConnection
groupMemberId
subMode = do
createdAt <- liftIO getCurrentTime
Connection {connId} <- createConnection_ db userId ConnMember (Just groupMemberId) agentConnId (fromJVersionRange cReqChatVRange) Nothing (Just userContactLinkId) Nothing 0 createdAt subMode PQSupportOff
Connection {connId} <- createConnection_ db userId ConnMember (Just groupMemberId) agentConnId cReqChatVRange Nothing (Just userContactLinkId) Nothing 0 createdAt subMode PQSupportOff
setCommandConnId db user cmdId connId
getContactViaMember :: DB.Connection -> User -> GroupMember -> ExceptT StoreError IO Contact
@@ -1002,7 +1002,7 @@ createNewMember_
createdAt = do
let invitedById = fromInvitedBy userContactId invitedBy
activeConn = Nothing
mcvr@(VersionRange minV maxV) = maybe chatInitialVRange fromChatVRange memChatVRange
memberChatVRange@(VersionRange minV maxV) = maybe chatInitialVRange fromChatVRange memChatVRange
DB.execute
db
[sql|
@@ -1034,7 +1034,7 @@ createNewMember_
memberContactId,
memberContactProfileId,
activeConn,
memberChatVRange = JVersionRange mcvr
memberChatVRange
}
checkGroupMemberHasItems :: DB.Connection -> User -> GroupMember -> IO (Maybe ChatItemId)
@@ -1174,7 +1174,7 @@ getForwardIntroducedMembers db user invitee highlyAvailable = do
DB.query
db
(q <> " AND intro_chat_protocol_version >= ?")
(mId, GMIntroReConnected, GMIntroToConnected, GMIntroConnected, minVersion groupForwardVRange)
(mId, GMIntroReConnected, GMIntroToConnected, GMIntroConnected, groupForwardVersion)
q =
[sql|
SELECT re_group_member_id
@@ -1194,7 +1194,7 @@ getForwardInvitedMembers db user forwardMember highlyAvailable = do
DB.query
db
(q <> " AND intro_chat_protocol_version >= ?")
(mId, GMIntroReConnected, GMIntroToConnected, GMIntroConnected, minVersion groupForwardVRange)
(mId, GMIntroReConnected, GMIntroToConnected, GMIntroConnected, groupForwardVersion)
q =
[sql|
SELECT to_group_member_id
@@ -1882,7 +1882,7 @@ createMemberContact
cReq
gInfo
GroupMember {groupMemberId, localDisplayName, memberProfile, memberContactProfileId}
Connection {connLevel, peerChatVRange = peerChatVRange@(JVersionRange (VersionRange minV maxV))}
Connection {connLevel, peerChatVRange = peerChatVRange@(VersionRange minV maxV)}
subMode = do
currentTs <- getCurrentTime
let incognitoProfile = incognitoMembershipProfile gInfo
@@ -2030,7 +2030,7 @@ createMemberContactConn_
user@User {userId}
(cmdId, acId)
gInfo
_memberConn@Connection {connLevel, peerChatVRange = peerChatVRange@(JVersionRange (VersionRange minV maxV))}
_memberConn@Connection {connLevel, peerChatVRange = peerChatVRange@(VersionRange minV maxV)}
contactId
subMode = do
currentTs <- liftIO getCurrentTime
@@ -2169,7 +2169,7 @@ updateUnknownMemberAnnounced db user@User {userId} invitingMember unknownMember@
)
getGroupMemberById db user groupMemberId
where
VersionRange minV maxV = maybe (fromJVersionRange memberChatVRange) fromChatVRange v
VersionRange minV maxV = maybe memberChatVRange fromChatVRange v
updateUserMemberProfileSentAt :: DB.Connection -> User -> GroupInfo -> UTCTime -> IO ()
updateUserMemberProfileSentAt db User {userId} GroupInfo {groupId} sentTs =
+3 -3
View File
@@ -160,7 +160,7 @@ toConnection ((connId, acId, connLevel, viaContact, viaUserContactLink, viaGroup
Connection
{ connId,
agentConnId = AgentConnId acId,
peerChatVRange = JVersionRange $ fromMaybe (versionToRange maxVer) $ safeVersionRange minVer maxVer,
peerChatVRange = fromMaybe (versionToRange maxVer) $ safeVersionRange minVer maxVer,
connLevel,
viaContact,
viaUserContactLink,
@@ -216,7 +216,7 @@ createConnection_ db userId connType entityId acId peerChatVRange@(VersionRange
Connection
{ connId,
agentConnId = AgentConnId acId,
peerChatVRange = JVersionRange peerChatVRange,
peerChatVRange,
connType,
contactConnInitiated = False,
entityId,
@@ -397,7 +397,7 @@ type ContactRequestRow = (Int64, ContactName, AgentInvId, Int64, AgentConnId, In
toContactRequest :: ContactRequestRow -> UserContactRequest
toContactRequest ((contactRequestId, localDisplayName, agentInvitationId, userContactLinkId, agentContactConnId, profileId, displayName, fullName, image, contactLink) :. (xContactId, pqSupport, preferences, createdAt, updatedAt, minVer, maxVer)) = do
let profile = Profile {displayName, fullName, image, contactLink, preferences}
cReqChatVRange = JVersionRange $ fromMaybe (versionToRange maxVer) $ safeVersionRange minVer maxVer
cReqChatVRange = fromMaybe (versionToRange maxVer) $ safeVersionRange minVer maxVer
in UserContactRequest {contactRequestId, agentInvitationId, userContactLinkId, agentContactConnId, cReqChatVRange, localDisplayName, profileId, profile, xContactId, pqSupport, createdAt, updatedAt}
userQuery :: Query
+11 -20
View File
@@ -329,7 +329,7 @@ data UserContactRequest = UserContactRequest
agentInvitationId :: AgentInvId,
userContactLinkId :: Int64,
agentContactConnId :: AgentConnId, -- connection id of user contact
cReqChatVRange :: JVersionRange,
cReqChatVRange :: VersionRangeChat,
localDisplayName :: ContactName,
profileId :: Int64,
profile :: Profile,
@@ -660,7 +660,7 @@ memberInfo GroupMember {memberId, memberRole, memberProfile, activeConn} =
MemberInfo
{ memberId,
memberRole,
v = ChatVersionRange . fromJVersionRange . peerChatVRange <$> activeConn,
v = ChatVersionRange . peerChatVRange <$> activeConn,
profile = redactedMemberProfile $ fromLocalProfile memberProfile
}
@@ -742,7 +742,7 @@ data GroupMember = GroupMember
-- member chat protocol version range; if member has active connection, its version range is preferred;
-- for membership current supportedChatVRange is set, it's not updated on protocol version increase in database,
-- but it's correctly set on read (see toGroupInfo)
memberChatVRange :: JVersionRange
memberChatVRange :: VersionRangeChat
}
deriving (Eq, Show)
@@ -760,10 +760,12 @@ memberConnId :: GroupMember -> Maybe ConnId
memberConnId GroupMember {activeConn} = aConnId <$> activeConn
memberChatVRange' :: GroupMember -> VersionRangeChat
memberChatVRange' GroupMember {activeConn, memberChatVRange} =
fromJVersionRange $ case activeConn of
Just Connection {peerChatVRange} -> peerChatVRange
Nothing -> memberChatVRange
memberChatVRange' GroupMember {activeConn, memberChatVRange} = case activeConn of
Just Connection {peerChatVRange} -> peerChatVRange
Nothing -> memberChatVRange
supportsVersion :: GroupMember -> VersionChat -> Bool
supportsVersion m v = maxVersion (memberChatVRange' m) >= v
groupMemberId' :: GroupMember -> GroupMemberId
groupMemberId' GroupMember {groupMemberId} = groupMemberId
@@ -1340,7 +1342,7 @@ type ConnReqContact = ConnectionRequestUri 'CMContact
data Connection = Connection
{ connId :: Int64,
agentConnId :: AgentConnId,
peerChatVRange :: JVersionRange,
peerChatVRange :: VersionRangeChat,
connLevel :: Int,
viaContact :: Maybe Int64, -- group member contact ID, if not direct connection
viaUserContactLink :: Maybe Int64, -- user contact link ID, if connected via "user address"
@@ -1694,6 +1696,7 @@ type VersionRangeChat = VersionRange ChatVersion
pattern VersionChat :: Word16 -> VersionChat
pattern VersionChat v = Version v
-- this newtype exists to have a concise JSON encoding of version ranges in chat protocol messages in the form of "1-2" or just "1"
newtype ChatVersionRange = ChatVersionRange {fromChatVRange :: VersionRangeChat} deriving (Eq, Show)
initialChatVersion :: VersionChat
@@ -1709,18 +1712,6 @@ instance ToJSON ChatVersionRange where
toJSON (ChatVersionRange vr) = strToJSON vr
toEncoding (ChatVersionRange vr) = strToJEncoding vr
newtype JVersionRange = JVersionRange {fromJVersionRange :: VersionRangeChat} deriving (Eq, Show)
instance FromJSON JVersionRange where
parseJSON = J.withObject "JVersionRange" $ \o -> do
minv <- o .: "minVersion"
maxv <- o .: "maxVersion"
maybe (fail "bad version range") (pure . JVersionRange) $ safeVersionRange minv maxv
instance ToJSON JVersionRange where
toJSON (JVersionRange (VersionRange minV maxV)) = J.object ["minVersion" .= minV, "maxVersion" .= maxV]
toEncoding (JVersionRange (VersionRange minV maxV)) = J.pairs $ "minVersion" .= minV <> "maxVersion" .= maxV
$(JQ.deriveJSON defaultJSON ''UserContact)
$(JQ.deriveJSON defaultJSON ''Profile)
+2 -2
View File
@@ -1200,8 +1200,8 @@ viewConnectionVerified :: Maybe SecurityCode -> StyledString
viewConnectionVerified (Just _) = "connection verified" -- TODO show verification time?
viewConnectionVerified _ = "connection not verified, use " <> highlight' "/code" <> " command to see security code"
viewPeerChatVRange :: JVersionRange -> StyledString
viewPeerChatVRange (JVersionRange (VersionRange minVer maxVer)) = "peer chat protocol version range: (" <> sShow minVer <> ", " <> sShow maxVer <> ")"
viewPeerChatVRange :: VersionRangeChat -> StyledString
viewPeerChatVRange (VersionRange minVer maxVer) = "peer chat protocol version range: (" <> sShow minVer <> ", " <> sShow maxVer <> ")"
viewConnectionStats :: ConnectionStats -> [StyledString]
viewConnectionStats ConnectionStats {rcvQueuesInfo, sndQueuesInfo} =