diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV2.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV2.java index 4e17def4b3..f677c8508c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV2.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/ContactDiscoveryV2.java @@ -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 databaseNumbers, @@ -47,7 +52,14 @@ class ContactDiscoveryV2 { Set allNumbers = SetUtil.union(databaseNumbers, systemNumbers); FuzzyPhoneNumberHelper.InputResult inputResult = FuzzyPhoneNumberHelper.generateInput(allNumbers, databaseNumbers); Set sanitizedNumbers = sanitizeNumbers(inputResult.getNumbers()); + Set ignoredNumbers = new HashSet<>(); + if (sanitizedNumbers.size() > MAX_NUMBERS) { + Set 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 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 randomlySelect(@NonNull Set numbers, int max) { + List 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); diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java index cb84c3f3ee..39df483974 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java @@ -235,6 +235,7 @@ public class DirectoryHelper { Set 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 registeredNumbers; private final Map numberRewrites; + private final Set ignoredNumbers; DirectoryResult(@NonNull Map registeredNumbers, - @NonNull Map numberRewrites) + @NonNull Map numberRewrites, + @NonNull Set ignoredNumbers) { this.registeredNumbers = registeredNumbers; this.numberRewrites = numberRewrites; + this.ignoredNumbers = ignoredNumbers; } @@ -484,6 +488,10 @@ public class DirectoryHelper { @NonNull Map getNumberRewrites() { return numberRewrites; } + + @NonNull Set getIgnoredNumbers() { + return ignoredNumbers; + } } private static class UnlistedResult {