-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Pending Transaction Performance Problems #8377
Labels
area-transactions
degraded performance
Issues relating to slowness of app, cpu usage, and/or blank screens.
type-bug
Comments
whymarrh
added
type-bug
area-transactions
degraded performance
Issues relating to slowness of app, cpu usage, and/or blank screens.
labels
Apr 22, 2020
This is wonderful work!
Just to confirm: your use of "primarily" here is to indicate that the most relevant steps of the loop are those you describe, not that you have reason to believe that there's some other, unknown cause? |
Yes, I cut a few frames out of the stack trace in describing it |
whymarrh
added a commit
to whymarrh/metamask-extension
that referenced
this issue
Apr 28, 2020
whymarrh
added a commit
that referenced
this issue
Apr 29, 2020
Gudahtt
pushed a commit
that referenced
this issue
Apr 30, 2020
Closed
These fixes are slated for 7.7.9: #8444 |
whymarrh
added a commit
to whymarrh/metamask-extension
that referenced
this issue
Jul 16, 2020
Refs MetaMask#8572 Refs MetaMask#8991 This change limits the number of transactions (`txMeta`s) that are passed outside of the `TransactionController`, resulting in shorter serialization and deserialization times when state is moved between the background and UI contexts. `TransactionController#_updateMemstore` --------------------------------------- The `currentNetworkTxList` state of the `TransactionController` is used externally (i.e. outside of the controller) as the canonical source for the full transaction history. Prior to this change, the method would iterate the full transaction history and possibly return all of it. This change limits it to `MAX_MEMSTORE_TX_LIST_SIZE` to make sure that: 1. Calls to `_updateMemstore` are fast(er) 2. Passing `currentNetworkTxList` around is fast(er) (Shown in MetaMask#8377, `_updateMemstore`, is called _frequently_ when a transaction is pending.) The list is iterated backwards because it is possible that new transactions are at the end of the list. [1] Results ------- In profiles before this change, with ~3k transactions locally, `PortDuplexStream._onMessage` took up to ~4.5s to complete when the set of transactions is included. [2] In profiles after this change, `PortDuplexStream._onMessage` took ~90ms to complete. [3] Before vs. after profile screenshots: ![Profile 1][2] ![Profile 2][3] [1]:https://github.com/MetaMask/metamask-extension/blob/5a3ae85b728096cb45c8cc6822249eed5555ee25/app/scripts/controllers/transactions/tx-state-manager.js#L172-L174 [2]:https://user-images.githubusercontent.com/1623628/87613203-36f51d80-c6e7-11ea-89bc-11a1cc2f3b1e.png [3]:https://user-images.githubusercontent.com/1623628/87613215-3bb9d180-c6e7-11ea-8d85-aff3acbd0374.png [8337]:MetaMask#8377 [8572]:MetaMask#8572 [8991]:MetaMask#8991
whymarrh
added a commit
that referenced
this issue
Jul 16, 2020
…9010) Refs #8572 Refs #8991 This change limits the number of transactions (`txMeta`s) that are passed outside of the `TransactionController`, resulting in shorter serialization and deserialization times when state is moved between the background and UI contexts. `TransactionController#_updateMemstore` --------------------------------------- The `currentNetworkTxList` state of the `TransactionController` is used externally (i.e. outside of the controller) as the canonical source for the full transaction history. Prior to this change, the method would iterate the full transaction history and possibly return all of it. This change limits it to `MAX_MEMSTORE_TX_LIST_SIZE` to make sure that: 1. Calls to `_updateMemstore` are fast(er) 2. Passing `currentNetworkTxList` around is fast(er) (Shown in #8377, `_updateMemstore`, is called _frequently_ when a transaction is pending.) The list is iterated backwards because it is possible that new transactions are at the end of the list. [1] Results ------- In profiles before this change, with ~3k transactions locally, `PortDuplexStream._onMessage` took up to ~4.5s to complete when the set of transactions is included. [2] In profiles after this change, `PortDuplexStream._onMessage` took ~90ms to complete. [3] Before vs. after profile screenshots: ![Profile 1][2] ![Profile 2][3] [1]:https://github.com/MetaMask/metamask-extension/blob/5a3ae85b728096cb45c8cc6822249eed5555ee25/app/scripts/controllers/transactions/tx-state-manager.js#L172-L174 [2]:https://user-images.githubusercontent.com/1623628/87613203-36f51d80-c6e7-11ea-89bc-11a1cc2f3b1e.png [3]:https://user-images.githubusercontent.com/1623628/87613215-3bb9d180-c6e7-11ea-8d85-aff3acbd0374.png [8337]:#8377 [8572]:#8572 [8991]:#8991
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
area-transactions
degraded performance
Issues relating to slowness of app, cpu usage, and/or blank screens.
type-bug
This issue details a possible performance issue that exists with pending transactions are handled.
Setup:
Screenshot
On
master
@a7bcc17f9
/v7.7.8
Result:
txMeta.history
for the transaction will grow unbounded at two rates:Regularly/slowly as the transaction is retried with exponential backoff
txMeta.history
:v778-slow-history.log
Rapidly if the call to
eth_getTransactionReceipt
fails/throwshttps://api.infura.io/v1/jsonrpc/ropsten/eth_getTransactionReceipt?params=%5B%220x…%22%5D
txMeta.history
:v778-fast-history.log
Screenshots
Once this history has grown significantly large, snapshotting the
txMeta
becomes prohibitvely expensive. (This is v7.7.8, before we added #8363.)The rapid case—the worse one—is primarily the following loop:
updateTx(…)
_saveTxList
(tx-state-manager.js:466
)TransactionController#_updateMemstore
is run viathis.txStateManager.store.subscribe(…)
(index.js:111
)updatePendingTxs
(pending-tx-tracker.js:43
)this.emit('tx:warning', txMeta, err)
(pending-tx-tracker.js:186
)updateTx(…)
is called viathis.pendingTxTracker.on('tx:warning', …)
(index.js:613
)Full stack trace
v778-network-fail-stacktrace-pathological.txt
I believe the behaviour described here is as old as 507397f (#5431) which first shipped in v4.14.0.
On
develop
@d90810263
Result:
txMeta.history
for the transaction will grow unbounded at one rate:txMeta.history
:develop-fast-history.log
This is all worse on
develop
where we essentially hit the pathological case with each pending transaction. As of #8351,_checkPendingTx
will always emit a warning for a pending transaction. Admittedly this is also related to #7483, where the fallback for anull
transaction receipt was originally mismanaged.Notes:
v778-slow-history.log
v778-fast-history.log
v778-network-fail-stacktrace-pathological.txt
develop-fast-history.log
The text was updated successfully, but these errors were encountered: