Skip to content

fix (cherry-pick-v12): setupControllerConnection outstream end event listener (#26141)#26193

Merged
danjm merged 1 commit intoVersion-v12.0.0from
cherry-pick-8f6c83e-v12.0.0
Jul 30, 2024
Merged

fix (cherry-pick-v12): setupControllerConnection outstream end event listener (#26141)#26193
danjm merged 1 commit intoVersion-v12.0.0from
cherry-pick-8f6c83e-v12.0.0

Conversation

@danjm
Copy link
Copy Markdown
Contributor

@danjm danjm commented Jul 29, 2024

Cherry pick 8f6c83e (#26141)

This PR addresses a problem which had the following surface level
symptoms: when the UI is closed, the extension continues to send network
requests to the provider.

Upon some investigation, we discovered that these requests were the
result of polling initiated from the account tracker. And then upon
further investigation, we discovered that the callback in the
`outstream` `'end'` listener in `setupControllerConnection` of
`metamask-controller.js` was not being called when the UI was closed.

This problem was introduced with
#24533. That PR
updates the `object-multiplex` dependency to v2.0.0. The major change in
that update is the update of the `readable-stream` dependency from a v2
version to a v3 version. With that update, we see new `premature-close`
errors in the background. It seems that these errors are still present
in v2, but they are handled differently, resulting in an `'error'` event
instead of an `'end'` event. We still have not established a definitive
understanding of why this is happening, and follow up investigation will
be needed.

However, this PR still puts forward a fix that safely resolves the
issue. The solution added here is to make use of the
`readableStream.finished` function. The callback passed to this function
will be called when the stream is ended. This function has the same
behaviour as the `outstream.on('end'` listener had prior to the
aforementioned PR.

Instead of fully replacing the existing listener, we have added the
`readableStream.finished` call in addition to the existing listener. The
reason for this is explained in a code comment:

> The presence of both of the below handlers may be redundant. After
upgrading metamask/object-multiples to v2.0.0, which included an upgrade
of readable-streams from v2 to v3, we saw that the `outStream.on('end'`
handler was almost never being called. This seems to related to how v3
handles errors vs how v2 handles errors; there are "premature close"
errors in both cases, although in the case of v2 they don't prevent
`outStream.on('end'` from being called. At the time that this comment
was committed, it was known that we need to investigate and resolve the
underlying error, however, for expediency, we are not addressing them at
this time. Instead, we can observe that `readableStream.finished`
preserves the same functionality as we had when we relied on
readable-stream v2. Meanwhile, the `outStream.on('end'` handler was
observed to have been called at least once. As we do not yet fully
understand the conditions under which both of these are being called, we
include both handlers at the risk of redundancy. Logic has been added to
the handler to ensure that calling it more than once does not have any
affect.

To achieve "Logic has been added to the handler to ensure that calling
it more than once does not have any affect.", the PR adds a unique id to
each stream passed to `setupControllerConnection`, and uses a `Set` to
ensure the handler code only runs once per stream.

This PR then adds automated tests. The added unit tests are focused on
validating both pre-existing and new behaviour of
`setupControllerChanged`. The added e2e tests focus on the inititially
mentioned surface level symptoms: it confirms that `eth_call` and
`eth_getBalance` calls, the calls coming from the account-tracker
initiated polling, are not continued after the UI is closed. This e2e
test fails on current develop but passes on this branch.

MetaMask team members can see more details in this thread:
https://consensys.slack.com/archives/CTQAGKY5V/p1721653870583869

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

Fixes: #26002

To observe the bug on develop:
1. Install and onboard
2. Open the service worker dev console and go to the network tab
3. Observe `eth_call` and `eth_getBalance` requests to infura
4. Close the UI, observe that the requests from step 3 continue

On this branch, in step 4, after closing the UI, those requests will not
continue.

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

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

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

- [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/develop/.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
- [ ] 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 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: legobt <6wbvkn0j@anonaddy.me>
Co-authored-by: legobeat <109787230+legobeat@users.noreply.github.com>
Co-authored-by: Danica Shen <zhaodanica@gmail.com>
@danjm danjm requested a review from a team as a code owner July 29, 2024 16:38
@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.

@metamaskbot metamaskbot added the INVALID-PR-TEMPLATE PR's body doesn't match template label Jul 29, 2024
@danjm danjm changed the title fix: setupControllerConnection outstream end event listener (#26141) fix (cherry-pick-v12): setupControllerConnection outstream end event listener (#26141) Jul 29, 2024
@danjm danjm merged commit ec223c5 into Version-v12.0.0 Jul 30, 2024
@danjm danjm deleted the cherry-pick-8f6c83e-v12.0.0 branch July 30, 2024 09:35
@github-actions github-actions bot locked and limited conversation to collaborators Jul 30, 2024
@metamaskbot
Copy link
Copy Markdown
Collaborator

Builds ready [877672a]
Page Load Metrics (55 ± 6 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint6610685115
domContentLoaded9241242
load448755126
domInteractive9241242

@metamaskbot metamaskbot added the release-12.0.0 Issue or pull request that will be included in release 12.0.0 label Jul 30, 2024
@metamaskbot
Copy link
Copy Markdown
Collaborator

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

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

Labels

INVALID-PR-TEMPLATE PR's body doesn't match template release-12.0.0 Issue or pull request that will be included in release 12.0.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants