diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 5f9be61a3..942aa93ef 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -320,7 +320,7 @@ static NSTimeInterval launchStartedAt; if (self.lokiP2PServer.isRunning) { break; } BOOL isStarted = [self.lokiP2PServer startOnPort:port.unsignedIntegerValue]; if (isStarted) { - OWSLogInfo(@"[Loki] Started server at %@.", self.lokiP2PServer.serverURL); + OWSLogInfo(@"[Loki] Started server at \"%@\".", self.lokiP2PServer.serverURL); break; } } diff --git a/SignalServiceKit/src/Contacts/TSThread.m b/SignalServiceKit/src/Contacts/TSThread.m index e266e6f50..e9e16f252 100644 --- a/SignalServiceKit/src/Contacts/TSThread.m +++ b/SignalServiceKit/src/Contacts/TSThread.m @@ -767,6 +767,7 @@ ConversationColorName const kConversationColorName_Default = ConversationColorNa - (void)saveFriendRequestStatus:(TSThreadFriendRequestStatus)friendRequestStatus withTransaction:(YapDatabaseReadWriteTransaction *_Nullable)transaction { + OWSLogInfo(@"[Loki] Setting thread friend request status to %d.", friendRequestStatus); self.friendRequestStatus = friendRequestStatus; void (^postNotification)() = ^() { [NSNotificationCenter.defaultCenter postNotificationName:NSNotification.threadFriendRequestStatusChanged object:self.uniqueId]; diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+Convenience.swift b/SignalServiceKit/src/Loki/API/LokiAPI+Convenience.swift index 16e489b24..94b68a0be 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+Convenience.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+Convenience.swift @@ -35,6 +35,18 @@ internal extension LokiAPI { } } +internal extension Promise { + + internal func recoveringNetworkErrorsIfNeeded() -> Promise { + return recover() { error -> Promise in + switch error { + case NetworkManagerError.taskError(_, let underlyingError): throw underlyingError + default: throw error + } + } + } +} + internal extension AnyPromise { internal static func from(_ promise: Promise) -> AnyPromise { diff --git a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift index a7738bc47..a6cdfc897 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI+SwarmAPI.swift @@ -31,7 +31,7 @@ public extension LokiAPI { // MARK: Internal API private static func getRandomSnode() -> Promise { return Promise { seal in - seal.fulfill(Target(address: "http://13.236.173.190", port: 8080)) // TODO: For debugging purposes + seal.fulfill(Target(address: "http://13.236.173.191", port: 8080)) // TODO: For debugging purposes } } @@ -53,7 +53,7 @@ public extension LokiAPI { private static func parseTargets(from rawResponse: Any) -> [Target] { // TODO: For debugging purposes // ======== - let target = Target(address: "http://13.236.173.190", port: defaultSnodePort) + let target = Target(address: "http://13.236.173.191", port: defaultSnodePort) return Array(repeating: target, count: 3) // ======== // guard let json = rawResponse as? JSON, let addresses = json["snodes"] as? [String] else { @@ -76,6 +76,7 @@ internal extension Promise { Logger.warn("[Loki] There appears to be a problem with LokiNet.") case 421: // The snode isn't associated with the given public key anymore + Logger.warn("[Loki] Invalidating swarm for: \(hexEncodedPublicKey).") let swarm = LokiAPI.swarmCache[hexEncodedPublicKey] if var swarm = swarm, let index = swarm.firstIndex(of: target) { swarm.remove(at: index) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index b7b62a9df..760f67127 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -28,7 +28,8 @@ import PromiseKit internal static func invoke(_ method: Target.Method, on target: Target, associatedWith hexEncodedPublicKey: String, parameters: [String:Any] = [:]) -> Promise { let url = URL(string: "\(target.address):\(target.port)/\(version)/storage_rpc")! let request = TSRequest(url: url, method: "POST", parameters: [ "method" : method.rawValue, "params" : parameters ]) - return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.handlingSwarmSpecificErrorsIfNeeded(for: target, associatedWith: hexEncodedPublicKey) + return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject } + .handlingSwarmSpecificErrorsIfNeeded(for: target, associatedWith: hexEncodedPublicKey).recoveringNetworkErrorsIfNeeded() } // MARK: Public API diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.m b/SignalServiceKit/src/Messages/Interactions/TSMessage.m index 4df337e48..01f906e70 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.m @@ -443,6 +443,7 @@ static const NSUInteger OWSMessageSchemaVersion = 4; - (void)saveFriendRequestStatus:(TSMessageFriendRequestStatus)friendRequestStatus withTransaction:(YapDatabaseReadWriteTransaction *_Nullable)transaction { + OWSLogInfo(@"[Loki] Setting message friend request status to %d.", friendRequestStatus); self.friendRequestStatus = friendRequestStatus; void (^postNotification)() = ^() { [NSNotificationCenter.defaultCenter postNotificationName:NSNotification.messageFriendRequestStatusChanged object:self.uniqueId]; diff --git a/SignalServiceKit/src/Messages/OWSMessageSend.swift b/SignalServiceKit/src/Messages/OWSMessageSend.swift index 366e5b99c..bb9b0fefb 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSend.swift +++ b/SignalServiceKit/src/Messages/OWSMessageSend.swift @@ -21,7 +21,7 @@ public class OWSMessageSend: NSObject { @objc public let recipient: SignalRecipient - private static let kMaxRetriesPerRecipient: Int = 3 + private static let kMaxRetriesPerRecipient: Int = 1 @objc public var remainingAttempts = OWSMessageSend.kMaxRetriesPerRecipient diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index c6c66f788..eb16f703f 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1066,10 +1066,10 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; hasValidMessageType = [validMessageTypes containsObject:messageType]; /* Loki: Original code - hasValidMessageType = ([messageType isEqualToNumber:@(TSEncryptedWhisperMessageType)] || - [messageType isEqualToNumber:@(TSPreKeyWhisperMessageType)]); + * ======== + hasValidMessageType = ([messageType isEqualToNumber:@(TSEncryptedWhisperMessageType)] || [messageType isEqualToNumber:@(TSPreKeyWhisperMessageType)]); + * ======== */ - } if (!hasValidMessageType) { @@ -1103,16 +1103,45 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; return messageSend.failure(error); } - // Update the state to show that the proof of work is being calculated - [self saveIsCalculatingProofOfWork:YES forMessage:messageSend]; - // Convert the message to a Loki message and send it using the Loki messaging API + // Get the message parameters and type NSDictionary *signalMessage = deviceMessages.firstObject; - // Update the message and thread if needed - NSInteger *messageType = ((NSNumber *)signalMessage[@"type"]).integerValue; - if (messageType == TSFriendRequestMessageType) { - [message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusRequestSending withTransaction:nil]; - [message saveFriendRequestStatus:TSMessageFriendRequestStatusPending withTransaction:nil]; - } + TSWhisperMessageType messageType = ((NSNumber *)signalMessage[@"type"]).integerValue; + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + // Update the PoW calculation status + [message saveIsCalculatingProofOfWork:YES withTransaction:transaction]; + // Update the message and thread if needed + if (messageType == TSFriendRequestMessageType) { + [message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusRequestSending withTransaction:transaction]; + [message saveFriendRequestStatus:TSMessageFriendRequestStatusPending withTransaction:transaction]; + } + }]; + // Convenience + void (^handleError)(NSError *error) = ^(NSError *error) { + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + // Update the thread if needed + if (messageType == TSFriendRequestMessageType) { + [message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusNone withTransaction:transaction]; + } + // Update the PoW calculation status + [message saveIsCalculatingProofOfWork:NO withTransaction:transaction]; + }]; + // Handle the error + NSUInteger statusCode = 0; + NSData *_Nullable responseData = nil; + if ([error.domain isEqualToString:TSNetworkManagerErrorDomain]) { + statusCode = error.code; + NSError *_Nullable underlyingError = error.userInfo[NSUnderlyingErrorKey]; + if (underlyingError) { + responseData = underlyingError.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey]; + } else { + OWSFailDebug(@"Missing underlying error: %@.", error); + } + } else { + OWSFailDebug(@"Unexpected error: %@.", error); + } + [self messageSendDidFail:messageSend deviceMessages:deviceMessages statusCode:statusCode error:error responseData:responseData]; + }; + // Convert the message to a Loki message and send it using the Loki API [[LokiAPI objc_sendSignalMessage:signalMessage to:recipient.recipientId with:message.timestamp] .thenOn(OWSDispatch.sendingQueue, ^(id result) { NSSet *promises = (NSSet *)result; @@ -1140,29 +1169,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; .catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { errorCount += 1; if (errorCount != promiseCount) { return; } // Only error out if all promises failed - // Update the thread if needed - if (messageType == TSFriendRequestMessageType) { - [message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusNone withTransaction:nil]; - } - // Update the PoW calculation status - [self saveIsCalculatingProofOfWork:NO forMessage:messageSend]; - // Handle the error - NSUInteger statusCode = 0; - NSData *_Nullable responseData = nil; - if ([error.domain isEqualToString:TSNetworkManagerErrorDomain]) { - statusCode = error.code; - NSError *_Nullable underlyingError = error.userInfo[NSUnderlyingErrorKey]; - if (underlyingError) { - responseData = underlyingError.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey]; - } else { - OWSFailDebug(@"Missing underlying error: %@.", error); - } - } else { - OWSFailDebug(@"Unexpected error: %@.", error); - } - [self messageSendDidFail:messageSend deviceMessages:deviceMessages statusCode:statusCode error:error responseData:responseData]; + handleError(error); }) retainUntilComplete]; } + }) + .catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { // Unreachable snode; usually a problem with LokiNet + handleError(error); }) retainUntilComplete]; // Loki: Original code diff --git a/SignalServiceKit/src/Network/MessageSenderJobQueue.swift b/SignalServiceKit/src/Network/MessageSenderJobQueue.swift index e2891998d..b989691d6 100644 --- a/SignalServiceKit/src/Network/MessageSenderJobQueue.swift +++ b/SignalServiceKit/src/Network/MessageSenderJobQueue.swift @@ -81,7 +81,7 @@ public class MessageSenderJobQueue: NSObject, JobQueue { public typealias DurableOperationType = MessageSenderOperation public static let jobRecordLabel: String = "MessageSender" - public static let maxRetries: UInt = 30 + public static let maxRetries: UInt = 1 public let requiresInternet: Bool = true public var runningOperations: [MessageSenderOperation] = []