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