Skip to content

release(runway): cherry-pick fix(sentry): Resolve AggregatedBalanceSelector transaction volume spike by not passing trace into getAggregatedBalanceForAccount cp-13.40.0 - #44460

Merged
HowardBraham merged 1 commit into
release/13.40.0from
runway-cherry-pick-13.40.0-1784064190
Jul 14, 2026
Merged

HowardBraham merged 1 commit into
release/13.40.0from
runway-cherry-pick-13.40.0-1784064190

Conversation

@runway-github

@runway-github runway-github Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Motivation

AggregatedBalanceSelector accounts for 91% of all Sentry transaction
roots
,
and is growing as 13.38+ adoption climbs. Accepted transaction volume is
holding at approximately 36M per week against a 3.2M per week pre-spike
baseline.

ui/selectors/assets.ts forwards traceAsControllerCallback into
getAggregatedBalanceForAccount through the assets.balance-utils
helpers. That function runs inside a Redux selector, so it recomputes
per account group on every relevant state change and re-render. Each
computation emits a forced transaction root (span.op: custom), with no
sample gate.

The same callback was removed from assets-controller-init.ts in
#43213. That fix covered the controller entry point. The selector entry
point, introduced by the same upstream changeset
(MetaMask/core#8310), was
not covered, and reached production in 13.38.0 via #43635.

AggregatedBalanceSelector is the only one of the seven traces added by
core#8310 that is still emitting. The other six route through the
controller callback removed in #43213 and are already at zero, so this
call site closes core#8310 entirely.

Description

This commit removes traceAsControllerCallback from the two call sites
in ui/selectors/assets.ts that forward it into the unified balance
selectors, along with the now-unused import.

The optional trace parameters are also removed from
aggregateGroupBalance, calculateBalanceForAllWallets, and
calculateBalanceChangeForAccountGroup in
ui/selectors/assets.balance-utils.ts. Leaving them in place would
allow the callback to be reintroduced by supplying a single argument,
which is how it arrived in the first place. The test that asserted trace
forwarding is inverted into a regression test asserting no trace is
passed.

Test plan

  • eslint passes on all three touched files
  • tsc --noEmit reports no errors in the touched files
  • ui/selectors/assets.test.ts and
    ui/selectors/assets.balance-utils.test.ts pass (71 tests)
  • After release, AggregatedBalanceSelector
    volume

    drops to approximately zero on the fixed release

Changelog

CHANGELOG entry: null

References

Fixes #44447
Related: #43211, #43213, #43370,
MetaMask/core#8310


Note

Low Risk
Observability-only change; balance math and selector inputs are
unchanged aside from omitting the optional trace argument.

Overview
Stops Sentry transaction roots from AggregatedBalanceSelector by
no longer forwarding traceAsControllerCallback into unified wallet and
account-group balance calculations.

ui/selectors/assets.ts drops the trace import and stops passing a
callback into calculateBalanceForAllWallets and
calculateBalanceChangeForAccountGroup when assets-unify state is
enabled. In assets.balance-utils.ts, optional trace parameters are
removed end-to-end so getAggregatedBalanceForAccount is never given a
trace callback from this Redux path (which recomputes per group on every
relevant state change). The unit test now asserts the 7th argument to
the aggregator stays undefined instead of expecting trace
forwarding.

Reviewed by Cursor Bugbot for commit
c781a10. Bugbot is set up for automated
code reviews on this repo. Configure
here.

[81bacd2](https://github.com/MetaMask/metamask-extension/commit/81bacd28eec628ee189ef4c8ed7e1b88b353ef6a)

…elector` transaction volume spike by not passing `trace` into `getAggregatedBalanceForAccount` cp-13.40.0 (#44449)

## Motivation

`AggregatedBalanceSelector` accounts for [91% of all Sentry transaction
roots](https://metamask.sentry.io/explore/traces/?aggregateField=%7B%22groupBy%22%3A%22transaction%22%7D&aggregateField=%7B%22yAxes%22%3A%5B%22count%28span.duration%29%22%5D%7D&environment=production&mode=aggregate&project=273505&sort=-count%28span.duration%29&statsPeriod=7d&query=is_transaction%3Atrue),
and is growing as 13.38+ adoption climbs. Accepted transaction volume is
holding at approximately 36M per week against a 3.2M per week pre-spike
baseline.

`ui/selectors/assets.ts` forwards `traceAsControllerCallback` into
`getAggregatedBalanceForAccount` through the `assets.balance-utils`
helpers. That function runs inside a Redux selector, so it recomputes
per account group on every relevant state change and re-render. Each
computation emits a forced transaction root (`span.op: custom`), with no
sample gate.

The same callback was removed from `assets-controller-init.ts` in
#43213. That fix covered the controller entry point. The selector entry
point, introduced by the same upstream changeset
([MetaMask/core#8310](MetaMask/core#8310)), was
not covered, and reached production in 13.38.0 via #43635.

`AggregatedBalanceSelector` is the only one of the seven traces added by
core#8310 that is still emitting. The other six route through the
controller callback removed in #43213 and are already at zero, so this
call site closes core#8310 entirely.

## Description

This commit removes `traceAsControllerCallback` from the two call sites
in `ui/selectors/assets.ts` that forward it into the unified balance
selectors, along with the now-unused import.

The optional `trace` parameters are also removed from
`aggregateGroupBalance`, `calculateBalanceForAllWallets`, and
`calculateBalanceChangeForAccountGroup` in
`ui/selectors/assets.balance-utils.ts`. Leaving them in place would
allow the callback to be reintroduced by supplying a single argument,
which is how it arrived in the first place. The test that asserted trace
forwarding is inverted into a regression test asserting no trace is
passed.

## Test plan

- [x] `eslint` passes on all three touched files
- [x] `tsc --noEmit` reports no errors in the touched files
- [x] `ui/selectors/assets.test.ts` and
`ui/selectors/assets.balance-utils.test.ts` pass (71 tests)
- [ ] After release, [`AggregatedBalanceSelector`
volume](https://metamask.sentry.io/explore/traces/?aggregateField=%7B%22groupBy%22%3A%22release%22%7D&aggregateField=%7B%22yAxes%22%3A%5B%22count%28span.duration%29%22%5D%7D&environment=production&mode=aggregate&project=273505&sort=-count%28span.duration%29&statsPeriod=30d&query=transaction%3AAggregatedBalanceSelector)
drops to approximately zero on the fixed release

## Changelog

CHANGELOG entry: null

## References

Fixes #44447
Related: #43211, #43213, #43370,
[MetaMask/core#8310](MetaMask/core#8310)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Observability-only change; balance math and selector inputs are
unchanged aside from omitting the optional trace argument.
> 
> **Overview**
> Stops **Sentry transaction roots** from `AggregatedBalanceSelector` by
no longer forwarding `traceAsControllerCallback` into unified wallet and
account-group balance calculations.
> 
> `ui/selectors/assets.ts` drops the trace import and stops passing a
callback into `calculateBalanceForAllWallets` and
`calculateBalanceChangeForAccountGroup` when assets-unify state is
enabled. In `assets.balance-utils.ts`, optional `trace` parameters are
removed end-to-end so `getAggregatedBalanceForAccount` is never given a
trace callback from this Redux path (which recomputes per group on every
relevant state change). The unit test now asserts the 7th argument to
the aggregator stays **undefined** instead of expecting trace
forwarding.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
c781a10. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@github-actions

Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamask-ci metamask-ci Bot added the team-bots Bot team (for MetaMask Bot, Runway Bot, etc.) label Jul 14, 2026
@HowardBraham
HowardBraham enabled auto-merge (squash) July 14, 2026 21:26
@sonarqubecloud

Copy link
Copy Markdown

@metamask-ci

metamask-ci Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor
Builds ready [30c61cf]
Deprecated Browserify fallback builds
⚡ Performance Benchmarks (Total: 🟢 15 pass · 🟡 9 warn · 🔴 0 fail)

Baseline (latest main): 81bacd2 | Date: 7/14/2026 | Pipeline: 29369340628 | Baseline logs

Interaction Benchmarks · Samples: 5
Benchmarkchrome-webpackfirefox-webpack
loadNewAccount
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
confirmTx
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
bridgeUserActions
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]

📈 Results compared to the previous 5 runs on main

  • ↓ loadNewAccount/load_new_account: -26%
  • ↓ loadNewAccount/total: -26%
  • ↓ loadNewAccount/inp: -11%
  • ↑ confirmTx/confirm_tx: +47%
  • ↑ confirmTx/longTaskTotalDuration: +16%
  • ↑ confirmTx/tbt: +18%
  • ↑ confirmTx/total: +47%
  • ↑ bridgeUserActions/bridge_load_page: +14%
  • ↑ bridgeUserActions/longTaskCount: +43%
  • ↑ bridgeUserActions/longTaskTotalDuration: +24%
  • ↓ bridgeUserActions/tbt: -39%
  • ↓ bridgeUserActions/inp: -18%
  • ↑ loadNewAccount/load_new_account: +59%
  • ↑ loadNewAccount/total: +59%
  • ↓ loadNewAccount/inp: -11%
  • ↑ loadNewAccount/lcp: +1131%
  • ↑ confirmTx/confirm_tx: +63%
  • ↓ confirmTx/longTaskCount: -100%
  • ↓ confirmTx/longTaskTotalDuration: -100%
  • ↓ confirmTx/longTaskMaxDuration: -100%
  • ↓ confirmTx/tbt: -100%
  • ↑ confirmTx/total: +63%
  • ↓ confirmTx/inp: -13%
  • ↓ confirmTx/fcp: -44%
  • ↑ confirmTx/lcp: +1259%
  • ↑ bridgeUserActions/bridge_load_page: +220%
  • ↑ bridgeUserActions/bridge_load_asset_picker: +73%
  • ↓ bridgeUserActions/longTaskCount: -100%
  • ↓ bridgeUserActions/longTaskTotalDuration: -100%
  • ↓ bridgeUserActions/longTaskMaxDuration: -100%
  • ↓ bridgeUserActions/tbt: -100%
  • ↑ bridgeUserActions/total: +189%
  • ↓ bridgeUserActions/fcp: -46%
  • ↑ bridgeUserActions/lcp: +1245%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 loadNewAccount/FCP: p75 1.8s
  • 🟡 loadNewAccount/FCP: p75 1.8s
Startup Benchmarks · Samples: 100
Benchmarkchrome-webpackfirefox-webpack
startupStandardHome
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
startupPowerUserHome
[Sentry log · main/release]
–🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • ↑ startupStandardHome/initialActions: +15%
  • ↑ startupStandardHome/numNetworkReqs: +15%
  • ↑ startupStandardHome/longTaskCount: +15%
  • ↓ startupStandardHome/lcp: -63%
  • ↓ startupStandardHome/uiStartup: -25%
  • ↓ startupStandardHome/load: -24%
  • ↓ startupStandardHome/domContentLoaded: -24%
  • ↓ startupStandardHome/domInteractive: -48%
  • ↓ startupStandardHome/backgroundConnect: -22%
  • ↓ startupStandardHome/firstReactRender: -26%
  • ↓ startupStandardHome/initialActions: -50%
  • ↓ startupStandardHome/loadScripts: -24%
  • ↓ startupStandardHome/setupStore: -30%
  • ↓ startupStandardHome/fcp: -42%
  • ↓ startupStandardHome/lcp: -24%
  • ↑ startupPowerUserHome/setupStore: +41%
  • ↓ startupPowerUserHome/fcp: -13%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 startupPowerUserHome/LCP: p75 3.6s
User Journey Benchmarks · Samples: 5 · mock API
Benchmarkchrome-webpackfirefox-webpack
onboardingImportWallet
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
onboardingNewWallet
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
🟡 total
assetDetails
[Sentry log · main/release]
🟡 [CI log]🟢 [CI log]
solanaAssetDetails
[Sentry log · main/release]
🟢 [CI log]🟢 [CI log]
importSrpHome
[Sentry log · main/release]
🟡 [CI log]🟡 [CI log]
sendTransactions
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]
swap
[Sentry log · main/release]
🟢 [CI log]🟡 [CI log]

📈 Results compared to the previous 5 runs on main

  • ↓ onboardingImportWallet/srpButtonToSrpForm: -20%
  • ↓ onboardingImportWallet/confirmSrpToPwForm: -22%
  • ↓ onboardingImportWallet/pwFormToMetricsScreen: -19%
  • ↓ onboardingImportWallet/metricsToWalletReadyScreen: -41%
  • ↓ onboardingImportWallet/doneButtonToHomeScreen: -92%
  • ↓ onboardingImportWallet/openAccountMenuToAccountListLoaded: -99%
  • ↓ onboardingImportWallet/longTaskCount: -92%
  • ↓ onboardingImportWallet/longTaskTotalDuration: -97%
  • ↓ onboardingImportWallet/longTaskMaxDuration: -92%
  • ↓ onboardingImportWallet/tbt: -99%
  • ↓ onboardingImportWallet/total: -91%
  • ↓ onboardingNewWallet/srpButtonToPwForm: -23%
  • ↓ onboardingNewWallet/createPwToRecoveryScreen: -32%
  • ↓ onboardingNewWallet/skipBackupToMetricsScreen: -31%
  • ↓ onboardingNewWallet/agreeButtonToOnboardingSuccess: -48%
  • ↓ onboardingNewWallet/doneButtonToAssetList: -56%
  • ↓ onboardingNewWallet/longTaskCount: -100%
  • ↓ onboardingNewWallet/longTaskTotalDuration: -100%
  • ↓ onboardingNewWallet/longTaskMaxDuration: -100%
  • ↓ onboardingNewWallet/tbt: -100%
  • ↓ onboardingNewWallet/total: -51%
  • ↓ solanaAssetDetails/assetClickToPriceChart: -36%
  • ↓ solanaAssetDetails/total: -36%
  • ↓ solanaAssetDetails/inp: -18%
  • ↑ solanaAssetDetails/lcp: +53%
  • ↓ solanaAssetDetails/cls: -86%
  • ↓ importSrpHome/loginToHomeScreen: -19%
  • ↑ importSrpHome/openAccountMenuAfterLogin: +24%
  • ↓ importSrpHome/homeAfterImportWithNewWallet: -60%
  • ↓ importSrpHome/longTaskCount: -47%
  • ↓ importSrpHome/longTaskTotalDuration: -50%
  • ↓ importSrpHome/longTaskMaxDuration: -11%
  • ↓ importSrpHome/tbt: -47%
  • ↓ importSrpHome/total: -54%
  • ↓ importSrpHome/inp: -10%
  • ↓ importSrpHome/cls: -29%
  • ↑ sendTransactions/openSendPageFromHome: +123%
  • ↑ sendTransactions/reviewTransactionToConfirmationPage: +92%
  • ↑ sendTransactions/longTaskCount: +25%
  • ↑ sendTransactions/longTaskTotalDuration: +14%
  • ↑ sendTransactions/longTaskMaxDuration: +14%
  • ↓ sendTransactions/tbt: -55%
  • ↑ sendTransactions/total: +88%
  • ↓ sendTransactions/inp: -16%
  • ↑ sendTransactions/fcp: +12%
  • ↑ sendTransactions/lcp: +13%
  • ↓ sendTransactions/cls: -86%
  • ↑ swap/fetchAndDisplaySwapQuotes: +118%
  • ↑ swap/longTaskTotalDuration: +15%
  • ↓ swap/tbt: -75%
  • ↑ swap/total: +117%
  • ↓ swap/cls: -86%

🌐 Core Web Vitals — 🟢 good · 🟡 needs improvement · 🔴 poor (web.dev thresholds)

  • 🟡 assetDetails/FCP: p75 1.8s
  • 🟡 importSrpHome/INP: p75 264ms
  • 🟡 importSrpHome/FCP: p75 1.9s
  • 🟡 sendTransactions/FCP: p75 1.9s
  • 🔴 swap/INP: p75 736ms
  • 🟡 swap/FCP: p75 1.9s
Dapp Page Load Benchmarks · Samples: 100
Benchmarkchrome-webpack
dappPageLoad
[Sentry log · main/release]
🟢 [CI log]
Bundle sizes
  • background: 14.22 MiB
  • ui: 17.06 MiB
  • common: 0 Bytes
  • other: 998.07 KiB
  • contentScripts: 1.87 MiB
  • zip: 27.03 MiB
No matching bundle-size baseline was found in the history data, so diff values are omitted.

@HowardBraham
HowardBraham merged commit 5d2bd7d into release/13.40.0 Jul 14, 2026
200 checks passed
@HowardBraham
HowardBraham deleted the runway-cherry-pick-13.40.0-1784064190 branch July 14, 2026 21:54
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 14, 2026
@metamaskbot metamaskbot added the release-13.40.0 Issue or pull request that will be included in release 13.40.0 label Jul 15, 2026
@gauthierpetetin

Copy link
Copy Markdown
Contributor

No release label on PR. Adding release label release-13.40.0 on PR, as PR was cherry-picked in branch 13.40.0.

This branch was previously deployed

1 inactive deployment
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-13.40.0 Issue or pull request that will be included in release 13.40.0 risk:medium team-bots Bot team (for MetaMask Bot, Runway Bot, etc.)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants