// DragonX Wallet - ImGui Edition // Copyright 2024-2026 The Hush Developers // Released under the GPLv3 // // PoolRegistry — the small table of official DragonX mining pools plus the pure // (no-I/O) helpers used to compare their hashrate and pick one for auto-balance. // // A pool is more than a URL: the two official pools speak DIFFERENT stats APIs // (pool.dragonx.is = a custom /api/stats; pool.dragonx.cc = Miningcore /api/pools) // and mine with DIFFERENT algo strings (rx/hush vs rx/dragonx), so each entry // carries how to read its hashrate and which algo xmrig must be told to use. // // Everything here is pure and unit-tested (see tests/test_phase4.cpp); the live // HTTP fetch lives in pool_stats_service.{h,cpp}. #pragma once #include #include #include namespace dragonx { namespace util { // How to read a pool's total hashrate from its public stats JSON. enum class PoolStatsSchema { DragonXIs, // GET /api/stats -> pools..hashrate (custom) Miningcore, // GET /api/pools -> pools[id==poolId].poolStats.poolHashrate (Miningcore) }; struct KnownPool { std::string id; // stable internal id, e.g. "dragonx-cc-pplns" std::string label; // human label for the UI (host, sans port) std::string stratum; // host:port the miner connects to std::string algo; // xmrig algo string for THIS pool std::string statsUrl; // absolute https URL of the stats endpoint PoolStatsSchema schema = PoolStatsSchema::DragonXIs; std::string miningcorePoolId; // Miningcore pool id (empty for DragonXIs) double feePercent = 0.0; // pool fee, for display only bool official = true; }; // A pool's live total hashrate sample (H/s). ok=false when the fetch/parse failed. struct PoolHashrate { std::string id; double hashrateHs = 0.0; bool ok = false; }; // The built-in official pools (PPLNS only — never a SOLO pool, whose hashrate is // meaningless to balance against). Stable order. const std::vector& knownPools(); // The known pool whose stratum matches `url` (host, and port when both specify one), // or nullptr. `url` may be a bare host, host:port, or carry a scheme/userinfo/path. const KnownPool* findKnownPoolByUrl(const std::string& url); // The algo xmrig must use for `url`: the matching known pool's algo, else `fallback`. std::string resolvePoolAlgo(const std::string& url, const std::string& fallback); // Parse a pool's total hashrate (H/s) out of its stats JSON per `schema`. // `miningcorePoolId` selects the pool entry for the Miningcore schema (ignored // otherwise). Sets ok=false and returns 0 on any parse failure / missing field. double parsePoolHashrate(PoolStatsSchema schema, const std::string& json, const std::string& miningcorePoolId, bool& ok); // Weighted-random pick among the usable (ok==true) pools: probability is inversely // proportional to hashrate (smaller pools favored), so miners spread out instead of // all stampeding to the single lowest pool. The current pool (`currentId`, may be // empty) gets a stickiness multiplier so re-balancing rarely churns the miner. // Returns the chosen pool id; returns `currentId` (or the sole usable id) when fewer // than two pools are usable. std::string chooseWeightedPool(const std::vector& pools, const std::string& currentId, std::mt19937& rng); // Stickiness applied to the incumbent pool's weight in chooseWeightedPool. inline constexpr double kIncumbentStayBias = 2.0; } // namespace util } // namespace dragonx