|
|
@ -915,6 +915,38 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
return deviceMessages;
|
|
|
|
return deviceMessages;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (AnyPromise *)calculateProofOfWorkForDeviceMessages:(NSArray<NSDictionary *> *)deviceMessages
|
|
|
|
|
|
|
|
ttl:(NSNumber *)ttl
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// LOKI: Calculate the proof of work for each device message
|
|
|
|
|
|
|
|
NSMutableArray *promises = [[NSMutableArray alloc] init];
|
|
|
|
|
|
|
|
for (NSDictionary<NSString *, id> *deviceMessage in deviceMessages) {
|
|
|
|
|
|
|
|
AnyPromise *promise = [AnyPromise promiseWithValue:deviceMessage]
|
|
|
|
|
|
|
|
.thenOn(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(NSDictionary<NSString *, id> *message) {
|
|
|
|
|
|
|
|
NSTimeInterval timestampInterval = [[NSDate date] timeIntervalSince1970];
|
|
|
|
|
|
|
|
NSNumber *timestamp = [NSNumber numberWithDouble:timestampInterval];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NSString *destination = message[@"destination"];
|
|
|
|
|
|
|
|
NSString *data = message[@"content"];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NSString *_Nullable nonce = [ProofOfWork calculateForData:data pubKey:destination timestamp:timestamp.unsignedIntegerValue ttl:ttl.integerValue];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Return our timestamp along with the nonce
|
|
|
|
|
|
|
|
// These will help us identify which nonce belongs to which message
|
|
|
|
|
|
|
|
return @{
|
|
|
|
|
|
|
|
@"destination": destination,
|
|
|
|
|
|
|
|
@"deviceId": message[@"destinationDeviceId"],
|
|
|
|
|
|
|
|
@"timestamp": timestamp,
|
|
|
|
|
|
|
|
@"nonce": nonce
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
[promises addObject:promise];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Wait for all the PoW Calculations to finish
|
|
|
|
|
|
|
|
return PMKWhen(promises);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)sendMessageToRecipient:(OWSMessageSend *)messageSend
|
|
|
|
- (void)sendMessageToRecipient:(OWSMessageSend *)messageSend
|
|
|
|
{
|
|
|
|
{
|
|
|
|
OWSAssertDebug(messageSend);
|
|
|
|
OWSAssertDebug(messageSend);
|
|
|
@ -1087,65 +1119,82 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
// linked devices that we don't know about.
|
|
|
|
// linked devices that we don't know about.
|
|
|
|
OWSLogWarn(@"Sending a message with no device messages.");
|
|
|
|
OWSLogWarn(@"Sending a message with no device messages.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
OWSRequestMaker *requestMaker = [[OWSRequestMaker alloc] initWithLabel:@"Message Send"
|
|
|
|
// TODO: Update message here to show the pow cog icon
|
|
|
|
requestFactoryBlock:^(SMKUDAccessKey *_Nullable udAccessKey) {
|
|
|
|
|
|
|
|
return [OWSRequestFactory submitMessageRequestWithRecipient:recipient.recipientId
|
|
|
|
// LOKI: Calculate the proof of work for each device message
|
|
|
|
messages:deviceMessages
|
|
|
|
NSNumber *ttl = [NSNumber numberWithInteger:@(4 * 24 * 60 * 60)];
|
|
|
|
timeStamp:message.timestamp
|
|
|
|
AnyPromise *PoWPromise = [self calculateProofOfWorkForDeviceMessages:deviceMessages ttl:ttl];
|
|
|
|
udAccessKey:udAccessKey];
|
|
|
|
[PoWPromise
|
|
|
|
}
|
|
|
|
.thenOn([OWSDispatch sendingQueue], ^(NSArray *nonceArray) {
|
|
|
|
udAuthFailureBlock:^{
|
|
|
|
OWSRequestMaker *requestMaker = [[OWSRequestMaker alloc] initWithLabel:@"Message Send"
|
|
|
|
// Note the UD auth failure so subsequent retries
|
|
|
|
requestFactoryBlock:^(SMKUDAccessKey *_Nullable udAccessKey) {
|
|
|
|
// to this recipient also use basic auth.
|
|
|
|
// Loki Changes:
|
|
|
|
[messageSend setHasUDAuthFailed];
|
|
|
|
return [OWSRequestFactory submitLokiMessageRequestWithRecipient:recipient.recipientId
|
|
|
|
}
|
|
|
|
messages:deviceMessages
|
|
|
|
websocketFailureBlock:^{
|
|
|
|
nonceArray:nonceArray
|
|
|
|
// Note the websocket failure so subsequent retries
|
|
|
|
ttl:ttl];
|
|
|
|
// to this recipient also use REST.
|
|
|
|
/* Original Code:
|
|
|
|
messageSend.hasWebsocketSendFailed = YES;
|
|
|
|
return [OWSRequestFactory submitMessageRequestWithRecipient:recipient.recipientId
|
|
|
|
}
|
|
|
|
messages:deviceMessages
|
|
|
|
recipientId:recipient.recipientId
|
|
|
|
timeStamp:message.timestamp
|
|
|
|
udAccess:messageSend.udAccess
|
|
|
|
udAccessKey:udAccessKey];
|
|
|
|
canFailoverUDAuth:NO];
|
|
|
|
*/
|
|
|
|
[[requestMaker makeRequestObjc]
|
|
|
|
}
|
|
|
|
.then(^(OWSRequestMakerResult *result) {
|
|
|
|
udAuthFailureBlock:^{
|
|
|
|
dispatch_async([OWSDispatch sendingQueue], ^{
|
|
|
|
// Note the UD auth failure so subsequent retries
|
|
|
|
[self messageSendDidSucceed:messageSend
|
|
|
|
// to this recipient also use basic auth.
|
|
|
|
deviceMessages:deviceMessages
|
|
|
|
[messageSend setHasUDAuthFailed];
|
|
|
|
wasSentByUD:result.wasSentByUD
|
|
|
|
}
|
|
|
|
wasSentByWebsocket:result.wasSentByWebsocket];
|
|
|
|
websocketFailureBlock:^{
|
|
|
|
});
|
|
|
|
// Note the websocket failure so subsequent retries
|
|
|
|
})
|
|
|
|
// to this recipient also use REST.
|
|
|
|
.catch(^(NSError *error) {
|
|
|
|
messageSend.hasWebsocketSendFailed = YES;
|
|
|
|
dispatch_async([OWSDispatch sendingQueue], ^{
|
|
|
|
}
|
|
|
|
NSUInteger statusCode = 0;
|
|
|
|
recipientId:recipient.recipientId
|
|
|
|
NSData *_Nullable responseData = nil;
|
|
|
|
udAccess:messageSend.udAccess
|
|
|
|
if ([error.domain isEqualToString:@"SignalServiceKit.RequestMakerUDAuthError"]) {
|
|
|
|
canFailoverUDAuth:NO];
|
|
|
|
// Try again.
|
|
|
|
return requestMaker;
|
|
|
|
OWSLogInfo(@"UD request auth failed; failing over to non-UD request.");
|
|
|
|
})
|
|
|
|
[error setIsRetryable:YES];
|
|
|
|
.thenOn([OWSDispatch sendingQueue], ^(OWSRequestMaker *requestMaker) {
|
|
|
|
} else if ([error.domain isEqualToString:TSNetworkManagerErrorDomain]) {
|
|
|
|
return [requestMaker makeRequestObjc];
|
|
|
|
statusCode = error.code;
|
|
|
|
}).then(^(OWSRequestMakerResult *result) {
|
|
|
|
|
|
|
|
dispatch_async([OWSDispatch sendingQueue], ^{
|
|
|
|
NSError *_Nullable underlyingError = error.userInfo[NSUnderlyingErrorKey];
|
|
|
|
[self messageSendDidSucceed:messageSend
|
|
|
|
if (underlyingError) {
|
|
|
|
deviceMessages:deviceMessages
|
|
|
|
responseData
|
|
|
|
wasSentByUD:result.wasSentByUD
|
|
|
|
= underlyingError.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
|
|
|
|
wasSentByWebsocket:result.wasSentByWebsocket];
|
|
|
|
} else {
|
|
|
|
});
|
|
|
|
OWSFailDebug(@"Missing underlying error: %@", error);
|
|
|
|
})
|
|
|
|
}
|
|
|
|
.catch(^(NSError *error) {
|
|
|
|
|
|
|
|
dispatch_async([OWSDispatch sendingQueue], ^{
|
|
|
|
|
|
|
|
NSUInteger statusCode = 0;
|
|
|
|
|
|
|
|
NSData *_Nullable responseData = nil;
|
|
|
|
|
|
|
|
if ([error.domain isEqualToString:@"SignalServiceKit.RequestMakerUDAuthError"]) {
|
|
|
|
|
|
|
|
// Try again.
|
|
|
|
|
|
|
|
OWSLogInfo(@"UD request auth failed; failing over to non-UD request.");
|
|
|
|
|
|
|
|
[error setIsRetryable:YES];
|
|
|
|
|
|
|
|
} else if ([error.domain isEqualToString:TSNetworkManagerErrorDomain]) {
|
|
|
|
|
|
|
|
statusCode = error.code;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NSError *_Nullable underlyingError = error.userInfo[NSUnderlyingErrorKey];
|
|
|
|
|
|
|
|
if (underlyingError) {
|
|
|
|
|
|
|
|
responseData
|
|
|
|
|
|
|
|
= underlyingError.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
OWSFailDebug(@"Unexpected error: %@", error);
|
|
|
|
OWSFailDebug(@"Missing underlying error: %@", error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
[self messageSendDidFail:messageSend
|
|
|
|
OWSFailDebug(@"Unexpected error: %@", error);
|
|
|
|
deviceMessages:deviceMessages
|
|
|
|
}
|
|
|
|
statusCode:statusCode
|
|
|
|
|
|
|
|
error:error
|
|
|
|
[self messageSendDidFail:messageSend
|
|
|
|
responseData:responseData];
|
|
|
|
deviceMessages:deviceMessages
|
|
|
|
});
|
|
|
|
statusCode:statusCode
|
|
|
|
}) retainUntilComplete];
|
|
|
|
error:error
|
|
|
|
|
|
|
|
responseData:responseData];
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}) retainUntilComplete];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)messageSendDidSucceed:(OWSMessageSend *)messageSend
|
|
|
|
- (void)messageSendDidSucceed:(OWSMessageSend *)messageSend
|
|
|
|