Skip to content
This repository has been archived by the owner on Jun 24, 2022. It is now read-only.

Add fast price fetching #2477

Merged
merged 7 commits into from
Feb 28, 2022
Merged

Add fast price fetching #2477

merged 7 commits into from
Feb 28, 2022

Conversation

nenadV91
Copy link
Contributor

@nenadV91 nenadV91 commented Feb 19, 2022

Summary

Fixes #2437

  • This will create a quote request to the fast API endpoint parallel to the current best quote request, and its going to be resolved faster and display the quote results in the UI also faster. Once the best quote request is also resolved it will update the quote data with those results.

  • It will also add separate quote loader that will be displayed when new quote request is made and it will hide when the best quote request is finished (This is just a placeholder, Michel could take a look at this)

Screenshot from 2022-02-19 20-19-19

@github-actions
Copy link
Contributor

CLA Assistant Lite All Contributors have signed the CLA.

@github-actions
Copy link
Contributor

  • 🔭 GP Swap: CoW Protocol v2 Swap UI

@nenadV91 nenadV91 marked this pull request as ready for review February 19, 2022 19:25
@nenadV91 nenadV91 requested review from a team February 19, 2022 19:25
@W3stside
Copy link
Contributor

as we discussed in the call, please revert the new loader SVG and use the nose picker default. if you'd like, open a new PR with the new loader

@elena-zh
Copy link

@nenadV91 , changes LGTM!
Agree not to remove "cow picking nose" icon when the best price is calculated.

Copy link
Contributor

@alfetopito alfetopito left a comment

Choose a reason for hiding this comment

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

Seems to work fine, not as fast as expected though.

Also, please keep the nose picking cow 🥺

@nenadV91
Copy link
Contributor Author

@alfetopito Updated with the cow gif

Copy link
Contributor

@anxolin anxolin left a comment

Choose a reason for hiding this comment

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

In principle works good, but im a bit concern with racing conditions.

Also, @biocom do you think we could experiment and add a different loader for the first loading?
I'd love that we show the logos of 1inch, paraswap, uni, sushi, etc making the impression we are FASTLY checking on those

@@ -63,7 +65,7 @@ export const Wrapper = styled.div<ShowLoaderProp>`
> div > img {
height: 100%;
width: 100%;
padding: 2px 2px 0;
padding: ${({ noPadding }) => (noPadding ? `0px` : `2px 2px 0`)};
Copy link
Contributor

Choose a reason for hiding this comment

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

curious why we need this? u end up leaving the nose picking GIF right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, reverted this also

// Get the best quote
getBestQuoteResolveOnlyLastCall(bestQuoteParams)
.then((res) => handleResponse(res, true))
.catch(handleError)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can there be a race condition?

getFastQuoteResolveOnlyLastCall is sent in parallel to getBestQuoteResolveOnlyLastCall. What happens if getBestQuoteResolveOnlyLastCall finish before the fast one? Wouldn't we update using the wrong price in this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It would, the solution for this is in latest commit and I tested it in a way by using setTimeout on fast price update action. And the update will check inside of update action code, if there is already a quote price amount, which means that the best quote request was already done and if the current action params are bestQuote update or not.

@@ -202,7 +190,9 @@ export function useRefetchQuoteCallback() {

// Update quote
updateQuote(quoteData)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we ALWAY update the price? no matter if its worse or better?

Copy link
Contributor Author

@nenadV91 nenadV91 Feb 25, 2022

Choose a reason for hiding this comment

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

Addressed in the comment up ☝️

Copy link

@elena-zh elena-zh left a comment

Choose a reason for hiding this comment

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

LGTM now!

@fairlighteth
Copy link
Contributor

@nenadV91 My first impression in terms of faster price loading, is positive. To me it feels I quickly get feedback in terms of seeing a quoted price. Here some comments I would consider:

  • When a price is being fetched and keeps on fetching, it would be good to have the shimmer effect also on the Receive (incl. fee) section. A strong indicator that the receive amount might be subject to an update and is not neccesarily final.
Screen.Recording.2022-02-28.at.10.04.45.mov
  • Perhaps out of scope, but once a price has been fetched, the section below the swap container is created and shown (Price, fees..). This container is removed/added quickly whenever you change an input amount. We could consider keeping this section consistent, beyond a first price being fetched. And use the 'shimmer' effects instead on it:
Screen.Recording.2022-02-28.at.10.10.12.mov

This prevents the feeling of 'flashing' content. A similar approach can be seen on 1inch.


@anxolin

Also, @biocom do you think we could experiment and add a different loader for the first loading?
I'd love that we show the logos of 1inch, paraswap, uni, sushi, etc making the impression we are FASTLY checking on those

Yes we definitely could. I would suggest to keep it out of this PR and try to address this separately. At first glance it seems more involved, in terms of what it takes to add a different loader visually to the UI.

@anxolin
Copy link
Contributor

anxolin commented Feb 28, 2022

Im also PRO shimmer effect and keeping the container. Also agree we should do it in another PR

Copy link
Contributor

@anxolin anxolin left a comment

Choose a reason for hiding this comment

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

Soft Approve. Looks ok, but i have some small nitpick comments.

Also, another comment that probably don't need to be addressed in this PR (and maybe we can get by for now not addressing it, if this solution is something we like and the other is hard to implement). However, I believe this solution is not super general. My first idea was to evolve the logic we have of making this price competition, see:

_extractPriceAndErrorPromiseValues

My thinking was, that we only need to update on every new price, and the update logic would only improve the price (never makes the price worse).
This would be more general, so we could launch the call to ANY number of services and update as the prices are coming back, so we don't differentiate between FAST and GOOD api

// Flag to not update the quote when the there is already a quote price and the
// current quote in action is not the best quote, meaning the best quote for
// some reason was already loaded before fast quote and we want to keep best quote data
const shouldNotUpdate = quote && quote[sellToken]?.price?.amount && !isBestQuote
Copy link
Contributor

Choose a reason for hiding this comment

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

Bad name, NOT in a var name makes it hard to read. Try to read:!shouldNotUpdate

Copy link
Contributor

Choose a reason for hiding this comment

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

can u also give a better name to quote[sellToken]?.price?.amount, like:
const hadPrice = !!quote[sellToken]?.price?.amount

also for readability

// Flag to not update the quote when the there is already a quote price and the
// current quote in action is not the best quote, meaning the best quote for
// some reason was already loaded before fast quote and we want to keep best quote data
const shouldNotUpdate = quote && quote[sellToken]?.price?.amount && !isBestQuote
Copy link
Contributor

Choose a reason for hiding this comment

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

Also, nitpick. Move the !isBestQuote to the first condition, so its evaluated first in short-circuit

@nenadV91 nenadV91 merged commit 588ccf2 into develop Feb 28, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Feb 28, 2022
@alfetopito alfetopito deleted the 2437/fast-quote-price branch March 2, 2022 19:01
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.

Faster price: Early first price / Progressive pricing
6 participants