Reduce impact of CDS rate-limiting issues.

This will at least allow users with > RateLimit contacts to perform a successful sync. More work needs to be done here in the future to handle this better.
This commit is contained in:
Greyson Parrelli 2020-10-29 10:16:21 -04:00 committed by GitHub
parent fbe62f0f3e
commit d1478c5ce0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 2 deletions

View file

@ -26,7 +26,10 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@ -38,6 +41,8 @@ class ContactDiscoveryV2 {
private static final String TAG = Log.tag(ContactDiscoveryV2.class);
private static final int MAX_NUMBERS = 20_500;
@WorkerThread
static DirectoryResult getDirectoryResult(@NonNull Context context,
@NonNull Set<String> databaseNumbers,
@ -47,7 +52,14 @@ class ContactDiscoveryV2 {
Set<String> allNumbers = SetUtil.union(databaseNumbers, systemNumbers);
FuzzyPhoneNumberHelper.InputResult inputResult = FuzzyPhoneNumberHelper.generateInput(allNumbers, databaseNumbers);
Set<String> sanitizedNumbers = sanitizeNumbers(inputResult.getNumbers());
Set<String> ignoredNumbers = new HashSet<>();
if (sanitizedNumbers.size() > MAX_NUMBERS) {
Set<String> randomlySelected = randomlySelect(sanitizedNumbers, MAX_NUMBERS);
ignoredNumbers = SetUtil.difference(sanitizedNumbers, randomlySelected);
sanitizedNumbers = randomlySelected;
}
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
KeyStore iasKeyStore = getIasKeyStore(context);
@ -56,7 +68,7 @@ class ContactDiscoveryV2 {
Map<String, UUID> results = accountManager.getRegisteredUsers(iasKeyStore, sanitizedNumbers, BuildConfig.CDS_MRENCLAVE);
FuzzyPhoneNumberHelper.OutputResultV2 outputResult = FuzzyPhoneNumberHelper.generateOutputV2(results, inputResult);
return new DirectoryResult(outputResult.getNumbers(), outputResult.getRewrites());
return new DirectoryResult(outputResult.getNumbers(), outputResult.getRewrites(), ignoredNumbers);
} catch (SignatureException | UnauthenticatedQuoteException | UnauthenticatedResponseException | Quote.InvalidQuoteFormatException e) {
Log.w(TAG, "Attestation error.", e);
throw new IOException(e);
@ -77,6 +89,13 @@ class ContactDiscoveryV2 {
}).collect(Collectors.toSet());
}
private static @NonNull Set<String> randomlySelect(@NonNull Set<String> numbers, int max) {
List<String> list = new ArrayList<>(numbers);
Collections.shuffle(list);
return new HashSet<>(list.subList(0, max));
}
private static KeyStore getIasKeyStore(@NonNull Context context) {
try {
TrustStore contactTrustStore = new IasTrustStore(context);

View file

@ -235,6 +235,7 @@ public class DirectoryHelper {
Set<RecipientId> inactiveIds = Stream.of(allNumbers)
.filterNot(activeNumbers::contains)
.filterNot(n -> result.getNumberRewrites().containsKey(n))
.filterNot(n -> result.getIgnoredNumbers().contains(n))
.map(recipientDatabase::getOrInsertFromE164)
.collect(Collectors.toSet());
@ -468,12 +469,15 @@ public class DirectoryHelper {
static class DirectoryResult {
private final Map<String, UUID> registeredNumbers;
private final Map<String, String> numberRewrites;
private final Set<String> ignoredNumbers;
DirectoryResult(@NonNull Map<String, UUID> registeredNumbers,
@NonNull Map<String, String> numberRewrites)
@NonNull Map<String, String> numberRewrites,
@NonNull Set<String> ignoredNumbers)
{
this.registeredNumbers = registeredNumbers;
this.numberRewrites = numberRewrites;
this.ignoredNumbers = ignoredNumbers;
}
@ -484,6 +488,10 @@ public class DirectoryHelper {
@NonNull Map<String, String> getNumberRewrites() {
return numberRewrites;
}
@NonNull Set<String> getIgnoredNumbers() {
return ignoredNumbers;
}
}
private static class UnlistedResult {