Skip to content

Correct invalid initial selectedNetworkClientId#5851

Merged
mcmire merged 2 commits intomainfrom
handle-invalid-selected-network-client-id
May 28, 2025
Merged

Correct invalid initial selectedNetworkClientId#5851
mcmire merged 2 commits intomainfrom
handle-invalid-selected-network-client-id

Conversation

@mcmire
Copy link
Copy Markdown
Contributor

@mcmire mcmire commented May 22, 2025

Explanation

Currently, when NetworkController is instantiated with pre-existing state that contains an invalid selectedNetworkClientId — that is, no RPC endpoint exists which has the same network client ID — then it throws an error. This was intentionally done to bring attention to possible bugs in NetworkController, but this has the unfortunate side effect of bricking users' wallets.

To fix this, we now correct an invalid selectedNetworkClientId to point to the default RPC endpoint of the first network sorted by chain ID (which in the vast majority of cases will be Mainnet). We still do want to know about this, though, so we log the error in Sentry.

References

Fixes #5739.

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

@mcmire mcmire force-pushed the handle-invalid-selected-network-client-id branch from 291f6b3 to 3d36c69 Compare May 22, 2025 20:00
Base automatically changed from add-error-reporting-service to main May 23, 2025 20:08
Currently, when NetworkController is instantiated with pre-existing
state that contains an invalid `selectedNetworkClientId` — that is, no
RPC endpoint exists which has the same network client ID — then it
throws an error. This was intentionally done to bring attention to
possible bugs in NetworkController, but this has the unfortunate side
effect of bricking users' wallets.

To fix this, we now correct an invalid `selectedNetworkClientId` to
point to the default RPC endpoint of the first network sorted by chain
ID (which in the vast majority of cases will be Mainnet). We still do
want to know about this, though, so we log the error in Sentry.
@mcmire mcmire force-pushed the handle-invalid-selected-network-client-id branch from 3d36c69 to 409b54c Compare May 23, 2025 21:02
NetworkControllerActions,
NetworkControllerEvents
>;
messenger: RootMessenger;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The type of the messenger in these tests only took internal actions and events into consideration and not external actions, so I've had to correct all of them.

return messenger.getRestricted({
name: 'NetworkController',
allowedActions: [],
allowedActions: ['ErrorReportingService:captureException'],
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Here we need to add ErrorReportingService:captureException to the list of external actions because we are now using it in the controller.

@mcmire mcmire marked this pull request as ready for review May 23, 2025 21:12
@mcmire mcmire requested review from a team as code owners May 23, 2025 21:12
@mcmire mcmire added the team-wallet-framework Deprecated: Please use `team-core-platform` instead. label May 23, 2025
Copy link
Copy Markdown
Contributor

@cryptodev-2s cryptodev-2s left a comment

Choose a reason for hiding this comment

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

LGTM!

@mcmire mcmire enabled auto-merge (squash) May 28, 2025 14:46
@mcmire mcmire merged commit 0830705 into main May 28, 2025
206 checks passed
@mcmire mcmire deleted the handle-invalid-selected-network-client-id branch May 28, 2025 14:51
mcmire added a commit that referenced this pull request May 29, 2025
This release primarily includes the following two fixes to
`network-controller`:

- Rather than throwing an error, NetworkController now corrects an
invalid initial `selectedNetworkClientId` to point to the default RPC
endpoint of the first network sorted by chain ID, then logs the error
via Sentry ([#5851](#5851))
- Fix the block tracker so that it will now reject if an error is thrown
while making the request instead of hanging
([#5860](#5860))

---

Full list of packages and versions in this release:

- `@metamask/error-reporting-service` (1.0.0)
- `@metamask/network-controller` (23.5.0 -> 23.5.1)
DDDDDanica pushed a commit to MetaMask/metamask-extension that referenced this pull request Jun 4, 2025
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

If `selectedNetworkClientId` in NetworkController state does not point
to an RPC endpoint and therefore does not also point to a network
client, then we automatically correct it to point to the default RPC
endpoint of the first network (sorted by chain ID). This allows the
wallet to start normally.

This change is being added as a patch because we do not want to upgrade
to 23.5.1, as doing so would fix another unrelated bug, and we want to
limit the scope of the change.

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

## **Related issues**

See MetaMask/core#5851 for the equivalent
changes to network-controller that were copied here.

Also see MetaMask/metamask-mobile#15941 for a
similar fix on the mobile side.

## **Manual testing steps**

1. Check out this branch.
2. Run `yarn start`.
3. Open the extension, and go through onboarding.
4. Close the UI.
5. Find the extension and open the service worker.
6. Navigate to the Application tab.
7. Click on "Extension storage", then "Local".
8. Click on the value for "data".
9. Look in the preview pane below (rendered JSON), right-click and
choose "Copy value".
10. Paste the value in another screen such as TextEdit.
11. Look for `selectedNetworkClientId` and change it to something
invalid.
12. Reload the extension.
13. The extension should still load successfully.
14. Go back to the service worker. You should still be on the
Application tab, and the preview should have been updated so that
`selectedNetworkClientId` should no longer be invalid.
15. Repeat the same steps, except run `yarn webpack --watch` instead of
`yarn start` (to test MV2).

## **Screenshots/Recordings**

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

(N/A)

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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.

---------

Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
NicolasMassart added a commit to MetaMask/metamask-mobile that referenced this pull request Jun 5, 2025
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

Currently, when NetworkController is instantiated with pre-existing
state that contains an invalid `selectedNetworkClientId` — that is, no
RPC endpoint exists which has the same network client ID — then it
throws an error. This was intentionally done to bring attention to
possible bugs in NetworkController, but this has the unfortunate side
effect of bricking users' wallets.

To fix this, we now correct an invalid `selectedNetworkClientId` to
point to the default RPC endpoint of the first network sorted by chain
ID (which in the vast majority of cases will be Mainnet). We still do
want to know about this, though, so we log the error in Sentry.

## **Related issues**

See MetaMask/core#5851 for the equivalent
changes to network-controller that were copied here.

## **Manual testing steps**

1. Check out this branch.
2. Run `yarn setup:expo`.
3. We now have to force the initial state to be invalid. Open
`Engine.ts`, scroll down to where NetworkController is initialized, and
apply these changes:
    ``` diff
          const networkControllerOpts = {
infuraProjectId: process.env.MM_INFURA_PROJECT_ID || NON_EMPTY,
    -       state: initialState.NetworkController,
    +       state: {
    +         ...initialState.NetworkController,
    +         selectedNetworkClientId: "nonexistent",
    +       },
            messenger: this.controllerMessenger.getRestricted({
              name: 'NetworkController',
              allowedEvents: [],
              allowedActions: [],
            }) as unknown as NetworkControllerMessenger,
            getRpcServiceOptions: () => ({
              fetch,
              btoa,
            }),
            additionalDefaultNetworks: [ChainId['megaeth-testnet']],
            captureException,
          };
const networkController = new NetworkController(networkControllerOpts);
+ Logger.log('selectedNetworkClientId',
networkController.state.selectedNetworkClientId);
    ```
4. Run `yarn watch:clean`.
5. Load the app, onboarding if necessary.
6. You should be able to get to the home screen without issues. If you
check the terminal you should see a line that says
`selectedNetworkClientId mainnet`. This proves that although the initial
`selectedNetworkClientId` was invalid, it was auto-corrected to
"mainnet".

## **Screenshots/Recordings**

(N/A)

### **Before**

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

### **After**

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

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **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.

Co-authored-by: Nico MASSART <NicolasMassart@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

team-wallet-framework Deprecated: Please use `team-core-platform` instead.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gracefully handle invalid selectedNetworkClientId upon NetworkController initialization

2 participants