Skip to content

Conversation

mathieuartu
Copy link
Contributor

@mathieuartu mathieuartu commented Sep 26, 2025

Explanation

- Use deferred promises for encryption/decryption KDF operations ([#6736](https://github.com/MetaMask/core/pull/6736))
  - That will prevent duplicate KDF operations from being computed if one with the same options is already in progress.
  - For operations that already completed, we use the already existing cache.

This improves startup performance on mobile by ~70%; going from an average of ~6s to an average of ~2s for the time it takes to derive the key.

References

Fixes: https://consensyssoftware.atlassian.net/browse/MUL-1100

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed, highlighting breaking changes as necessary
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

Note

Deduplicates concurrent scrypt KDF operations via a bounded promise cache, adds concurrency/eviction tests, and updates changelog.

  • Encryption (src/shared/encryption):
    • encryption.ts: Add deferred KDF promise cache to avoid duplicate scrypt derivations; cap size using MAX_KDF_PROMISE_CACHE_SIZE; add cache-key generation and #performKdfOperation helper; minor refactors to use salt consistently.
    • constants.ts: Add MAX_KDF_PROMISE_CACHE_SIZE.
  • Tests:
    • encryption.test.ts: Add concurrent encrypt/decrypt tests (same/different passwords), load tests, and cache size eviction test.
  • Changelog:
    • Note use of deferred promises for KDF to prevent duplicate work.

Written by Cursor Bugbot for commit 3b179d1. This will update automatically on new commits. Configure here.

@mathieuartu mathieuartu marked this pull request as ready for review September 26, 2025 16:01
@mathieuartu mathieuartu requested review from a team as code owners September 26, 2025 16:01
fabiobozzo
fabiobozzo previously approved these changes Sep 26, 2025
Copy link
Contributor

@fabiobozzo fabiobozzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👏 Let's make KDF work as fast as 🚀 And one day we'll merge #6097 too hopefully, I remember that PR eheh

@Tlees-MMI
Copy link

@fabiobozzo lol we'll make sure to get it in the first RC after BIP-44!

Copy link
Member

@gantunesr gantunesr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, will approve after the comments are resolved

@mathieuartu mathieuartu requested a review from a team as a code owner September 29, 2025 08:05
cmd-ob
cmd-ob previously approved these changes Sep 29, 2025
cursor[bot]

This comment was marked as outdated.

import { SHARED_SALT } from '../shared/encryption/constants';
import { Env } from '../shared/env';
import { USER_STORAGE_FEATURE_NAMES } from '../shared/storage-schema';
import type { UserStorageGenericFeatureKey } from 'src/shared/storage-schema';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be ../shared/storage-schema? I guess src/... probably works too

ccharly
ccharly previously approved these changes Sep 29, 2025
const results = await Promise.all(promises);
expect(results).toHaveLength(numOperations);

// Verify a sampling of results can be decrypted (testing all 25 would be slow)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:

Suggested change
// Verify a sampling of results can be decrypted (testing all 25 would be slow)
// Verify a sampling of results can be decrypted (testing 25 would be slow)

@mathieuartu mathieuartu merged commit 947355c into main Sep 29, 2025
239 checks passed
@mathieuartu mathieuartu deleted the feat/user-storage-encryption-kdf-deferred branch September 29, 2025 09:44
mathieuartu added a commit that referenced this pull request Sep 29, 2025
## Explanation

Release for `@metamask/profile-sync-controller` &
`@metamask/multichain-account-service`.

```md
## [25.1.0]

### Changed

- Use deferred promises for encryption/decryption KDF operations ([#6736](#6736))
  - That will prevent duplicate KDF operations from being computed if one with the same options is already in progress.
  - For operations that already completed, we use the already existing cache.
- Bump `@metamask/utils` from `^11.8.0` to `^11.8.1` ([#6708](#6708))
- Bump `@metamask/keyring-api` from `^20.1.0` to `^21.0.0` ([#6560](#6560))
- Bump `@metamask/keyring-internal-api` from `^8.1.0` to `^9.0.0` ([#6560](#6560))
- Strip `srpSessionData.token.accessToken` from state logs ([#6553](#6553))
  - We haven't started using the `includeInStateLogs` metadata yet in clients, so this will have no functional impact. This change brings this metadata into alignment with the hard-coded state log generation performed by clients.today.
- Add dependency on `@metamask/utils` ([#6553](#6553))
- Bump `@metamask/base-controller` from `^8.3.0` to `^8.4.0` ([#6632](#6632))
```

## References

<!--
Are there any issues that this pull request is tied to?
Are there other links that reviewers should consult to understand these
changes better?
Are there client or consumer pull requests to adopt any breaking
changes?

For example:

* Fixes #12345
* Related to #67890
-->

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've communicated my changes to consumers by [updating changelogs
for packages I've
changed](https://github.com/MetaMask/core/tree/main/docs/contributing.md#updating-changelogs),
highlighting breaking changes as necessary
- [ ] I've prepared draft pull requests for clients and consumer
packages to resolve any breaking changes


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Releases core 589.0.0, publishing @metamask/profile-sync-controller
25.1.0 and @metamask/multichain-account-service 1.3.0, and bumps
dependent packages and changelogs.
> 
> - **Release**: `@metamask/core-monorepo` to `589.0.0`.
> - **Packages**:
>   - `@metamask/[email protected]`
> - Use deferred promises for KDF operations; update deps and strip
`srpSessionData.token.accessToken` from state logs.
>   - `@metamask/[email protected]`
>     - Add `{Btc, Trx}AccountProvider`; update compare links.
> - **Deps Bumped**:
> - Update references to `@metamask/profile-sync-controller` to
`^25.1.0` in `account-tree-controller`,
`notification-services-controller`, `subscription-controller`, and
lockfile.
> - Update references to `@metamask/multichain-account-service` to
`^1.3.0` in `assets-controllers`, `account-tree-controller`, and
lockfile.
> - **Changelogs**:
> - Add Unreleased note for `assets-controllers` reflecting
`multichain-account-service` bump.
>   - Add `1.3.0` section and links in `multichain-account-service`.
>   - Add `25.1.0` section and links in `profile-sync-controller`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
88351ca. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Antonio Regadas <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants