-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
[Bug]: App freezes for 1 minute then crash when swapping unapproved token #11085
Comments
I was able to reproduce on iOS simulator on
Between Mobile 7.26.0 and 7.27.0, TransactionController jumps from v13 to v35 |
@infiniteflower I confirm that this started happening after the TransactionController jumps from v13 to v35 with this commit #10263 If I build the app with previous the following previous commit it doesn't repro |
## **Description** The freeze was ultimately caused by a render loop inside `RootRPCMethodsUI` caused by the `TransactionController:unapprovedTransactionAdded` listener. More specifically: 1. When swaps are detected, the transaction is automatically approved via the `autoSign` function. 2. This registers a listener to send a completed metric once the transaction is confirmed. 3. This is triggered by adding the transaction ID to a queue via the `addTransactionMetaIdForListening` function. 4. This function updates React state, but was also using that same state as a dependency, meaning the callback was updated on every usage. 5. This function was a dependency of `autoSign` which was in turn a dependency of `onUnapprovedTransaction` which was the only dependency for a `useEffect` that re-created the `TransactionController:unapprovedTransactionAdded` listener. 6. The `ControllerMessenger` processes listeners using an iterator rather than a static list meaning each new listener was automatically ran which in turn created another listener and resulted in a very high CPU render loop. The core fix was to update the `addTransactionMetaIdForListening` to update the state using the callback override meaning it did not require the state dependency. However during testing it was discovered that this swaps completed metric was not functioning since the `swapsTransaction` state was being incorrectly populated with the `TransactionController` instance due to a legacy function argument that was not fully removed. This has been addressed, and all swaps transactions updates have been abstracted via a new `swaps-transactions` utility file. ## **Related issues** Fixes: [#11085](#11085) ## **Manual testing steps** Full swaps regression, including: - Swaps with approvals. - Smart swaps. - Metric support. - Multiple sequential swaps (with and without approvals). ## **Screenshots/Recordings** ### **Before** ### **After** ## **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: sethkfman <10342624+sethkfman@users.noreply.github.com>
## **Description** The freeze was ultimately caused by a render loop inside `RootRPCMethodsUI` caused by the `TransactionController:unapprovedTransactionAdded` listener. More specifically: 1. When swaps are detected, the transaction is automatically approved via the `autoSign` function. 2. This registers a listener to send a completed metric once the transaction is confirmed. 3. This is triggered by adding the transaction ID to a queue via the `addTransactionMetaIdForListening` function. 4. This function updates React state, but was also using that same state as a dependency, meaning the callback was updated on every usage. 5. This function was a dependency of `autoSign` which was in turn a dependency of `onUnapprovedTransaction` which was the only dependency for a `useEffect` that re-created the `TransactionController:unapprovedTransactionAdded` listener. 6. The `ControllerMessenger` processes listeners using an iterator rather than a static list meaning each new listener was automatically ran which in turn created another listener and resulted in a very high CPU render loop. The core fix was to update the `addTransactionMetaIdForListening` to update the state using the callback override meaning it did not require the state dependency. However during testing it was discovered that this swaps completed metric was not functioning since the `swapsTransaction` state was being incorrectly populated with the `TransactionController` instance due to a legacy function argument that was not fully removed. This has been addressed, and all swaps transactions updates have been abstracted via a new `swaps-transactions` utility file. ## **Related issues** Fixes: [#11085](#11085) ## **Manual testing steps** Full swaps regression, including: - Swaps with approvals. - Smart swaps. - Metric support. - Multiple sequential swaps (with and without approvals). ## **Screenshots/Recordings** ### **Before** ### **After** ## **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: sethkfman <10342624+sethkfman@users.noreply.github.com>
## **Description** The freeze was ultimately caused by a render loop inside `RootRPCMethodsUI` caused by the `TransactionController:unapprovedTransactionAdded` listener. More specifically: 1. When swaps are detected, the transaction is automatically approved via the `autoSign` function. 2. This registers a listener to send a completed metric once the transaction is confirmed. 3. This is triggered by adding the transaction ID to a queue via the `addTransactionMetaIdForListening` function. 4. This function updates React state, but was also using that same state as a dependency, meaning the callback was updated on every usage. 5. This function was a dependency of `autoSign` which was in turn a dependency of `onUnapprovedTransaction` which was the only dependency for a `useEffect` that re-created the `TransactionController:unapprovedTransactionAdded` listener. 6. The `ControllerMessenger` processes listeners using an iterator rather than a static list meaning each new listener was automatically ran which in turn created another listener and resulted in a very high CPU render loop. The core fix was to update the `addTransactionMetaIdForListening` to update the state using the callback override meaning it did not require the state dependency. However during testing it was discovered that this swaps completed metric was not functioning since the `swapsTransaction` state was being incorrectly populated with the `TransactionController` instance due to a legacy function argument that was not fully removed. This has been addressed, and all swaps transactions updates have been abstracted via a new `swaps-transactions` utility file. ## **Related issues** Fixes: [#11085](#11085) ## **Manual testing steps** Full swaps regression, including: - Swaps with approvals. - Smart swaps. - Metric support. - Multiple sequential swaps (with and without approvals). ## **Screenshots/Recordings** ### **Before** ### **After** ## **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: sethkfman <10342624+sethkfman@users.noreply.github.com>
) ## **Description** The freeze was ultimately caused by a render loop inside `RootRPCMethodsUI` caused by the `TransactionController:unapprovedTransactionAdded` listener. More specifically: 1. When swaps are detected, the transaction is automatically approved via the `autoSign` function. 2. This registers a listener to send a completed metric once the transaction is confirmed. 3. This is triggered by adding the transaction ID to a queue via the `addTransactionMetaIdForListening` function. 4. This function updates React state, but was also using that same state as a dependency, meaning the callback was updated on every usage. 5. This function was a dependency of `autoSign` which was in turn a dependency of `onUnapprovedTransaction` which was the only dependency for a `useEffect` that re-created the `TransactionController:unapprovedTransactionAdded` listener. 6. The `ControllerMessenger` processes listeners using an iterator rather than a static list meaning each new listener was automatically ran which in turn created another listener and resulted in a very high CPU render loop. The core fix was to update the `addTransactionMetaIdForListening` to update the state using the callback override meaning it did not require the state dependency. However during testing it was discovered that this swaps completed metric was not functioning since the `swapsTransaction` state was being incorrectly populated with the `TransactionController` instance due to a legacy function argument that was not fully removed. This has been addressed, and all swaps transactions updates have been abstracted via a new `swaps-transactions` utility file. ## **Related issues** Fixes: [#11085](#11085) ## **Manual testing steps** Full swaps regression, including: - Swaps with approvals. - Smart swaps. - Metric support. - Multiple sequential swaps (with and without approvals). ## **Screenshots/Recordings** ### **Before** ### **After** ## **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: sethkfman <10342624+sethkfman@users.noreply.github.com>
) - fix: freeze during swap with approval (#11165) ## **Description** The freeze was ultimately caused by a render loop inside `RootRPCMethodsUI` caused by the `TransactionController:unapprovedTransactionAdded` listener. More specifically: 1. When swaps are detected, the transaction is automatically approved via the `autoSign` function. 2. This registers a listener to send a completed metric once the transaction is confirmed. 3. This is triggered by adding the transaction ID to a queue via the `addTransactionMetaIdForListening` function. 4. This function updates React state, but was also using that same state as a dependency, meaning the callback was updated on every usage. 5. This function was a dependency of `autoSign` which was in turn a dependency of `onUnapprovedTransaction` which was the only dependency for a `useEffect` that re-created the `TransactionController:unapprovedTransactionAdded` listener. 6. The `ControllerMessenger` processes listeners using an iterator rather than a static list meaning each new listener was automatically ran which in turn created another listener and resulted in a very high CPU render loop. The core fix was to update the `addTransactionMetaIdForListening` to update the state using the callback override meaning it did not require the state dependency. However during testing it was discovered that this swaps completed metric was not functioning since the `swapsTransaction` state was being incorrectly populated with the `TransactionController` instance due to a legacy function argument that was not fully removed. This has been addressed, and all swaps transactions updates have been abstracted via a new `swaps-transactions` utility file. ## **Related issues** Fixes: [#11085](#11085) ## **Manual testing steps** Full swaps regression, including: - Swaps with approvals. - Smart swaps. - Metric support. - Multiple sequential swaps (with and without approvals). ## **Screenshots/Recordings** ### **Before** ### **After** ## **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: sethkfman <10342624+sethkfman@users.noreply.github.com> [059a391](059a391) --------- Co-authored-by: Matthew Walsh <matthew.walsh@consensys.net> Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com> Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Describe the bug
After an app install or app upgrade, or after an account import, if I swap an unapproved token the app will hang and crash after 1 minute.
It started happening with RC 7.27.1 after the TransactionController jumps from v13 to v35 with this commit
#10263
If I build the app with the following previous commit it doesn't repro
#10458
Watch video
Hang2.mov
Expected behavior
The Swap completes successfully
Screenshots/Recordings
No response
Steps to reproduce
Notice the app freezing and then crashing after 1 minute
Error messages or log output
No response
Detection stage
During 7.30.0 release testing
Version
7.27.1 and older
Build type
None
Device
iPhone 12 Pro
Operating system
iOS
Additional context
No response
Severity
No response
The text was updated successfully, but these errors were encountered: