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

1.5.0 Hot fixes #1070

Merged
merged 5 commits into from
Apr 3, 2024
Merged

1.5.0 Hot fixes #1070

merged 5 commits into from
Apr 3, 2024

Conversation

GhenadieVP
Copy link
Contributor

@GhenadieVP GhenadieVP commented Apr 3, 2024

1.5.0 Hot fixes

  • Properly truncate price before initialising the RETDecimal.
  • Apply empty vaults when refreshing the portfolio for a given account.
  • TXID truncation.

FLOOP worth:
Screenshot 2024-04-03 at 09 07 07

Tokens with near zero value are still shown
Screenshot 2024-04-03 at 09 07 43

TXID truncation
Screenshot 2024-04-03

@@ -133,7 +133,7 @@ extension AccountPortfoliosClient: DependencyKey {
cacheClient.removeFolder(.onLedgerEntity(.account(accountAddress.asGeneral)))
}

let account = try await onLedgerEntitiesClient.getAccount(accountAddress)
let account = try await onLedgerEntitiesClient.getAccount(accountAddress).nonEmptyVaults
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was causing users to see tokens with zero values when they did performa pull to refresh in Account details

Copy link
Contributor

Choose a reason for hiding this comment

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

If this is done here, will that not affect all the endpoints on the client? In transaction history I need the full portfolio, including empty vaults.

Copy link
Contributor

Choose a reason for hiding this comment

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

right should be able to do it later, in view layer is Gustafs meaning?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

probably will it will,
will move this at UI level

@@ -4,11 +4,8 @@ extension TokenPricesClient {
@Dependency(\.jsonDecoder) var jsonDecoder
@Dependency(\.jsonEncoder) var jsonEncoder
@Dependency(\.cacheClient) var cacheClient
#if DEBUG
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Opt to always use prod token price service to facilitate testing. Dev endpoint might not have all prices available or latest ones.

formatter.numberStyle = .decimal
formatter.maximumFractionDigits = Int(RETDecimal.maxDivisibility)
formatter.roundingMode = .down
formatter.decimalSeparator = "." // Enfore dot notation for RETDecimal
formatter.decimalSeparator = "." // Enforce dot notation for RETDecimal
formatter.usesGroupingSeparator = false // No grouping separator for RETDecimal
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not having this caused the prices > 1000 to be formatted with a thousand separator which then couldn't be converted to RETDecimal.

Copy link
Contributor

Choose a reason for hiding this comment

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

there is another initialiser than value: String, there is formatted: String as well. which should be able to accept strings with a thousands separator.

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like we are rounding the Double that represents the price, by first converting the price Double to a string (using a fixed decimal separator) and then converting it back to RETDecimal?

  1. I presume that RETDecimal(value: String) is the version that takes a machine readable string, so that it ignores the user preference on decimal separator, because otherwise this wouldn't work, but even so, I don't like this, it doesn't seem nice or necessary to convert the price to a Double, then a String and the RETDecimal, just in order to round it.

  2. If we do want to round it here, can't we convert it (back) to RETDecimal and just round that, without going by way of String?

  3. Why do we want price to be a Double at all? This operation here would be even simpler if it was kept a RETDecimal until it's to be displayed.

  4. Is the behaviour actually correct? What is the purpose of clamping the number of decimals in the price according to the divisibility, isn't the price here given in a fiat currency?

Copy link
Contributor

Choose a reason for hiding this comment

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

there is another initialiser than value: String, there is formatted: String as well. which should be able to accept strings with a thousands separator.

Presumably (hopefully), the latter respects the user's locale, and the former does not, and in this case we don't want to respect the locale, since we hard code the decimal separator.

Copy link
Contributor Author

@GhenadieVP GhenadieVP Apr 3, 2024

Choose a reason for hiding this comment

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

@kugel3 note that this whole shenanigans is not about rounding, it is about truncating to RETDecimal max divisibility, otherwise we cannot initialise the RETDecimal with a double that has more decimals than 18.

The price is double as it comes from the TokenPrice service, here we do immediately convert it to RETDecimal.

Copy link
Contributor

@kugel3 kugel3 Apr 3, 2024

Choose a reason for hiding this comment

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

Alright, then I understand your other comment about an initialiser for RETDecimal that takes a Double with arbitrary number of decimals, that would be highly preferable. Since NumberFormatter is pretty expensive to initialise, we probably don't want to make that initialiser in Swift.

But while we have this workaround, I think we should be more explicit about what is going on, so that nobody accidentally changes to using the other string based initialiser for example. Because RETDecimal(formatted: String) could not actually be used here? It does respect locale, right? @CyonAlexRDX

Perhaps change // Enforce dot notation for RETDecimal to something like // Use a period as decimal separator, for the sake of RETDecimal(formatted: String).

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes RETDecimal.init(formattedStrinf:locale) is respects locale

@GhenadieVP GhenadieVP marked this pull request as ready for review April 3, 2024 06:08
@@ -45,10 +42,12 @@ extension TokenPricesClient {
extension TokenPricesClient.TokenPrices {
fileprivate init(_ tokenPricesResponse: TokensPriceResponse) {
let formatter = NumberFormatter()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Would be nice to have a RETDecimal initializer in Sargon to handle the case of providing a Double with more than 18 decimal places.

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah I can fix one!

@@ -74,3 +74,16 @@ extension NonFungibleLocalId {
}
}
}

extension TXID {
Copy link
Contributor

Choose a reason for hiding this comment

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

Aha! I suspected we had a regression, because I started adding this in Sargon for transaction hashes but then tested main branch and saw we did not truncated. I should have spoken up :) @micbakos-rdx we can you add a PR implementing this in Sargon?

@testable import Radix_Wallet_Dev
import XCTest

final class TokenPriceCientTests: XCTestCase {
Copy link
Contributor

Choose a reason for hiding this comment

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

tests! 🙂

@@ -3,10 +3,6 @@ import EngineToolkit
public typealias TXID = TransactionHash

extension TXID {
public func formatted(_ format: AddressFormat = .default) -> String {
Copy link
Contributor

Choose a reason for hiding this comment

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

@GhenadieVP merge conflict imminent, but I see, it must happen, since you needed to implement this a method with this signature.

Copy link
Contributor

@CyonAlexRDX CyonAlexRDX left a comment

Choose a reason for hiding this comment

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

LGTM !

@GhenadieVP GhenadieVP merged commit bc17e07 into main Apr 3, 2024
7 checks passed
@GhenadieVP GhenadieVP deleted the price_trimm_bugfix branch April 3, 2024 12:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants