Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: NFT detection running too many times #3917

Merged
merged 3 commits into from
Feb 15, 2024

Conversation

bergeron
Copy link
Contributor

@bergeron bergeron commented Feb 14, 2024

Explanation

The NftDetectionController was making unnecessary HTTP requests.

(1) It was fetching NFTs when any setting changes:

Screen.Recording.2024-02-13.at.6.11.28.PM.mov

(2) When each polling interval arrives, it can send ~7 identical requests instead of 1. See timeline:

Screenshot 2024-02-13 at 6 08 53 PM

(3) one redundant request when switching accounts

All come from onPreferencesStateChange triggering a re-start.

(2) happens because it fires ~7 times on startup from keyring related updates. This causes each to run:

this.stopPolling();
await this.detectNfts();
this.intervalId = setInterval(...)

Because detectNfts is async, intervalId is still undefined. So they each schedule their own interval without stopping a previous interval.

Fix: Only start/stop when relevant settings change.

References

Changelog

@metamask/assets-controllers

  • FIXED: NFT detection running too many times

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 highlighted breaking changes using the "BREAKING" category above as appropriate

@bergeron bergeron requested a review from a team as a code owner February 14, 2024 02:46
salimtb
salimtb previously approved these changes Feb 14, 2024
sahar-fehri
sahar-fehri previously approved these changes Feb 14, 2024
Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Are there any tests we can write to ensure that this doesn't occur again?

@bergeron
Copy link
Contributor Author

bergeron commented Feb 14, 2024

Are there any tests we can write to ensure that this doesn't occur again?

probably. I'll try to write a unit test flipping some preferences and checking how many times the HTTP route is called

mcmire
mcmire previously approved these changes Feb 14, 2024
Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

@bergeron Okay, cool. These tests are not in the best shape, and I'm noticing that there aren't any tests at all for when useNftDetection is set. This seems pretty important, so if you have to spend more than an hour on this, don't worry about it — we can add these tests later. From looking at the changes here, it makes sense that this would reduce the number of calls, so I'll approve it.

@bergeron bergeron dismissed stale reviews from mcmire, sahar-fehri, and salimtb via 554b7d0 February 14, 2024 21:08
@bergeron
Copy link
Contributor Author

Added a unit test that failed on the old code, and passes on the new code

Copy link
Contributor

@mcmire mcmire left a comment

Choose a reason for hiding this comment

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

Glad you were able to figure it out. Nice and simple!

@bergeron bergeron merged commit 3ea7a48 into main Feb 15, 2024
136 checks passed
@bergeron bergeron deleted the brian/nft-detection-too-many-calls branch February 15, 2024 16:16
MajorLift pushed a commit that referenced this pull request Feb 16, 2024
## Explanation

The `NftDetectionController` was making unnecessary HTTP requests.

(1) It was fetching NFTs when any setting changes:


https://github.com/MetaMask/core/assets/3500406/297b1889-ee17-4c57-890b-8f94e4b1be4b

(2) When each polling interval arrives, it can send ~7 identical
requests instead of 1. See timeline:

<img width="1001" alt="Screenshot 2024-02-13 at 6 08 53 PM"
src="https://github.com/MetaMask/core/assets/3500406/c8052108-7e2e-4d42-8732-05b25311a2bf">

(3) one redundant request when switching accounts

All come from `onPreferencesStateChange` triggering a re-start.

(2) happens because it fires ~7 times on startup from keyring related
updates. This causes each to run:

```
this.stopPolling();
await this.detectNfts();
this.intervalId = setInterval(...)
```

Because `detectNfts` is async, `intervalId` is still undefined. So they
each schedule their own interval without stopping a previous interval.

Fix: Only start/stop when relevant settings change.

## 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?

For example:

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

## Changelog

<!--
If you're making any consumer-facing changes, list those changes here as
if you were updating a changelog, using the template below as a guide.

(CATEGORY is one of BREAKING, ADDED, CHANGED, DEPRECATED, REMOVED, or
FIXED. For security-related issues, follow the Security Advisory
process.)

Please take care to name the exact pieces of the API you've added or
changed (e.g. types, interfaces, functions, or methods).

If there are any breaking changes, make sure to offer a solution for
consumers to follow once they upgrade to the changes.

Finally, if you're only making changes to development scripts or tests,
you may replace the template below with "None".
-->

### `@metamask/assets-controllers`

- **FIXED**: NFT detection running too many times

## 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 highlighted breaking changes using the "BREAKING" category
above as appropriate
bergeron added a commit to MetaMask/metamask-extension that referenced this pull request Feb 21, 2024
## **Description**

Patches MetaMask/core#3917, fixing an issue
where NFT detection was running too many times.

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/23082?quickstart=1)

## **Related issues**


## **Manual testing steps**


## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've clearly explained what problem this PR is solving and how it
is solved.
- [ ] I've linked related issues
- [ ] I've included manual testing steps
- [ ] I've included screenshots/recordings if applicable
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
- [ ] I’ve properly set the pull request status:
  - [ ] In case it's not yet "ready for review", I've set it to "draft".
- [ ] In case it's "ready for review", I've changed it from "draft" to
"non-draft".

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
dbrans pushed a commit to MetaMask/metamask-extension that referenced this pull request Feb 27, 2024
## **Description**

Patches MetaMask/core#3917, fixing an issue
where NFT detection was running too many times.

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/23082?quickstart=1)

## **Related issues**


## **Manual testing steps**


## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've clearly explained what problem this PR is solving and how it
is solved.
- [ ] I've linked related issues
- [ ] I've included manual testing steps
- [ ] I've included screenshots/recordings if applicable
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
- [ ] I’ve properly set the pull request status:
  - [ ] In case it's not yet "ready for review", I've set it to "draft".
- [ ] In case it's "ready for review", I've changed it from "draft" to
"non-draft".

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants