More tweaks to fix crash

Wrapped the force sync calls within their own Storage.write blocks to ensure they have the latest data and aren't accessing a transaction completed in a different thread
Reverted a number of the unneeded changes
pull/604/head
Morgan Pretty 3 years ago
parent 1214005c59
commit 29c53223e0

@ -1183,7 +1183,7 @@ extension ConversationVC {
// Send a sync message with the details of the contact // Send a sync message with the details of the contact
if let appDelegate = UIApplication.shared.delegate as? AppDelegate { if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.forceSyncConfigurationNowIfNeeded(with: transaction).retainUntilComplete() appDelegate.forceSyncConfigurationNowIfNeeded().retainUntilComplete()
} }
} }
} }

@ -22,14 +22,17 @@ extension AppDelegate {
} }
} }
func forceSyncConfigurationNowIfNeeded(with transaction: YapDatabaseReadWriteTransaction? = nil) -> Promise<Void> { func forceSyncConfigurationNowIfNeeded() -> Promise<Void> {
guard Storage.shared.getUser()?.name != nil, let configurationMessage = ConfigurationMessage.getCurrent(with: transaction) else {
return Promise.value(())
}
let destination = Message.Destination.contact(publicKey: getUserHexEncodedPublicKey()) let destination = Message.Destination.contact(publicKey: getUserHexEncodedPublicKey())
let (promise, seal) = Promise<Void>.pending() let (promise, seal) = Promise<Void>.pending()
// Note: SQLite only supports a single write thread so we can be sure this will retrieve the most up-to-date data
Storage.writeSync { transaction in Storage.writeSync { transaction in
guard Storage.shared.getUser()?.name != nil, let configurationMessage = ConfigurationMessage.getCurrent() else {
seal.fulfill(())
return
}
MessageSender.send(configurationMessage, to: destination, using: transaction).done { MessageSender.send(configurationMessage, to: destination, using: transaction).done {
seal.fulfill(()) seal.fulfill(())
}.catch { _ in }.catch { _ in

@ -10,20 +10,14 @@ extension Storage {
private static let closedGroupZombieMembersCollection = "SNClosedGroupZombieMembersCollection" private static let closedGroupZombieMembersCollection = "SNClosedGroupZombieMembersCollection"
public func getClosedGroupEncryptionKeyPairs(for groupPublicKey: String) -> [ECKeyPair] { public func getClosedGroupEncryptionKeyPairs(for groupPublicKey: String) -> [ECKeyPair] {
var result: [ECKeyPair] = []
Storage.read { transaction in
result = self.getClosedGroupEncryptionKeyPairs(for: groupPublicKey, using: transaction)
}
return result
}
public func getClosedGroupEncryptionKeyPairs(for groupPublicKey: String, using transaction: YapDatabaseReadTransaction) -> [ECKeyPair] {
let collection = Storage.getClosedGroupEncryptionKeyPairCollection(for: groupPublicKey) let collection = Storage.getClosedGroupEncryptionKeyPairCollection(for: groupPublicKey)
var timestampsAndKeyPairs: [(timestamp: Double, keyPair: ECKeyPair)] = [] var timestampsAndKeyPairs: [(timestamp: Double, keyPair: ECKeyPair)] = []
Storage.read { transaction in
transaction.enumerateKeysAndObjects(inCollection: collection) { key, object, _ in transaction.enumerateKeysAndObjects(inCollection: collection) { key, object, _ in
guard let timestamp = Double(key), let keyPair = object as? ECKeyPair else { return } guard let timestamp = Double(key), let keyPair = object as? ECKeyPair else { return }
timestampsAndKeyPairs.append((timestamp, keyPair)) timestampsAndKeyPairs.append((timestamp, keyPair))
} }
}
return timestampsAndKeyPairs.sorted { $0.timestamp < $1.timestamp }.map { $0.keyPair } return timestampsAndKeyPairs.sorted { $0.timestamp < $1.timestamp }.map { $0.keyPair }
} }
@ -31,10 +25,6 @@ extension Storage {
return getClosedGroupEncryptionKeyPairs(for: groupPublicKey).last return getClosedGroupEncryptionKeyPairs(for: groupPublicKey).last
} }
public func getLatestClosedGroupEncryptionKeyPair(for groupPublicKey: String, using transaction: YapDatabaseReadTransaction) -> ECKeyPair? {
return getClosedGroupEncryptionKeyPairs(for: groupPublicKey, using: transaction).last
}
public func addClosedGroupEncryptionKeyPair(_ keyPair: ECKeyPair, for groupPublicKey: String, using transaction: Any) { public func addClosedGroupEncryptionKeyPair(_ keyPair: ECKeyPair, for groupPublicKey: String, using transaction: Any) {
let collection = Storage.getClosedGroupEncryptionKeyPairCollection(for: groupPublicKey) let collection = Storage.getClosedGroupEncryptionKeyPairCollection(for: groupPublicKey)
let timestamp = String(Date().timeIntervalSince1970) let timestamp = String(Date().timeIntervalSince1970)
@ -49,15 +39,11 @@ extension Storage {
public func getUserClosedGroupPublicKeys() -> Set<String> { public func getUserClosedGroupPublicKeys() -> Set<String> {
var result: Set<String> = [] var result: Set<String> = []
Storage.read { transaction in Storage.read { transaction in
result = self.getUserClosedGroupPublicKeys(using: transaction) result = Set(transaction.allKeys(inCollection: Storage.closedGroupPublicKeyCollection))
} }
return result return result
} }
public func getUserClosedGroupPublicKeys(using transaction: YapDatabaseReadTransaction) -> Set<String> {
return Set(transaction.allKeys(inCollection: Storage.closedGroupPublicKeyCollection))
}
public func addClosedGroupPublicKey(_ groupPublicKey: String, using transaction: Any) { public func addClosedGroupPublicKey(_ groupPublicKey: String, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).setObject(groupPublicKey, forKey: groupPublicKey, inCollection: Storage.closedGroupPublicKeyCollection) (transaction as! YapDatabaseReadWriteTransaction).setObject(groupPublicKey, forKey: groupPublicKey, inCollection: Storage.closedGroupPublicKeyCollection)
} }
@ -95,8 +81,4 @@ extension Storage {
public func isClosedGroup(_ publicKey: String) -> Bool { public func isClosedGroup(_ publicKey: String) -> Bool {
getUserClosedGroupPublicKeys().contains(publicKey) getUserClosedGroupPublicKeys().contains(publicKey)
} }
public func isClosedGroup(_ publicKey: String, using transaction: YapDatabaseReadTransaction) -> Bool {
getUserClosedGroupPublicKeys(using: transaction).contains(publicKey)
}
} }

@ -36,21 +36,12 @@ extension Storage {
} }
@objc public func getUser() -> Contact? { @objc public func getUser() -> Contact? {
return getUser(using: nil)
}
public func getUser(using transaction: YapDatabaseReadTransaction?) -> Contact? {
let userPublicKey = getUserHexEncodedPublicKey() let userPublicKey = getUserHexEncodedPublicKey()
var result: Contact? var result: Contact?
if let transaction = transaction {
result = Storage.shared.getContact(with: userPublicKey, using: transaction)
}
else {
Storage.read { transaction in Storage.read { transaction in
result = Storage.shared.getContact(with: userPublicKey, using: transaction) result = Storage.shared.getContact(with: userPublicKey, using: transaction)
} }
}
return result return result
} }
} }

@ -2,9 +2,9 @@ import SessionUtilitiesKit
extension ConfigurationMessage { extension ConfigurationMessage {
public static func getCurrent(with transaction: YapDatabaseReadWriteTransaction? = nil) -> ConfigurationMessage? { public static func getCurrent() -> ConfigurationMessage? {
let storage = Storage.shared let storage = Storage.shared
guard let user = storage.getUser(using: transaction) else { return nil } guard let user = storage.getUser() else { return nil }
let displayName = user.name let displayName = user.name
let profilePictureURL = user.profilePictureURL let profilePictureURL = user.profilePictureURL
@ -13,7 +13,7 @@ extension ConfigurationMessage {
var openGroups: Set<String> = [] var openGroups: Set<String> = []
var contacts: Set<ConfigurationMessage.Contact> = [] var contacts: Set<ConfigurationMessage.Contact> = []
let populateDataClosure: (YapDatabaseReadTransaction) -> () = { transaction in Storage.read { transaction in
TSGroupThread.enumerateCollectionObjects(with: transaction) { object, _ in TSGroupThread.enumerateCollectionObjects(with: transaction) { object, _ in
guard let thread = object as? TSGroupThread else { return } guard let thread = object as? TSGroupThread else { return }
@ -24,10 +24,7 @@ extension ConfigurationMessage {
let groupID = thread.groupModel.groupId let groupID = thread.groupModel.groupId
let groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID) let groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID)
guard guard storage.isClosedGroup(groupPublicKey), let encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey) else {
storage.isClosedGroup(groupPublicKey, using: transaction),
let encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(for: groupPublicKey, using: transaction)
else {
return return
} }
@ -93,15 +90,6 @@ extension ConfigurationMessage {
.asSet() .asSet()
} }
// If we are provided with a transaction then read the data based on the state of the database
// from within the transaction rather than the state in disk
if let transaction: YapDatabaseReadWriteTransaction = transaction {
populateDataClosure(transaction)
}
else {
Storage.read { transaction in populateDataClosure(transaction) }
}
return ConfigurationMessage( return ConfigurationMessage(
displayName: displayName, displayName: displayName,
profilePictureURL: profilePictureURL, profilePictureURL: profilePictureURL,

@ -17,18 +17,15 @@ public protocol SessionMessagingKitStorageProtocol {
func getUserKeyPair() -> ECKeyPair? func getUserKeyPair() -> ECKeyPair?
func getUserED25519KeyPair() -> Box.KeyPair? func getUserED25519KeyPair() -> Box.KeyPair?
func getUser() -> Contact? func getUser() -> Contact?
func getUser(using transaction: YapDatabaseReadTransaction?) -> Contact?
func getAllContacts() -> Set<Contact> func getAllContacts() -> Set<Contact>
func getAllContacts(with transaction: YapDatabaseReadTransaction) -> Set<Contact> func getAllContacts(with transaction: YapDatabaseReadTransaction) -> Set<Contact>
// MARK: - Closed Groups // MARK: - Closed Groups
func getUserClosedGroupPublicKeys() -> Set<String> func getUserClosedGroupPublicKeys() -> Set<String>
func getUserClosedGroupPublicKeys(using transaction: YapDatabaseReadTransaction) -> Set<String>
func getZombieMembers(for groupPublicKey: String) -> Set<String> func getZombieMembers(for groupPublicKey: String) -> Set<String>
func setZombieMembers(for groupPublicKey: String, to zombies: Set<String>, using transaction: Any) func setZombieMembers(for groupPublicKey: String, to zombies: Set<String>, using transaction: Any)
func isClosedGroup(_ publicKey: String) -> Bool func isClosedGroup(_ publicKey: String) -> Bool
func isClosedGroup(_ publicKey: String, using transaction: YapDatabaseReadTransaction) -> Bool
// MARK: - Jobs // MARK: - Jobs

Loading…
Cancel
Save