Skip to content

Compute the 24h price change when a provider does not send it - #1528

Merged
gemcoder21 merged 3 commits into
mainfrom
wt2/price-change-24h-fallback
Oct 9, 2026
Merged

gemcoder21 merged 3 commits into
mainfrom
wt2/price-change-24h-fallback

Conversation

@DRadmir

@DRadmir DRadmir commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Why

CoinGecko and other providers often send no 24h price change for smaller coins. The server saved it as 0, so the app showed "0.00%" even when the price had moved a lot, and price change alerts for those coins never fired.

What changed

  • A missing 24h change is no longer saved as 0.
  • When a price update arrives without it, the server computes it from its own price history 24 hours earlier, as it already did for Pyth and DefiLlama.
  • This now happens when prices are saved, so the separate job that did it every 5 minutes is removed.
  • The app gets the same response as before.

Also in this PR

  • The 24h change rule lives in PriceClient. The price adapter exposes get_chart_prices(price_ids, from, until), and PriceClient::store_prices fills in a missing change before saving. Covered by test_store_prices_fills_a_missing_24h_change_from_the_price_a_day_ago.
  • No function outside storage takes a DatabaseClient. The 17 helpers that did (assets, nft, prices, setup dev seed, rewards units.rs) became one of:
    • a storage method (get_nft_asset, get_referral_use_facts, get_abuse_facts);
    • a pure mapper or rule;
    • a port method the service composes.
  • Rewards behaviour is unchanged. Each reward step runs the same queries in the same order. apply_referral_code now returns the decision, and the service calls set_referral.
  • Every storage update is update_x(filters, updates). Each filter enum implements QueryFilter, so reads and updates share one condition. AssetFilter::ExcludeIds replaces reading and diffing id sets for the image, price and fiat flags, and the fiat port no longer takes function pointers.
  • Five verbs for every storage and port method: get, add, set, update, delete. Port reads are get_*.
  • The rules are written down and enforced. core/skills/architecture.md (Repository Pattern) states them, and just check-boundaries adds two rules: only storage takes a DatabaseClient, and repository methods use the five verbs.

Checks

Check Result
services tests 156 pass
storage tests 17 pass
swapper tests 364 pass
primitives tests 209 pass
Storage database tests (local Postgres) 11 pass
Clippy and just lint 0 warnings
cargo check --workspace --all-features --tests builds
Repo checks all pass

The flag updates and the wallet-transactions query were also checked by hand against Postgres.

@DRadmir DRadmir self-assigned this Oct 9, 2026
@DRadmir
DRadmir requested a review from gemcoder21 October 9, 2026 05:58
The 24h price change is computed in PriceClient from a new get_chart_prices port read, instead of a helper that took the DatabaseClient inside the price adapter.

No function outside storage takes a DatabaseClient: the 17 helpers in the assets, nft, prices, setup and rewards adapters became storage methods (get_nft_asset, get_referral_use_facts, get_abuse_facts), pure mappers and rules, or port methods the service composes. The dev seed is plain data written by the setup adapter, and the dev username goes through the rewards port.

Every storage update is one update_x(filters, updates) method, for assets, devices, prices, price alerts, redemptions and transactions. Each filter enum implements QueryFilter, so reads and updates share one condition; AssetFilter gains ExcludeIds, and the asset and fiat flag updates use it instead of reading and diffing id sets. The fiat port no longer takes function pointers.

Storage repositories and service ports use five verbs: get, add, set, update and delete. core/skills/architecture.md states the rules and check-boundaries enforces them.
…fallback

# Conflicts:
#	core/crates/services/src/devices/devices_client.rs
@gemcoder21
gemcoder21 merged commit 82df074 into main Oct 9, 2026
6 checks passed
@gemcoder21
gemcoder21 deleted the wt2/price-change-24h-fallback branch October 9, 2026 17:20
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.

2 participants