Skip to content
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

fix contract exchange rate race condition #10414

Merged
merged 1 commit into from
Feb 12, 2021
Merged

Conversation

brad-decker
Copy link
Contributor

Fixes: #10189

Token fiat amounts would become out of sync with one another because contract exchange rates are fetched when tokens are added, not when the network switches. As a result, token exchange rates would get updated on network switch as a result of the token list changing -- but the token rates controller's event was happening prior to the currency rate controller's native currency key being updated.

To fix this I simplified the code a bit, breaking apart the dependency of token-rates-controller to currency-rate-controller. The only thing that token rates needed from currency rates was the native currency. Because currency rates controller also has a dependency on the network's native currency I decided to tie token rates controller to the network instead.

I also removed the 'preferences' setter in the controller because it confused me. in no place are we setting preferences on the controller except the constructor.

@brad-decker brad-decker changed the title use native currency in asset row fix contract exchange rate race condition Feb 9, 2021
@brad-decker brad-decker force-pushed the custom-network-bugs-two branch from 96a48b2 to afeb45e Compare February 10, 2021 23:15
@brad-decker brad-decker changed the base branch from custom-network-bugs to develop February 10, 2021 23:15
@brad-decker brad-decker marked this pull request as ready for review February 10, 2021 23:27
@brad-decker brad-decker requested a review from a team as a code owner February 10, 2021 23:28
@metamaskbot
Copy link
Collaborator

Builds ready [afeb45e]
Page Load Metrics (606 ± 47 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint47836094
domContentLoaded3938276059747
load3948286069747
domInteractive3938276059747

Copy link
Member

@Gudahtt Gudahtt left a comment

Choose a reason for hiding this comment

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

These changes all seem like improvements!

I'm still a little fuzzy on the order-of-operations when a network switch happens. It seems like now the exchange rate update is being triggered twice - once as a result of the network change, and a second time as a result of the tokens changing.

app/scripts/controllers/token-rates.js Show resolved Hide resolved
@brad-decker
Copy link
Contributor Author

It seems like now the exchange rate update is being triggered twice - once as a result of the network change, and a second time as a result of the tokens changing.

this is true, but we need both in the case where tokens change without a network change.

@Gudahtt
Copy link
Member

Gudahtt commented Feb 12, 2021

🤔 Could we only update on a token change than, and assume it will always change when the network switches?

It does seem to change every time at the moment. But. That doesn't seem great to have that assumption baked in here when it might not always apply...

@brad-decker
Copy link
Contributor Author

You'd still have a race condition then if the token preference change occurs before the network switch, which doesn't seem likely.

@brad-decker brad-decker force-pushed the custom-network-bugs-two branch from afeb45e to 96ad3e2 Compare February 12, 2021 16:34
@brad-decker
Copy link
Contributor Author

brad-decker commented Feb 12, 2021

removing the additional sync led to a race condition, which is weird but I think I found a way around it. The race condition occurs because we're copying the nativeCurrency into this controller's local context.

By making the updateExchangeRates function always ask for the most recent nativeCurrency from the network controller, we guarantee that even if there is some weird anomaly with nativeCurrency changing after tokens are set that we can at least recover from it on the next tick of the timer in token-rates.

in practice, this failed state doesn't seem to occur. 🎉

Here's my theory:

  1. User changes network.
    2a. Preferences controller is listening for providerStore state changes, NOT NetworkDidChange. Updates Token state.
    2b. Network Did Change Fires
    3a. Token Rates updates its tokens and gets new exchange rates.
    3b. Token Rates Controller sets new nativeCurrency & requested new exchange rates

By removing 3b, it broke this paradigm. However ticker is part of the provider store, so by always getting the value fresh from this store before fetching exchange rates you're guaranteed to be using the value that was set in #2a before tokens are updated.

@metamaskbot
Copy link
Collaborator

Builds ready [96ad3e2]
Page Load Metrics (592 ± 37 ms)
PlatformPageMetricMin (ms)Max (ms)Average (ms)StandardDeviation (ms)MarginOfError (ms)
ChromeHomefirstPaint489360115
domContentLoaded3586835917838
load3596845927837
domInteractive3586835907838

Copy link
Member

@Gudahtt Gudahtt left a comment

Choose a reason for hiding this comment

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

LGTM!

This is a good case-study for our future controller messaging improvements.

@brad-decker brad-decker merged commit 4c5edea into develop Feb 12, 2021
@brad-decker brad-decker deleted the custom-network-bugs-two branch February 12, 2021 17:41
@github-actions github-actions bot locked and limited conversation to collaborators Feb 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Token fiat currency display incorrect after switching from a custom network to mainnet
3 participants