fix: Deduplicate key OTK uploads

We do the key upload asynchronously without awaiting it. This means we
may do multiple syncs before the key upload finishes. So we may generate
more keys than we should.

To fix that prevent multiple key uploads from running at once. This may
lead to outdated key uploads in some cases if we miss an OTK being used
in sync. However, the next sync will still tell us about that so in the
worst case this might delay key uploads by 30s (with the default sync
timeout), which for normal usage should be completely acceptable.
This commit is contained in:
Nicolas Werner 2024-10-07 19:05:54 +02:00
parent 583be5ece7
commit 6a28ab05d0
No known key found for this signature in database
GPG Key ID: B38119FF80087618
1 changed files with 36 additions and 28 deletions

View File

@ -28,6 +28,7 @@ import 'package:matrix/encryption/utils/json_signature_check_extension.dart';
import 'package:matrix/encryption/utils/olm_session.dart';
import 'package:matrix/matrix.dart';
import 'package:matrix/msc_extensions/msc_3814_dehydrated_devices/api.dart';
import 'package:matrix/src/utils/run_benchmarked.dart';
import 'package:matrix/src/utils/run_in_root.dart';
class OlmManager {
@ -326,11 +327,16 @@ class OlmManager {
return false;
}
final _otkUpdateDedup = AsyncCache<void>.ephemeral();
Future<void> handleDeviceOneTimeKeysCount(
Map<String, int>? countJson, List<String>? unusedFallbackKeyTypes) async {
if (!enabled) {
return;
}
await _otkUpdateDedup.fetch(() =>
runBenchmarked('handleOtkUpdate', () async {
final haveFallbackKeys = encryption.isMinOlmVersion(3, 2, 0);
// Check if there are at least half of max_number_of_one_time_keys left on the server
// and generate and upload more if not.
@ -357,12 +363,14 @@ class OlmManager {
if (keyCount < (_olmAccount!.max_number_of_one_time_keys() / 2) ||
!unusedFallbackKey) {
await uploadKeys(
oldKeyCount: keyCount < (_olmAccount!.max_number_of_one_time_keys() / 2)
oldKeyCount:
keyCount < (_olmAccount!.max_number_of_one_time_keys() / 2)
? keyCount
: null,
unusedFallbackKey: haveFallbackKeys ? unusedFallbackKey : null,
);
}
}));
}
Future<void> storeOlmSession(OlmSession session) async {