Skip to content

Conversation

@peachbits
Copy link
Contributor

@peachbits peachbits commented Nov 3, 2025

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Requirements

If you have made any visual changes to the GUI. Make sure you have:

  • Tested on iOS device
  • Tested on Android device
  • Tested on small-screen device (iPod Touch)
  • Tested on large-screen device (tablet)

Note

Deduplicates cached asset pairs on load, fetches rates in parallel, then merges successful results back into the pair caches before updating/persisting the cache.

  • Exchange Rates
    • Cache loading: Deduplicate cryptoPairs/fiatPairs via keyed maps, drop expired entries, and normalize pairs (unset isoDate).
    • Fetching: Replace sequential, retried POSTs with parallel requests (Promise.allSettled) to v3/rates.
    • Cache merge: After successful responses, merge discovered pairs into pair caches and update in-memory cache with cryptoPairCache/fiatPairCache before writing to disk.
    • Rates handling: Preserve unexpired rates; compute and set current/yesterday with timestamps and expirations as before.

Written by Cursor Bugbot for commit d35d3b7. This will update automatically on new commits. Configure here.


cryptoPairs: Array.from(cryptoPairMap.values()),
fiatPairs: Array.from(fiatPairMap.values())
cryptoPairs: Array.from(cryptoPairCache.values()),
fiatPairs: Array.from(fiatPairCache.values())
Copy link

Choose a reason for hiding this comment

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

Bug: Cache clears failed rate pairs, causing missing data

The exchange rate cache now only persists asset pairs that successfully returned rate data, rather than all initially requested pairs. If a rate fetch fails, the asset pair is removed from the cache and won't be tracked or re-requested until its associated wallet is active again, potentially causing missing exchange rates.

Fix in Cursor Fix in Web

Copy link
Contributor

@swansontec swansontec left a comment

Choose a reason for hiding this comment

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

It seems like this would be better, but as Cursor points out, we do run the risk of losing rates that we fail to fetch. It might make sense to pre-populate these two sets with the existing data, which would turn this into an update rather than a stomp.

With the cache, and periodic looping, this isn't really necessary and can actually slow down rate updates
const key = `${pair.fiatCode}_${pair.targetFiat}`
fiatPairsMap.set(key, { ...pair, isoDate: undefined })
}
out.fiatPairs = Array.from(fiatPairsMap.values())
Copy link

Choose a reason for hiding this comment

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

Bug: Historical Exchange Rate Data Integrity Compromised

The deduplication logic in loadExchangeRateCache uses a key that excludes isoDate, causing pairs with the same pluginId/tokenId/targetFiat but different isoDate values to collide and overwrite each other. Since the persisted cache can contain pairs with historical dates (e.g., isoDate: yesterday), only one per key is kept with isoDate cleared to undefined. This loses historical rate pair information that was previously persisted, preventing the app from accurately restoring its previous state after restart when daily rate updates were involved.

Fix in Cursor Fix in Web

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 is a good thing

@peachbits peachbits merged commit 7e06906 into develop Nov 18, 2025
3 checks passed
@peachbits peachbits deleted the matthew/pair-cache branch November 18, 2025 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants