Skip to content

Stop refetching tokens without a price source on every block#56

Merged
TaprootFreak merged 1 commit into
developfrom
fix/retry-storm-unlisted-tokens
May 15, 2026
Merged

Stop refetching tokens without a price source on every block#56
TaprootFreak merged 1 commit into
developfrom
fix/retry-storm-unlisted-tokens

Conversation

@TaprootFreak
Copy link
Copy Markdown

Summary

Mirror of the d-EURO API fix in d-EURO/api#112. The two services share the same updatePrices() shape and the same defect:

  • When fetchPrice() returns no usd value (e.g. CoinGecko returns {} for an unlisted collateral token, so fetchSourcesCoingecko() yields undefined), updatePrices() discards the result without touching the cache entry.
  • Because the entry's timestamp never advances, oldEntry.timestamp + 300_000 < Date.now() stays true and the same token is retried on every block tick (every 10 s via ApiService.updateBlockheight).
  • The in-cluster pricing proxy absorbs most of that with its 60 s cache, but one upstream MISS per minute per token still leaks through — exactly the pattern that pushed our CoinGecko monthly quota over the limit.
  • Bump the entry's timestamp on a failed fetch as well, so a missing price obeys the same 5-minute retry window as a successful one.

Test plan

  • yarn build
  • On a running instance: confirm the upstream call rate to simple/token_price/ethereum?contract_addresses=… for unlisted-token addresses drops from ~50/h to ~12/h
  • Verify GET /prices/list still lists those tokens (without a meaningful price.usd, as before)

Same retry-storm bug we fixed in d-EURO API (PR d-EURO#112):
when fetchPrice() returns no usd value (e.g. an unlisted collateral
token where CoinGecko returns {}), updatePrices() left the cache
entry untouched and the 5-minute staleness check
(timestamp + 300_000 < now) was still true on the next block tick.
Combined with the 10 s block polling that drives updatePrices(),
this made the same handful of unlisted tokens generate a steady
upstream MISS on every cycle, leaking through the pricing-proxy's
60 s cache once per minute per token.

Bump the entry's timestamp on a failed fetch too, so the retry
honours the same 5-minute window as a successful fetch.
@TaprootFreak TaprootFreak marked this pull request as ready for review May 15, 2026 17:58
@TaprootFreak TaprootFreak requested a review from Danswar as a code owner May 15, 2026 17:58
@TaprootFreak TaprootFreak merged commit eeb65af into develop May 15, 2026
1 check passed
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.

1 participant