// DragonX Wallet - ImGui Edition // Copyright 2024-2026 The Hush Developers // Released under the GPLv3 // // LiteServerProbe — background latency/IP probe for lite (lightwalletd) servers. // // The lite backend only exposes a yes/no checkServerOnline, so the Network tab measures latency // itself: for each server URL, a libcurl CONNECT_ONLY request does the TCP+TLS handshake (which // works for gRPC/HTTP-2 lightwalletd endpoints without needing an HTTP response) and records the // handshake time as latency plus the resolved IP. Runs on a background thread; results are read // thread-safely from the UI thread and re-run on demand (Refresh). #pragma once #include #include #include #include #include #include namespace dragonx { namespace util { struct LiteServerProbeResult { bool probed = false; // a probe has completed for this URL bool online = false; // the TCP+TLS handshake succeeded int latencyMs = 0; // handshake latency (ms); valid when online std::string ip; // resolved primary IP (CURLINFO_PRIMARY_IP) }; // Pure helper: the host[:port] authority of a URL (scheme + path stripped), for display. // "https://lite.dragonx.is:443/x" -> "lite.dragonx.is:443"; "" on a malformed input. std::string liteServerHost(const std::string& url); class LiteServerProbe { public: LiteServerProbe() = default; ~LiteServerProbe(); LiteServerProbe(const LiteServerProbe&) = delete; LiteServerProbe& operator=(const LiteServerProbe&) = delete; // Probe each URL on a background thread (replacing any in-flight probe). Results stream in as // each server completes; poll results() each frame. void start(std::vector urls); // Snapshot of results so far, keyed by URL. std::map results() const; bool busy() const { return busy_.load(); } private: void run(std::vector urls); mutable std::mutex mutex_; std::map results_; std::atomic busy_{false}; std::atomic cancel_{false}; std::thread worker_; }; } // namespace util } // namespace dragonx