From 2ef26ab915f0587ba0c44dc1722d7d673dd5912f Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Mon, 6 Jul 2020 16:37:07 +1000 Subject: [PATCH] Don't fetch device links unnecessarily, debug & fix excessive PoW bug --- SignalServiceKit/src/Loki/API/SnodeAPI.swift | 17 ++++++++++++----- .../Closed Groups/ClosedGroupsProtocol.swift | 4 ++-- .../Multi Device/MultiDeviceProtocol.swift | 7 ++++--- .../src/Messages/OWSMessageManager.m | 3 ++- .../src/Messages/OWSMessageSender.m | 9 ++++++--- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/SnodeAPI.swift b/SignalServiceKit/src/Loki/API/SnodeAPI.swift index 6d25db9bb..b8fd953d0 100644 --- a/SignalServiceKit/src/Loki/API/SnodeAPI.swift +++ b/SignalServiceKit/src/Loki/API/SnodeAPI.swift @@ -300,9 +300,7 @@ public final class SnodeAPI : NSObject { #if DEBUG assertOnQueue(SnodeAPI.workQueue) #endif - switch statusCode { - case 0, 400, 500, 503: - // The snode is unreachable + func handleBadSnode() { let oldFailureCount = SnodeAPI.snodeFailureCount[snode] ?? 0 let newFailureCount = oldFailureCount + 1 SnodeAPI.snodeFailureCount[snode] = newFailureCount @@ -313,6 +311,11 @@ public final class SnodeAPI : NSObject { SnodeAPI.dropSnodeFromSnodePool(snode) SnodeAPI.snodeFailureCount[snode] = 0 } + } + switch statusCode { + case 0, 400, 500, 503: + // The snode is unreachable + handleBadSnode() case 406: print("[Loki] The user's clock is out of sync with the service node network.") return SnodeAPI.SnodeAPIError.clockOutOfSync @@ -323,8 +326,12 @@ public final class SnodeAPI : NSObject { case 432: // The proof of work difficulty is too low if let powDifficulty = json?["difficulty"] as? UInt { - print("[Loki] Setting proof of work difficulty to \(powDifficulty).") - SnodeAPI.powDifficulty = UInt(powDifficulty) + if powDifficulty < 100 { + print("[Loki] Setting proof of work difficulty to \(powDifficulty).") + SnodeAPI.powDifficulty = UInt(powDifficulty) + } else { + handleBadSnode() + } } else { print("[Loki] Failed to update proof of work difficulty.") } diff --git a/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift index 70eff427f..4d38c00ed 100644 --- a/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Closed Groups/ClosedGroupsProtocol.swift @@ -28,7 +28,7 @@ public final class ClosedGroupsProtocol : NSObject { members.remove(userPublicKey) members.insert(UserDefaults.standard[.masterHexEncodedPublicKey] ?? userPublicKey) // Create ratchets for all members (and their linked devices) - var membersAndLinkedDevices: Set = [] + var membersAndLinkedDevices: Set = members for member in members { let deviceLinks = OWSPrimaryStorage.shared().getDeviceLinks(for: member, in: transaction) membersAndLinkedDevices.formUnion(deviceLinks.flatMap { [ $0.master.hexEncodedPublicKey, $0.slave.hexEncodedPublicKey ] }) @@ -82,7 +82,7 @@ public final class ClosedGroupsProtocol : NSObject { var members = group.groupMemberIds members.append(contentsOf: newMembers) // Generate ratchets for the new members (and their linked devices) - var newMembersAndLinkedDevices: Set = [] + var newMembersAndLinkedDevices: Set = newMembers for member in newMembers { let deviceLinks = OWSPrimaryStorage.shared().getDeviceLinks(for: member, in: transaction) newMembersAndLinkedDevices.formUnion(deviceLinks.flatMap { [ $0.master.hexEncodedPublicKey, $0.slave.hexEncodedPublicKey ] }) diff --git a/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift b/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift index 5e76c4e1f..2112b8b7b 100644 --- a/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift +++ b/SignalServiceKit/src/Loki/Protocol/Multi Device/MultiDeviceProtocol.swift @@ -55,9 +55,10 @@ public final class MultiDeviceProtocol : NSObject { // MARK: - Sending (Part 1) - @objc(isMultiDeviceRequiredForMessage:) - public static func isMultiDeviceRequired(for message: TSOutgoingMessage) -> Bool { + @objc(isMultiDeviceRequiredForMessage:toPublicKey:) + public static func isMultiDeviceRequired(for message: TSOutgoingMessage, to publicKey: String) -> Bool { return !(message is DeviceLinkMessage) && !(message is UnlinkDeviceMessage) && (message.thread as? TSGroupThread)?.groupModel.groupType != .openGroup + && !Storage.getUserClosedGroupPublicKeys().contains(publicKey) } private static func copy(_ messageSend: OWSMessageSend, for destination: MultiDeviceDestination, with seal: Resolver) -> OWSMessageSend { @@ -120,7 +121,7 @@ public final class MultiDeviceProtocol : NSObject { } let message = messageSend.message let messageSender = SSKEnvironment.shared.messageSender - if !isMultiDeviceRequired(for: message) { + if !isMultiDeviceRequired(for: message, to: messageSend.recipient.recipientId()) { print("[Loki] sendMessageToDestinationAndLinkedDevices(_:in:) invoked for a message that doesn't require multi device routing.") OWSDispatch.sendingQueue().async { messageSender.sendMessage(messageSend) diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 4d6a22f0e..d162a0949 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -1268,7 +1268,8 @@ NS_ASSUME_NONNULL_BEGIN // FIXME: This is horrible for performance // FIXME: ======== // The envelope source is set during UD decryption - if ([ECKeyPair isValidHexEncodedPublicKeyWithCandidate:envelope.source] && dataMessage.publicChatInfo == nil) { // Handled in LokiPublicChatPoller for open group messages + if ([ECKeyPair isValidHexEncodedPublicKeyWithCandidate:envelope.source] && dataMessage.publicChatInfo == nil // Handled in LokiPublicChatPoller for open group messages + && envelope.type != SSKProtoEnvelopeTypeClosedGroupCiphertext) { dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); [[LKMultiDeviceProtocol updateDeviceLinksIfNeededForPublicKey:envelope.source transaction:transaction].ensureOn(queue, ^() { diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 6d58c65d9..14c2a8130 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -612,7 +612,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; resolve(error); }]; - if ([LKMultiDeviceProtocol isMultiDeviceRequiredForMessage:message]) { // Avoid the write transaction if possible + NSString *publicKey = recipients.firstObject.recipientId; + if ([LKMultiDeviceProtocol isMultiDeviceRequiredForMessage:message toPublicKey:publicKey]) { // Avoid the write transaction if possible [self.primaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { [LKMultiDeviceProtocol sendMessageToDestinationAndLinkedDevices:messageSend transaction:transaction]; }]; @@ -931,7 +932,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; OWSAssertDebug(messageSend); OWSAssertDebug(messageSend.thread || [messageSend.message isKindOfClass:[OWSOutgoingSyncMessage class]]); NSString *userPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey; - OWSAssertDebug(messageSend.isUDSend || [messageSend.recipient.recipientId isEqual:userPublicKey]); + if (!messageSend.isUDSend && ![messageSend.recipient.recipientId isEqual:userPublicKey]) { + [LKLogger print:@"[Loki] Non-UD send"]; + } TSOutgoingMessage *message = messageSend.message; SignalRecipient *recipient = messageSend.recipient; @@ -1132,7 +1135,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; if ([messageSend.thread isKindOfClass:TSGroupThread.class] && ((TSGroupThread *)messageSend.thread).usesSharedSenderKeys) { senderID = [LKGroupUtilities getDecodedGroupID:((TSGroupThread *)messageSend.thread).groupModel.groupId]; } else { - OWSAssertDebug([senderID isEqual:@""]); + [LKLogger print:@"Non-UD send"]; } uint32_t senderDeviceID = type == SSKProtoEnvelopeTypeUnidentifiedSender ? 0 : OWSDevicePrimaryDeviceId; NSString *content = signalMessageInfo[@"content"];