From 9618fc16c517d6c8e492531ac73cee93ed18a816 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 13 Jul 2018 15:23:08 -0400 Subject: [PATCH] Streamline SignalRecipient. --- .../src/Contacts/ContactsUpdater.m | 33 ++++++++++--------- SignalServiceKit/src/Contacts/SignalAccount.h | 5 --- SignalServiceKit/src/Contacts/SignalAccount.m | 9 ----- .../src/Contacts/SignalRecipient.h | 15 ++++----- .../src/Contacts/SignalRecipient.m | 19 +++++++++++ .../src/Messages/OWSMessageSender.m | 13 +++++++- 6 files changed, 56 insertions(+), 38 deletions(-) diff --git a/SignalServiceKit/src/Contacts/ContactsUpdater.m b/SignalServiceKit/src/Contacts/ContactsUpdater.m index 6c0e9cc63..60b6325d6 100644 --- a/SignalServiceKit/src/Contacts/ContactsUpdater.m +++ b/SignalServiceKit/src/Contacts/ContactsUpdater.m @@ -38,6 +38,16 @@ NS_ASSUME_NONNULL_BEGIN return self; } +- (SignalRecipient *)signalRecipientForRegisteredRecipientId:(NSString *)recipientId +{ + __block SignalRecipient *recipient; + [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + recipient = + [SignalRecipient ensureRecipientExistsWithRegisteredRecipientId:recipientId transaction:transaction]; + }]; + return recipient; +} + - (void)lookupIdentifier:(NSString *)identifier success:(void (^)(SignalRecipient *recipient))success failure:(void (^)(NSError *error))failure @@ -52,7 +62,7 @@ NS_ASSUME_NONNULL_BEGIN [self contactIntersectionWithSet:[NSSet setWithObject:identifier] success:^(NSSet *_Nonnull matchedIds) { if (matchedIds.count == 1) { - success([SignalRecipient recipientWithTextSecureIdentifier:identifier]); + success([self signalRecipientForRegisteredRecipientId:identifier]); } else { failure(OWSErrorMakeNoSuchSignalRecipientError()); } @@ -75,7 +85,8 @@ NS_ASSUME_NONNULL_BEGIN if (matchedIds.count > 0) { NSMutableArray *recipients = [NSMutableArray new]; for (NSString *identifier in matchedIds) { - [recipients addObject:[SignalRecipient recipientWithTextSecureIdentifier:identifier]]; + [recipients + addObject:[self signalRecipientForRegisteredRecipientId:identifier]]; } success([recipients copy]); } else { @@ -109,18 +120,9 @@ NS_ASSUME_NONNULL_BEGIN success:^(NSSet *matchedIds) { [recipientIds minusSet:matchedIds]; - // Cleaning up unregistered identifiers - [OWSPrimaryStorage.dbReadWriteConnection - readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - for (NSString *identifier in recipientIds) { - SignalRecipient *recipient = - [SignalRecipient fetchObjectWithUniqueID:identifier - transaction:transaction]; - - [recipient removeWithTransaction:transaction]; - } - }]; - + // TODO: + // + // Update cache of registered identifiers. DDLogInfo(@"%@ successfully intersected contacts.", self.logTag); success(); } @@ -165,7 +167,8 @@ NS_ASSUME_NONNULL_BEGIN [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { for (NSString *identifier in identifiers) { - [SignalRecipient ensureRecipientExistsWithRecipientId:identifier transaction:transaction]; + [SignalRecipient ensureRecipientExistsWithRegisteredRecipientId:identifier + transaction:transaction]; } }]; diff --git a/SignalServiceKit/src/Contacts/SignalAccount.h b/SignalServiceKit/src/Contacts/SignalAccount.h index e2345c515..5b416f9a4 100644 --- a/SignalServiceKit/src/Contacts/SignalAccount.h +++ b/SignalServiceKit/src/Contacts/SignalAccount.h @@ -41,11 +41,6 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithRecipientId:(NSString *)recipientId; -// In most cases this should be non-null. This should only -// be null in the case where the SignalRecipient was -// deleted before this property was accessed. -- (nullable SignalRecipient *)signalRecipientWithTransaction:(YapDatabaseReadTransaction *)transaction; - @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Contacts/SignalAccount.m b/SignalServiceKit/src/Contacts/SignalAccount.m index 158992de1..523947479 100644 --- a/SignalServiceKit/src/Contacts/SignalAccount.m +++ b/SignalServiceKit/src/Contacts/SignalAccount.m @@ -36,15 +36,6 @@ NS_ASSUME_NONNULL_BEGIN return self; } -- (nullable SignalRecipient *)signalRecipientWithTransaction:(YapDatabaseReadTransaction *)transaction -{ - OWSAssertIsOnMainThread(); - OWSAssert(transaction); - - OWSAssert(self.recipientId.length > 0); - return [SignalRecipient recipientWithTextSecureIdentifier:self.recipientId withTransaction:transaction]; -} - - (nullable NSString *)uniqueId { return _recipientId; diff --git a/SignalServiceKit/src/Contacts/SignalRecipient.h b/SignalServiceKit/src/Contacts/SignalRecipient.h index 8e9896b7e..6f1d993d5 100644 --- a/SignalServiceKit/src/Contacts/SignalRecipient.h +++ b/SignalServiceKit/src/Contacts/SignalRecipient.h @@ -6,22 +6,20 @@ NS_ASSUME_NONNULL_BEGIN -// This class serves two purposes: -// -// * We only _persist_ SignalRecipient instances when we know -// that it corresponds to an account on the Signal service. -// So SignalRecipient serves as a defacto cache of "known -// Signal users." -// * We hang the "known device list" for signal accounts on -// this entity. +// We hang the "known device list" for signal accounts on this entity. @interface SignalRecipient : TSYapDatabaseObject @property (readonly) NSOrderedSet *devices; +@property (nonatomic) BOOL mayBeUnregistered; + - (instancetype)init NS_UNAVAILABLE; + (instancetype)selfRecipient; ++ (SignalRecipient *)ensureRecipientExistsWithRegisteredRecipientId:(NSString *)recipientId + transaction:(YapDatabaseReadWriteTransaction *)transaction; + + (SignalRecipient *)ensureRecipientExistsWithRecipientId:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction; @@ -29,6 +27,7 @@ NS_ASSUME_NONNULL_BEGIN deviceId:(UInt32)deviceId transaction:(YapDatabaseReadWriteTransaction *)transaction; +// TODO: Replace with cache of known signal account ids. + (nullable instancetype)recipientWithTextSecureIdentifier:(NSString *)textSecureIdentifier; + (nullable instancetype)recipientWithTextSecureIdentifier:(NSString *)textSecureIdentifier withTransaction:(YapDatabaseReadTransaction *)transaction; diff --git a/SignalServiceKit/src/Contacts/SignalRecipient.m b/SignalServiceKit/src/Contacts/SignalRecipient.m index 351e74f9e..6f11a0140 100644 --- a/SignalServiceKit/src/Contacts/SignalRecipient.m +++ b/SignalServiceKit/src/Contacts/SignalRecipient.m @@ -22,6 +22,25 @@ NS_ASSUME_NONNULL_BEGIN return @"SignalRecipient"; } +- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction +{ + OWSFail(@"%@ We should no longer remove SignalRecipients.", self.logTag); + + [super removeWithTransaction:transaction]; +} + ++ (SignalRecipient *)ensureRecipientExistsWithRegisteredRecipientId:(NSString *)recipientId + transaction:(YapDatabaseReadWriteTransaction *)transaction +{ + SignalRecipient *recipient = + [self ensureRecipientExistsWithRegisteredRecipientId:recipient transaction:transaction]; + if (recipient.mayBeUnregistered) { + recipient.mayBeUnregistered = NO; + [recipient saveWithTransaction:transaction]; + } + return recipient; +} + + (SignalRecipient *)ensureRecipientExistsWithRecipientId:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction { diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index cf183a70b..a0e80f1a6 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -712,7 +712,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [message updateWithSkippedRecipient:recipient.recipientId transaction:transaction]; } - [recipient removeWithTransaction:transaction]; + if (recipient.mayBeUnregistered) { + return; + } + recipient.mayBeUnregistered = YES; + [recipient saveWithTransaction:transaction]; + [[TSInfoMessage userNotRegisteredMessageInThread:thread recipientId:recipient.recipientId] saveWithTransaction:transaction]; }]; @@ -1010,6 +1015,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [recipient saveWithTransaction:transaction]; [message updateWithSentRecipient:recipient.uniqueId transaction:transaction]; + + if (recipient.mayBeUnregistered) { + recipient.mayBeUnregistered = NO; + [recipient saveWithTransaction:transaction]; + } }]; [self handleMessageSentLocally:message]; @@ -1075,6 +1085,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; DDLogWarn(@"%@ Unregistered recipient: %@", self.logTag, recipient.uniqueId); OWSAssert(thread); + [self unregisteredRecipient:recipient message:message thread:thread]; NSError *error = OWSErrorMakeNoSuchSignalRecipientError(); // No need to retry if the recipient is not registered.