Conversation
listAccounts, fetchAndUpdateMetamaskNotifications, and markMetamaskNotificationsAsRead all rebuild an array (spread/map) and reassign it unconditionally, even when the result is identical to what's already in state. Since state.update() uses Immer, assigning a new-but-equal reference still emits a patch and publishes stateChange, which triggers a full state persist. listAccounts in particular gets called by several unrelated methods just to read the current accounts array, so on a wallet with many accounts this fired a lot more often than the account set itself actually changed. Add a cheap check before each of the three writes so they're skipped when nothing changed, and add tests asserting no stateChange is published in that case (and that it still is when something genuinely changes).
juanmigdr
force-pushed
the
chore/skip-no-op-notification-state-writes
branch
from
September 16, 2026 17:39
70479a2 to
8febbf2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Explanation
listAccounts,fetchAndUpdateMetamaskNotifications, andmarkMetamaskNotificationsAsReadeach rebuild an array (a spread of aSet, or a.map()over the notification list) and assign it back to state unconditionally, even when the result is identical to what's already there.this.update()is backed by Immer, and Immer only compares by reference. A new array with the exact same contents still counts as "changed" to Immer, so every one of these calls published astateChangeand triggered a full state persist, whether or not anything actually changed.listAccountsis the one that matters most in practice: it's called from several unrelated public methods just to read the currentaccountsarray (not because the caller cares about diffing accounts), so on a wallet with a lot of accounts under one SRP it was rewritingsubscriptionAccountsSeenfar more often than the account set itself ever changes.Before: any call to these three methods writes and persists, every time.
After: they only write when the account set / notification list / read list actually differs from what's stored.
Confirmed on a real device with a large multi-account wallet — before this fix, most
listAccountscalls during a normal session were reassigning an identical array; after, they don't touch state at all unless an account was actually added or removed.References
None
Checklist
Note
Low Risk
Behavioral change is limited to suppressing redundant state persistence and events; observable state when data actually changes should match prior behavior.
Overview
Stops unnecessary controller state updates when account listing, notification fetch, or mark-as-read rebuild arrays that are deep-equal to what is already stored. Immer treated every new array reference as a change, so
stateChangeand persisted state fired even when nothing meaningful changed—especially on repeatedlistAccountscalls in multi-account wallets.subscriptionAccountsSeenis written only when the keyring account set actually adds or removes addresses (not on everylistAccountsinvocation).metamaskNotificationsListis updated after fetch or mark-as-read only whenlodashisEqualsays the new list differs.metamaskNotificationsReadListgrows only when at least one new read ID is introduced.Tests assert no
stateChange(or no Immer patch on the notifications list) for idempotent repeats, and that updates still occur when data genuinely changes.Reviewed by Cursor Bugbot for commit 8febbf2. Bugbot is set up for automated code reviews on this repo. Configure here.