ObsidianDragon - DragonX ImGui Wallet
Full-node GUI wallet for DragonX cryptocurrency. Built with Dear ImGui, SDL3, and OpenGL3/DX11. Features: - Send/receive shielded and transparent transactions - Autoshield with merged transaction display - Built-in CPU mining (xmrig) - Peer management and network monitoring - Wallet encryption with PIN lock - QR code generation for receive addresses - Transaction history with pagination - Console for direct RPC commands - Cross-platform (Linux, Windows)
This commit is contained in:
169
src/daemon/xmrig_manager.h
Normal file
169
src/daemon/xmrig_manager.h
Normal file
@@ -0,0 +1,169 @@
|
||||
// DragonX Wallet - ImGui Edition
|
||||
// Copyright 2024-2026 The Hush Developers
|
||||
// Released under the GPLv3
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
namespace dragonx {
|
||||
namespace daemon {
|
||||
|
||||
/**
|
||||
* @brief Manages the xmrig pool mining process
|
||||
*
|
||||
* Handles starting/stopping xmrig for pool mining, polling stats via its
|
||||
* HTTP API, and capturing stdout for the log panel. Modelled on
|
||||
* EmbeddedDaemon (same fork/pipe/monitor pattern, same #ifdef split).
|
||||
*/
|
||||
class XmrigManager {
|
||||
public:
|
||||
enum class State { Stopped, Starting, Running, Stopping, Error };
|
||||
|
||||
/// Live stats polled from xmrig HTTP API (/2/summary)
|
||||
struct PoolStats {
|
||||
double hashrate_10s = 0;
|
||||
double hashrate_60s = 0;
|
||||
double hashrate_15m = 0;
|
||||
int64_t accepted = 0;
|
||||
int64_t rejected = 0;
|
||||
int64_t uptime_sec = 0;
|
||||
double pool_diff = 0;
|
||||
std::string pool_url;
|
||||
std::string algo;
|
||||
bool connected = false;
|
||||
// Memory usage
|
||||
int64_t memory_free = 0; // bytes
|
||||
int64_t memory_total = 0; // bytes
|
||||
int64_t memory_used = 0; // bytes (resident set size)
|
||||
int threads_active = 0; // actual mining threads
|
||||
};
|
||||
|
||||
/// User-facing config (maps 1:1 to UI fields / Settings)
|
||||
struct Config {
|
||||
std::string pool_url = "pool.dragonx.is";
|
||||
std::string wallet_address;
|
||||
std::string worker_name = "x";
|
||||
std::string algo = "rx/hush";
|
||||
int threads = 0; // 0 = xmrig auto
|
||||
bool tls = false;
|
||||
bool hugepages = true;
|
||||
};
|
||||
|
||||
XmrigManager();
|
||||
~XmrigManager();
|
||||
|
||||
// Non-copyable
|
||||
XmrigManager(const XmrigManager&) = delete;
|
||||
XmrigManager& operator=(const XmrigManager&) = delete;
|
||||
|
||||
/**
|
||||
* @brief Start xmrig with the given config.
|
||||
* Generates a JSON config file, finds the binary, and spawns the process.
|
||||
*/
|
||||
bool start(const Config& cfg);
|
||||
|
||||
/**
|
||||
* @brief Stop xmrig gracefully (SIGTERM → wait → SIGKILL).
|
||||
*/
|
||||
void stop(int wait_ms = 5000);
|
||||
|
||||
bool isRunning() const;
|
||||
State getState() const { return state_.load(std::memory_order_relaxed); }
|
||||
|
||||
const PoolStats& getStats() const { return stats_; }
|
||||
const std::string& getLastError() const { return last_error_; }
|
||||
|
||||
/**
|
||||
* @brief Get last N lines of xmrig stdout (thread-safe snapshot).
|
||||
*/
|
||||
std::vector<std::string> getRecentLines(int maxLines = 30) const;
|
||||
|
||||
/**
|
||||
* @brief Get new output since a given offset (thread-safe).
|
||||
* Returns the new text and updates offset to the current size.
|
||||
*/
|
||||
std::string getOutputSince(size_t& offset) const {
|
||||
std::lock_guard<std::mutex> lk(output_mutex_);
|
||||
if (offset >= process_output_.size()) {
|
||||
offset = process_output_.size();
|
||||
return {};
|
||||
}
|
||||
std::string result = process_output_.substr(offset);
|
||||
offset = process_output_.size();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current output size (thread-safe, no copy)
|
||||
*/
|
||||
size_t getOutputSize() const {
|
||||
std::lock_guard<std::mutex> lk(output_mutex_);
|
||||
return process_output_.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Poll the xmrig HTTP API for live stats.
|
||||
* Lightweight — reads cached stats updated by the monitor thread.
|
||||
* Called from App::update() every ~2 s while running.
|
||||
*/
|
||||
void pollStats();
|
||||
|
||||
/**
|
||||
* @brief Get xmrig process memory usage in MB (from OS, not API).
|
||||
*/
|
||||
double getMemoryUsageMB() const;
|
||||
|
||||
/**
|
||||
* @brief Find xmrig binary in standard locations.
|
||||
*/
|
||||
static std::string findXmrigBinary();
|
||||
|
||||
private:
|
||||
bool generateConfig(const Config& cfg, const std::string& outPath);
|
||||
bool startProcess(const std::string& xmrigPath, const std::string& cfgPath, int threads);
|
||||
void monitorProcess();
|
||||
void drainOutput();
|
||||
void appendOutput(const char* data, size_t len);
|
||||
void fetchStatsHttp(); // Blocking HTTP call — runs on monitor thread only
|
||||
|
||||
std::atomic<State> state_{State::Stopped};
|
||||
std::string last_error_;
|
||||
|
||||
mutable std::mutex output_mutex_;
|
||||
std::string process_output_;
|
||||
|
||||
// xmrig HTTP API credentials (random per session)
|
||||
int api_port_ = 0;
|
||||
std::string api_token_;
|
||||
int threads_ = 0; // Thread count for mining
|
||||
PoolStats stats_;
|
||||
mutable std::mutex stats_mutex_;
|
||||
|
||||
// Process handles
|
||||
#ifdef _WIN32
|
||||
HANDLE process_handle_ = nullptr;
|
||||
HANDLE stdout_read_ = nullptr;
|
||||
#else
|
||||
pid_t process_pid_ = 0;
|
||||
int stdout_fd_ = -1;
|
||||
#endif
|
||||
|
||||
std::thread monitor_thread_;
|
||||
std::atomic<bool> should_stop_{false};
|
||||
};
|
||||
|
||||
} // namespace daemon
|
||||
} // namespace dragonx
|
||||
Reference in New Issue
Block a user