Skip to content

src/services/rate_service.rs is a dead, misleading duplicate stub of the real RateService in rate.rs #20

Description

@abayomicornelius

src/services/rate_service.rs is a dead, misleading duplicate of the real src/services/rate.rs. It contains only:

// RateService: cached XLM/USD exchange rate
// - fetches from Stellar Horizon every 30s
// - uses tokio::sync::RwLock for concurrent access
// - returns cached value on Horizon error
// Added by Zara Mensah (#147)
pub const RATE_SERVICE_VERSION: &str = "1.0";

Meanwhile src/services/rate.rs::RateService is the actual implementation used in production (an Arc<Mutex<HashMap<String, CacheEntry>>>-backed cache with a configurable TTL, wired up wherever RateService::new(stellar, cache_ttl_secs) is constructed). src/services/mod.rs presumably declares both modules, meaning the crate compiles two structs that could plausibly both be named RateService in different modules, or rate_service.rs is simply never pub mod-declared and is fully dead weight.

Why it matters

  • A contributor searching for "RateService" will find two files and have to read both to figure out which one is real — the comment block in rate_service.rs describes a different design (30s fixed poll interval, tokio::sync::RwLock, "returns cached value on Horizon error" fallback semantics) than what rate.rs actually implements (on-demand fetch-or-cache with a TTL, no stale-on-error fallback at all — a Horizon error in fetch_rate propagates as an AppResult error, it does not fall back to a stale cached value).
  • This is exactly the same "stub implies finished work" defect shape as issues /health/deep documented but not implemented — health.rs is a dead stub #1, Contacts API routes exist as unreachable stub, migration 003 has no working endpoints #2, and Response-caching middleware (cache.rs) is an empty stub with no ETag logic #3 (health.rs, contacts.rs, cache.rs) — a systemic pattern in this codebase worth fixing everywhere at once, not just here.
  • If rate_service.rs is actually referenced anywhere via pub mod rate_service; in src/services/mod.rs, its RATE_SERVICE_VERSION constant is unused (#[allow(dead_code)] is set crate-wide in main.rs's #![allow(dead_code)], which is itself worth questioning — it's likely papering over exactly this kind of dead code across the "Added by ..." stub files).

Reproduction / detection

  1. grep -rn "rate_service" src/services/mod.rs src/ — confirm whether rate_service is declared as a module and, if so, whether anything besides its own file references RATE_SERVICE_VERSION.
  2. Compare the documented behavior in rate_service.rs's comment (stale-on-error fallback, RwLock, fixed 30s poll) against rate.rs's actual fetch_rate implementation — confirm they diverge, meaning at some point a "real" rewrite happened in rate.rs and the old stub was never deleted.

Proposed fix

  • Delete src/services/rate_service.rs and its module declaration entirely, since rate.rs::RateService is the real, tested implementation actually used by src/routes/rates.rs.
  • Alternatively, if the "return cached value on Horizon error" behavior described in the dead stub is actually a desired resilience feature that never got implemented in the real rate.rs, treat this as a legitimate enhancement request for rate.rs (stale-while-error fallback) rather than reviving the stub file — cross-reference issue No retry/backoff logic for Horizon API calls in StellarService #15 (no retry/backoff for Horizon calls), since a stale-on-error cache fallback and retry-with-backoff solve overlapping reliability problems and should be designed together.
  • Audit the rest of src/ for other _VERSION / "Added by ..." comment-only stub files that might have the same dead-duplicate problem (src/routes/health.rs, src/routes/contacts.rs, src/middleware/cache.rs, src/models/contact.rs are already known instances per issues /health/deep documented but not implemented — health.rs is a dead stub #1Response-caching middleware (cache.rs) is an empty stub with no ETag logic #3).

Edge cases

  • If rate_service.rs genuinely isn't declared as a module anywhere (dead file, not even compiled), this is a pure documentation-hygiene fix with zero runtime risk — verify this first before assuming any behavior change is needed.

Testing strategy

  • No behavioral test needed if the file is simply deleted; add a cargo clippy/CI check (once issue No CI workflow configured (missing .github/workflows) #6 lands) that fails on #[allow(dead_code)] being used to silence what should be legitimately-referenced code, forcing future stub files to be caught at PR review time instead of accumulating.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26backendBackend service logicbugSomething isn't workingvery hardVery difficult / senior-level bounty issue

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions