Cache GroupFields

Computing GroupFields is costly so cache them instead of doing the
derivation anew on every message.
This commit is contained in:
Fedor Indutny 2021-04-09 11:20:37 -07:00
parent 847cc3e055
commit 9846fb8edf

View file

@ -12,6 +12,7 @@ import {
} from 'lodash'; } from 'lodash';
import { ClientZkGroupCipher } from 'zkgroup'; import { ClientZkGroupCipher } from 'zkgroup';
import { v4 as getGuid } from 'uuid'; import { v4 as getGuid } from 'uuid';
import LRU from 'lru-cache';
import { import {
getCredentialsForToday, getCredentialsForToday,
GROUP_CREDENTIALS_KEY, GROUP_CREDENTIALS_KEY,
@ -202,6 +203,18 @@ export type GroupV2ChangeType = {
details: Array<GroupV2ChangeDetailType>; details: Array<GroupV2ChangeDetailType>;
}; };
export type GroupFields = {
readonly id: ArrayBuffer;
readonly secretParams: ArrayBuffer;
readonly publicParams: ArrayBuffer;
};
const MAX_CACHED_GROUP_FIELDS = 100;
const groupFieldsCache = new LRU<string, GroupFields>({
max: MAX_CACHED_GROUP_FIELDS,
});
const { updateConversation } = dataInterface; const { updateConversation } = dataInterface;
if (!isNumber(MAX_MESSAGE_SCHEMA)) { if (!isNumber(MAX_MESSAGE_SCHEMA)) {
@ -1314,18 +1327,26 @@ export function idForLogging(groupId: string | undefined): string {
return `groupv2(${groupId})`; return `groupv2(${groupId})`;
} }
export function deriveGroupFields( export function deriveGroupFields(masterKey: ArrayBuffer): GroupFields {
masterKey: ArrayBuffer const cacheKey = arrayBufferToBase64(masterKey);
): { id: ArrayBuffer; secretParams: ArrayBuffer; publicParams: ArrayBuffer } { const cached = groupFieldsCache.get(cacheKey);
if (cached) {
return cached;
}
window.log.info('deriveGroupFields: cache miss');
const secretParams = deriveGroupSecretParams(masterKey); const secretParams = deriveGroupSecretParams(masterKey);
const publicParams = deriveGroupPublicParams(secretParams); const publicParams = deriveGroupPublicParams(secretParams);
const id = deriveGroupID(secretParams); const id = deriveGroupID(secretParams);
return { const fresh = {
id, id,
secretParams, secretParams,
publicParams, publicParams,
}; };
groupFieldsCache.set(cacheKey, fresh);
return fresh;
} }
async function makeRequestWithTemporalRetry<T>({ async function makeRequestWithTemporalRetry<T>({