MetaMask / metamask-extension

:globe_with_meridians: :electric_plug: The MetaMask browser extension enables browsing Ethereum blockchain enabled websites
https://metamask.io
Other
11.87k stars 4.85k forks source link

Metamask caches data across account & network resets instead of reading current data from chain, even for private testnets. #3439

Closed wbt closed 6 years ago

wbt commented 6 years ago

Metamask caches blockchain data and displays old data even after an account reset.

If the network is reset, Metamask will continue to display cached data from the previous state of the blockchain, and display all transactions as permanently pending, until the new blockchain is longer than the old one was. Transactions sent at/after that moment will be marked successful (if appropriate) and Metamask will start returning information from the current blockchain instead of the previous one. Even then, the previously sent transactions remain in a pending state, although the transactions succeeded and their effects are visible on the information shown after the new instance of the blockchain became longer than what came before.

The workaround is to use Metamask’s network selector to switch networks away from and then back to the network being reset. “Reset account” is not sufficient to clear the cache and trigger MetaMask to start reading from the blockchain network as it currently stands (instead of reading from cache).

The expected behavior is for Metamask to always return information which reflects information currently stored on the blockchain, instead of returning cached versions of a previous instance of the blockchain. A second-choice fallback would clear Metamask’s cache of a network, in the same way it does when changing networks, when the user manually chooses Reset Account.

This is an issue on networks that get reset, primarily private test networks.

Here were my steps to reproduce:

  1. Close Ganache, verify it is not running in Windows 10 x64 Task manager.
  2. Uninstall Metamask.
  3. Close browser, verify it is not running in Task manager.
  4. Stop localhost server.
  5. Start Ganche 1.1.0-beta.0.
  6. Start Chrome; verify at chrome://settings/help it’s up-to-date v64.0.3282.186
  7. Install Metamask from link at https://metamask.io/
  8. Create new password; import private key for Ganache account 0.
  9. Connect to the Ganache network from Metamask.
  10. Migrate appropriate portions of dapp to Ganache blockchain.
  11. Start server for non-blockchain dapp files, at localhost:3000.
  12. Browse to dapp. Metamask loads correct data from Ganache blockchain.
  13. In dapp (interface), take action which triggers a transaction.
  14. A Metamask window pops up for confirmation. Dapp logs show correct parameters being sent and everything in the Metamask window looks good. Click “Submit” to confirm transaction.
  15. The transaction is submitted, mined, logged, and the dapp display properly updates to reflect the updated information.
  16. Submit another of the same type of transaction. That works too.
  17. Restart Ganache, re-migrate dapp content, reset account in Metamask, refresh dapp interface in browser.
  18. Browser receives log events associated with blocks that are higher-numbered than latest, and displays content reflecting the second change from the previous test, instead of the data migrated in after restarting Ganache.
  19. In the dapp, trigger a different transaction updating different information. Confirm in Metamask.
  20. Receive a transaction receipt reflecting that the transaction was successfully mined, containing logs which match the events that the transaction should have logged. However, information loaded by Metamask does not display the update in the dapp. Metamask displays the transaction as pending.
  21. Do that same type of transaction another time. Again, the updated information will not be reflected in the dapp and Metamask will show the transaction as pending.
  22. Do that same type of transaction a third time, before the updated information will be loaded by MetaMask and reflected in the dapp. Metamask will show this transaction as successful.
  23. Restart Ganache, re-migrate dapp content, reset account in Metamask, refresh dapp interface in browser.
  24. As before, Metamask shows the cached data as it was before the Ganache reset, instead of showing the dapp content as migrated in.
  25. Use the dapp interface to activate a different transaction, modifying information not modified before in this walkthrough. Confirm this transaction in the Metamask pop-up window. As before, get a receipt showing the transaction was mined with logs as expected for that transaction, also confirmed in the Ganache interface. However, Metamask will not display the update information, and will show the transaction as pending. Refreshing to read other information from the dapp will not reflect updates, and will reflect the information as it was before the last Ganache restart/account reset/etc.
  26. Do an additional 3 transactions before Metamask will recognize one as complete, and start showing information from the current instance of the blockchain instead of the previous instance.
  27. Restart Ganache, re-migrate dapp content, reset account in Metamask, refresh dapp interface in browser.
  28. Again, Metamask loads previous information showing what used to be on the blockchain before the latest reset, instead of reading it fresh.
  29. Submit another transaction, confirmed in Metamask, with receipt showing expected logs etc., and Metamask shows it as pending, as before.
  30. Using Metamask’s network selector, choose the main net.
  31. Metamask will freeze up for a while, not allowing the user to switch back. After clicking out of the Metamask popup, clicking again on the Metamask icon will cause it to fill with a darker background as if the popup were active, but no popup appears. Waiting several minutes does not fix it.
  32. Close and restart Chrome. Log into Metamask, which is on the main network.
  33. Change Metamask back to the test network.
  34. Browse to the dapp, and updated information is displayed.
  35. Do another transaction to update the information again. Updated information is correctly displayed.
  36. Restart Ganache, re-migrate dapp content, reset account in Metamask, refresh dapp interface in browser.
  37. As before, outdated information will be shown instead of what was migrated in or set via the first transaction.
  38. Using MetaMask’s network selector, switch to localhost:8545 instead of the custom RPC network (running on port 7545). While Metamask still reports “Connecting to Unknown Private Network,” switch back. Now, the updated information from the current run will be displayed.

Note that in this dapp, the information read from the blockchain did not require any account private keys, so any reset specific to one account might not be broad enough to cover the information being read.

I suspect step 31 is a different bug, but haven't gotten that one isolated or well-documented enough to report yet.

2-am-zzz commented 6 years ago

Thank you for this hugely detailed response!

danfinlay commented 6 years ago

Summary

The "Reset account" function needs to perform a full network selection (restart the provider).

The reasoning, digesting the original post

The problem is that our cache isn't perfect when private networks change. We can either:

  1. Remove the cache
  2. Clear the cache more aggressively:
    • "Reset account" needs to perform a full network selection (restart provider)
    • We should detect when the provider is changed or reset, and activate Reset Account in those cases. #2623.

I think the cache is actually very valuable to our provider API's health, so I don't think that's a reasonable option. Since the second option has two components, and one is already captured as #2623, I think this issue's requirements should be considered:

"Reset account" needs to perform a full network selection (restart provider).

mrwillis commented 5 years ago

This issue still seems to persist. We have a bunch of our users report that their balances are incorrect. Resetting their account usually does it for them. Is there any other solution?

bdresser commented 5 years ago

@mrwillis are you able to reproduce consistently? We see this issue occasionally but have trouble identifying reliable steps to help us debug.

if you are able to, it'd be a huge help - feel free to open a new issue.

mrwillis commented 5 years ago

Yes we have the same issue. Cannot reliably reproduce :(

On Mon., Mar. 25, 2019, 3:07 p.m. bobby dresser, notifications@github.com wrote:

@mrwillis https://github.com/mrwillis are you able to reproduce consistently? We see this issue occasionally but have trouble identifying reliable steps to help us debug.

if you are able to, it'd be a huge help - feel free to open a new issue.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/MetaMask/metamask-extension/issues/3439#issuecomment-476336880, or mute the thread https://github.com/notifications/unsubscribe-auth/ACh6CwiIbu7r2ItwDu-Jc8qR5HZZDGQNks5vaR6LgaJpZM4Sdlvo .