@ -213,81 +213,90 @@ public extension LibSession {
let ed25519KeyPair : KeyPair = Identity . fetchUserEd25519KeyPair ( db )
else { return Log . warn ( . libSession , " Ignoring loadState due to existing state " ) }
// R e t r i e v e t h e e x i s t i n g d u m p s f r o m t h e d a t a b a s e
let existingDumps : [ ConfigDump ] = ( ( try ? ConfigDump . fetchSet ( db ) ) ? ? [ ] )
. sorted { lhs , rhs in lhs . variant . loadOrder < rhs . variant . loadOrder }
let existingDumpVariants : Set < ConfigDump . Variant > = existingDumps
. map { $0 . variant }
. asSet ( )
let missingRequiredVariants : Set < ConfigDump . Variant > = ConfigDump . Variant . userVariants
. subtracting ( existingDumpVariants )
let groupsByKey : [ String : ClosedGroup ] = ( try ? ClosedGroup
// / R e t r i e v e t h e e x i s t i n g d u m p s f r o m t h e d a t a b a s e
typealias ConfigInfo = ( sessionId : SessionId , variant : ConfigDump . Variant , dump : ConfigDump ? )
let existingDumpsByKey : [ String : [ ConfigDump ] ] = ( ( try ? ConfigDump . fetchAll ( db ) ) ? ? [ ] )
. grouped ( by : \ . sessionId . hexString )
var configsToLoad : [ ConfigInfo ] = [ ]
// / L o a d i n t h e u s e r d u m p s f i r s t ( i t ' s p o s s i b l e f o r a u s e r d u m p t o b e m i s s i n g d u e t o s o m e e d g e - c a s e s s o u s e
// / ` C o n f i g D u m p . V a r i a n t . u s e r V a r i a n t s ` t o e n s u r e w e w i l l a t l e a s t l o a d a d e f a u l t s t a t e a n d j u s t a s s u m e
// / i t w i l l b e f i x e d w h e n w e e v e n t u a l l y p o l l f o r i t )
configsToLoad . append (
contentsOf : ConfigDump . Variant . userVariants
. sorted { $0 . loadOrder < $1 . loadOrder }
. map { variant in
(
userSessionId ,
variant ,
existingDumpsByKey [ userSessionId . hexString ] ?
. first ( where : { $0 . variant = = variant } )
)
}
)
// / T h e n l o a d i n d u m p s f o r g r o u p s
// /
// / S i m i l a r t o t h e a b o v e i t ' s p o s s i b l e t o h a v e a p a r t i a l g r o u p s t a t e d u e t o e d g e - c a s e s w h e r e a c o n f i g c o u l d b e l o s t , b u t a l s o
// / i m m e d i a t e l y a f t e r c r e a t i n g a g r o u p ( e g . w h e n a c r a s h h a p p e n s a t t h e r i g h t t i m e ) , f o r t h e s e c a s e s w e a g a i n a s s u m e t h e y
// / w i l l b e s o l v e d e v e n t u a l l y v i a p o l l i n g s o s t i l l w a n t t o l o a d t h e i r s t a t e s i n t o m e m o r y ( i f w e d o n ' t t h e n w e l i k e l y w o u l d n ' t b e
// / a b l e t o d e c r y p t t h e p o l l r e s p o n s e a n d t h e g r o u p w o u l d n e v e r r e c o v e r )
// /
// / * * N o t e : * * W e e x c l u d e g r o u p s i n t h e ` i n v i t e d ` s t a t e a s t h e y s h o u l d o n l y h a v e t h e i r s t a t e l o a d e d o n c e t h e i n v i t a t i o n
// / g e t s a c c e p t e d
let allGroups : [ ClosedGroup ] = ( try ? ClosedGroup
. filter (
ClosedGroup . Columns . threadId > SessionId . Prefix . group . rawValue &&
ClosedGroup . Columns . threadId < SessionId . Prefix . group . endOfRangeString
)
. fetchAll ( db )
. reduce ( into : [ : ] ) { result , next in result [ next . threadId ] = next } )
. defaulting ( to : [ : ] )
let groupsWithNoDumps : [ ClosedGroup ] = groupsByKey
. values
. filter { group in ! existingDumps . contains ( where : { $0 . sessionId . hexString = = group . id } ) }
// C r e a t e t h e c o n f i g r e c o r d s f o r e a c h d u m p
existingDumps . forEach { dump in
configStore [ dump . sessionId , dump . variant ] = try ? loadState (
for : dump . variant ,
sessionId : dump . sessionId ,
. filter ( ClosedGroup . Columns . invited = = false )
. fetchAll ( db ) )
. defaulting ( to : [ ] )
let groupsByKey : [ String : ClosedGroup ] = allGroups
. reduce ( into : [ : ] ) { result , group in result [ group . threadId ] = group }
allGroups . forEach { group in
configsToLoad . append (
contentsOf : ConfigDump . Variant . groupVariants
. sorted { $0 . loadOrder < $1 . loadOrder }
. map { variant in
(
SessionId ( . group , hex : group . threadId ) ,
variant ,
existingDumpsByKey [ group . threadId ] ?
. first ( where : { $0 . variant = = variant } )
)
}
)
}
// / N o w t h a t w e h a v e f u l l y p o p u l a t e d a n d s o r t e d ` c o n f i g s T o L o a d ` w e s h o u l d l o a d e a c h i n t o m e m o r y
configsToLoad . forEach { sessionId , variant , dump in
configStore [ sessionId , variant ] = try ? loadState (
for : variant ,
sessionId : sessionId ,
userEd25519SecretKey : ed25519KeyPair . secretKey ,
groupEd25519SecretKey : groupsByKey [ dump . sessionId . hexString ] ?
groupEd25519SecretKey : groupsByKey [ sessionId . hexString ] ?
. groupIdentityPrivateKey
. map { Array ( $0 ) } ,
cachedData : dump . data
cachedData : dump ? .data
)
}
// / I t ' s p o s s i b l e f o r t h e r e t o n o t b e d u m p s f o r a l l o f t h e c o n f i g s s o w e l o a d a n y m i s s i n g o n e s t o e n s u r e f u n c t i o n a l i t y
// / w o r k s s m o o t h l y
// /
// / I t ' s a l s o p o s s i b l e f o r a g r o u p t o g e t c r e a t e d b u t f o r a d u m p t o n o t b e c r e a t e d ( e g . w h e n a c r a s h h a p p e n s a t t h e r i g h t t i m e ) , t o
// / h a n d l e t h i s w e a l s o l o a d t h e s t a t e o f a n y g r o u p s w h i c h d o n ' t h a v e d u m p s i f t h e y a r e n ' t i n t h e ` i n v i t e d ` s t a t e ( t h o s e i n
// / t h e ` i n v i t e d ` s t a t e w i l l h a v e t h e i r s t a t e l o a d e d i f t h e i n v i t e i s a c c e p t e d )
loadDefaultStatesFor (
userConfigVariants : missingRequiredVariants ,
groups : groupsWithNoDumps ,
userSessionId : userSessionId ,
userEd25519KeyPair : ed25519KeyPair
)
Log . info ( . libSession , " Completed loadState " )
}
public func loadDefaultState s For(
userConfigVariants: Set < ConfigDump . Variant > ,
groups: [ ClosedGroup ] ,
user SessionId: SessionId ,
userEd25519KeyPair: KeyPair
public func loadDefaultStateFor (
variant : ConfigDump . Variant ,
sessionId : SessionId ,
userEd25519KeyPair : KeyPair ,
groupEd25519SecretKey : [ UInt8 ] ?
) {
// / C r e a t e a n e m p t y s t a t e f o r t h e s p e c i f i e d u s e r c o n f i g v a r i a n t s
userConfigVariants . forEach { variant in
configStore [ userSessionId , variant ] = try ? loadState (
for : variant ,
sessionId : userSessionId ,
userEd25519SecretKey : userEd25519KeyPair . secretKey ,
groupEd25519SecretKey : nil ,
cachedData : nil
)
}
// / C r e a t e e m p t y g r o u p s t a t e s f o r t h e p r o v i d e d g r o u p s
groups
. filter { $0 . invited != true }
. forEach { group in
_ = try ? createAndLoadGroupState (
groupSessionId : SessionId ( . group , hex : group . id ) ,
userED25519KeyPair : userEd25519KeyPair ,
groupIdentityPrivateKey : group . groupIdentityPrivateKey
)
}
configStore [ sessionId , variant ] = try ? loadState (
for : variant ,
sessionId : sessionId ,
userEd25519SecretKey : userEd25519KeyPair . secretKey ,
groupEd25519SecretKey : groupEd25519SecretKey ,
cachedData : nil
)
}
internal func loadState (
@ -895,11 +904,11 @@ public protocol LibSessionCacheType: LibSessionImmutableCacheType, MutableCacheT
// MARK: - S t a t e M a n a g e m e n t
func loadState ( _ db : Database )
func loadDefaultState s For(
userConfigVariants: Set < ConfigDump . Variant > ,
groups: [ ClosedGroup ] ,
user SessionId: SessionId ,
userEd25519KeyPair: KeyPair
func loadDefaultState For(
variant: ConfigDump . Variant ,
sessionId: SessionId ,
user Ed25519KeyPair: KeyPair ,
groupEd25519SecretKey: [ UInt8 ] ?
)
func hasConfig ( for variant : ConfigDump . Variant , sessionId : SessionId ) -> Bool
func config ( for variant : ConfigDump . Variant , sessionId : SessionId ) -> LibSession . Config ?
@ -988,11 +997,11 @@ private final class NoopLibSessionCache: LibSessionCacheType {
// MARK: - S t a t e M a n a g e m e n t
func loadState ( _ db : Database ) { }
func loadDefaultState s For(
userConfigVariants: Set < ConfigDump . Variant > ,
groups: [ ClosedGroup ] ,
user SessionId: SessionId ,
userEd25519KeyPair: KeyPair
func loadDefaultState For(
variant: ConfigDump . Variant ,
sessionId: SessionId ,
user Ed25519KeyPair: KeyPair ,
groupEd25519SecretKey: [ UInt8 ] ?
) { }
func hasConfig ( for variant : ConfigDump . Variant , sessionId : SessionId ) -> Bool { return false }
func config ( for variant : ConfigDump . Variant , sessionId : SessionId ) -> LibSession . Config ? { return nil }