Fix nested write transaction

pull/162/head
nielsandriesse 5 years ago
parent 2c5b3ecdc1
commit 2e1a157a8e

@ -26,17 +26,8 @@ public class CreatePreKeysOperation: OWSOperation {
if identityKeyManager.identityKeyPair() == nil { if identityKeyManager.identityKeyPair() == nil {
identityKeyManager.generateNewIdentityKeyPair() identityKeyManager.generateNewIdentityKeyPair()
} }
// Loki: We don't generate PreKeyRecords here.
// This is because we need the records to be linked to a contact since we don't have a central server.
// It's done automatically when we generate a pre key bundle to send to a contact (`generatePreKeyBundleForContact:`).
// You can use `getOrCreatePreKeyForContact:` to generate one if needed.
let signedPreKeyRecord = primaryStorage.generateRandomSignedRecord()
signedPreKeyRecord.markAsAcceptedByService()
primaryStorage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord)
primaryStorage.setCurrentSignedPrekeyId(signedPreKeyRecord.id)
print("[Loki] Pre keys created successfully.") SessionManagementProtocol.createPreKeys()
reportSuccess() reportSuccess()
/* Loki: Original code /* Loki: Original code

@ -38,7 +38,7 @@ public class RefreshPreKeysOperation: OWSOperation {
// Loki: Doing this on the global queue to match Signal // Loki: Doing this on the global queue to match Signal
DispatchQueue.global().async { DispatchQueue.global().async {
SessionManagementProtocol.refreshPreKeys() SessionManagementProtocol.refreshSignedPreKey()
self.reportSuccess() self.reportSuccess()
} }

@ -29,7 +29,7 @@ public class RotateSignedPreKeyOperation: OWSOperation {
// Loki: Doing this on the global queue to match Signal // Loki: Doing this on the global queue to match Signal
DispatchQueue.global().async { DispatchQueue.global().async {
SessionManagementProtocol.rotatePreKeys() SessionManagementProtocol.rotateSignedPreKey()
self.reportSuccess() self.reportSuccess()
} }

@ -59,13 +59,13 @@
@try { @try {
return [self throws_loadPreKey:preKeyId]; return [self throws_loadPreKey:preKeyId];
} @catch (NSException *exception) { } @catch (NSException *exception) {
[LKLogger print:[NSString stringWithFormat:@"[Loki] New pre key generated for %@.", pubKey]];
return [self generateAndStorePreKeyForContact:pubKey]; return [self generateAndStorePreKeyForContact:pubKey];
} }
} }
/// Generate prekey for a contact and store it /// Generate prekey for a contact and store it
- (PreKeyRecord *)generateAndStorePreKeyForContact:(NSString *)pubKey { - (PreKeyRecord *)generateAndStorePreKeyForContact:(NSString *)pubKey {
[LKLogger print:[NSString stringWithFormat:@"[Loki] Generating new pre key for: %@.", pubKey]];
OWSAssertDebug(pubKey.length > 0); OWSAssertDebug(pubKey.length > 0);
NSArray<PreKeyRecord *> *records = [self generatePreKeyRecords:1]; NSArray<PreKeyRecord *> *records = [self generatePreKeyRecords:1];

@ -38,12 +38,17 @@ public final class MultiDeviceProtocol : NSObject {
private override init() { } private override init() { }
// MARK: - Sending (Part 1) // MARK: - Sending (Part 1)
@objc(isMultiDeviceRequiredForMessage:)
public static func isMultiDeviceRequired(for message: TSOutgoingMessage) -> Bool {
return !(message is DeviceLinkMessage)
}
@objc(sendMessageToDestinationAndLinkedDevices:in:) @objc(sendMessageToDestinationAndLinkedDevices:in:)
public static func sendMessageToDestinationAndLinkedDevices(_ messageSend: OWSMessageSend, in transaction: YapDatabaseReadWriteTransaction) { public static func sendMessageToDestinationAndLinkedDevices(_ messageSend: OWSMessageSend, in transaction: YapDatabaseReadWriteTransaction) {
// TODO: I'm pretty sure there are quite a few holes in this logic // TODO: I'm pretty sure there are quite a few holes in this logic
let message = messageSend.message let message = messageSend.message
let recipientID = messageSend.recipient.recipientId() let recipientID = messageSend.recipient.recipientId()
let thread = messageSend.thread ?? TSContactThread.getOrCreateThread(withContactId: recipientID, transaction: transaction) // TODO: Added this because I think we need it let thread = messageSend.thread ?? TSContactThread.getOrCreateThread(withContactId: recipientID, transaction: transaction) // TODO: This seems really iffy
let isGroupMessage = thread.isGroupThread() let isGroupMessage = thread.isGroupThread()
let isOpenGroupMessage = (thread as? TSGroupThread)?.isPublicChat == true let isOpenGroupMessage = (thread as? TSGroupThread)?.isPublicChat == true
let isDeviceLinkMessage = message is DeviceLinkMessage let isDeviceLinkMessage = message is DeviceLinkMessage

@ -34,8 +34,8 @@ public final class SessionManagementProtocol : NSObject {
print("[Loki] Pre keys created successfully.") print("[Loki] Pre keys created successfully.")
} }
@objc(refreshPreKeys) @objc(refreshSignedPreKey)
public static func refreshPreKeys() { public static func refreshSignedPreKey() {
guard storage.currentSignedPrekeyId() == nil else { guard storage.currentSignedPrekeyId() == nil else {
print("[Loki] Skipping pre key refresh; using existing signed pre key.") print("[Loki] Skipping pre key refresh; using existing signed pre key.")
return return
@ -49,15 +49,15 @@ public final class SessionManagementProtocol : NSObject {
print("[Loki] Pre keys refreshed successfully.") print("[Loki] Pre keys refreshed successfully.")
} }
@objc(rotatePreKeys) @objc(rotateSignedPreKey)
public static func rotatePreKeys() { public static func rotateSignedPreKey() {
let signedPreKeyRecord = storage.generateRandomSignedRecord() let signedPreKeyRecord = storage.generateRandomSignedRecord()
signedPreKeyRecord.markAsAcceptedByService() signedPreKeyRecord.markAsAcceptedByService()
storage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord) storage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord)
storage.setCurrentSignedPrekeyId(signedPreKeyRecord.id) storage.setCurrentSignedPrekeyId(signedPreKeyRecord.id)
TSPreKeyManager.clearPreKeyUpdateFailureCount() TSPreKeyManager.clearPreKeyUpdateFailureCount()
TSPreKeyManager.clearSignedPreKeyRecords() TSPreKeyManager.clearSignedPreKeyRecords()
print("[Loki] Pre keys rotated successfully.") print("[Loki] Signed pre key rotated successfully.")
} }
@objc(shouldUseFallbackEncryptionForMessage:) @objc(shouldUseFallbackEncryptionForMessage:)

@ -591,9 +591,14 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
} }
resolve(error); resolve(error);
}]; }];
[self.primaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[LKMultiDeviceProtocol sendMessageToDestinationAndLinkedDevices:messageSend in:transaction]; if ([LKMultiDeviceProtocol isMultiDeviceRequiredForMessage:message]) { // Avoid the write transaction if possible
}]; [self.primaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[LKMultiDeviceProtocol sendMessageToDestinationAndLinkedDevices:messageSend in:transaction];
}];
} else {
[self sendMessage:messageSend];
}
}]; }];
[sendPromises addObject:sendPromise]; [sendPromises addObject:sendPromise];
} }
@ -1559,9 +1564,13 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
failure(error); failure(error);
}]; }];
[self.primaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { if ([LKMultiDeviceProtocol isMultiDeviceRequiredForMessage:message]) { // Avoid the write transaction if possible
[LKMultiDeviceProtocol sendMessageToDestinationAndLinkedDevices:messageSend in:transaction]; [self.primaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
}]; [LKMultiDeviceProtocol sendMessageToDestinationAndLinkedDevices:messageSend in:transaction];
}];
} else {
[self sendMessage:messageSend];
}
} }
- (NSArray<NSDictionary *> *)throws_deviceMessagesForMessageSend:(OWSMessageSend *)messageSend - (NSArray<NSDictionary *> *)throws_deviceMessagesForMessageSend:(OWSMessageSend *)messageSend

Loading…
Cancel
Save