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:
195
src/daemon/embedded_daemon.h
Normal file
195
src/daemon/embedded_daemon.h
Normal file
@@ -0,0 +1,195 @@
|
||||
// DragonX Wallet - ImGui Edition
|
||||
// Copyright 2024-2026 The Hush Developers
|
||||
// Released under the GPLv3
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
namespace dragonx {
|
||||
namespace daemon {
|
||||
|
||||
/**
|
||||
* @brief Manages the embedded dragonxd process
|
||||
*
|
||||
* Handles starting, stopping, and monitoring the dragonxd daemon process.
|
||||
* Ports functionality from Qt version's connection.cpp.
|
||||
*/
|
||||
class EmbeddedDaemon {
|
||||
public:
|
||||
enum class State {
|
||||
Stopped,
|
||||
Starting,
|
||||
Running,
|
||||
Stopping,
|
||||
Error
|
||||
};
|
||||
|
||||
using StateCallback = std::function<void(State, const std::string&)>;
|
||||
|
||||
EmbeddedDaemon();
|
||||
~EmbeddedDaemon();
|
||||
|
||||
// Non-copyable
|
||||
EmbeddedDaemon(const EmbeddedDaemon&) = delete;
|
||||
EmbeddedDaemon& operator=(const EmbeddedDaemon&) = delete;
|
||||
|
||||
/**
|
||||
* @brief Start the embedded dragonxd daemon
|
||||
* @param binary_path Path to dragonxd binary (auto-detect if empty)
|
||||
* @return true if process started successfully
|
||||
*/
|
||||
bool start(const std::string& binary_path = "");
|
||||
|
||||
/**
|
||||
* @brief Stop the running daemon
|
||||
* @param wait_ms Maximum milliseconds to wait for graceful shutdown
|
||||
*/
|
||||
void stop(int wait_ms = 5000);
|
||||
|
||||
/**
|
||||
* @brief Check if daemon process is running
|
||||
*/
|
||||
bool isRunning() const;
|
||||
|
||||
/**
|
||||
* @brief Get current daemon state
|
||||
*/
|
||||
State getState() const { return state_; }
|
||||
|
||||
/**
|
||||
* @brief Get daemon process memory usage (RSS) in MB
|
||||
* @return Memory usage in MB, or 0 if unavailable
|
||||
*/
|
||||
double getMemoryUsageMB() const;
|
||||
|
||||
/**
|
||||
* @brief Get last error message
|
||||
*/
|
||||
const std::string& getLastError() const { return last_error_; }
|
||||
|
||||
/**
|
||||
* @brief Get dragonxd process output (thread-safe copy)
|
||||
*/
|
||||
std::string getOutput() const {
|
||||
std::lock_guard<std::mutex> lk(output_mutex_);
|
||||
return process_output_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 Get last N lines of daemon output (thread-safe snapshot)
|
||||
*/
|
||||
std::vector<std::string> getRecentLines(int maxLines = 8) const;
|
||||
|
||||
/**
|
||||
* @brief Whether start() detected an existing daemon on the RPC port.
|
||||
* When true the wallet should connect to it instead of showing an error.
|
||||
*/
|
||||
bool externalDaemonDetected() const { return external_daemon_detected_; }
|
||||
|
||||
/**
|
||||
* @brief Set callback for state changes
|
||||
*/
|
||||
void setStateCallback(StateCallback cb) { state_callback_ = cb; }
|
||||
|
||||
/**
|
||||
* @brief Find dragonxd binary in standard locations
|
||||
* @return Path to binary, or empty if not found
|
||||
*/
|
||||
static std::string findDaemonBinary();
|
||||
|
||||
/**
|
||||
* @brief Check whether anything is listening on the default RPC port.
|
||||
* Useful for detecting an externally-started daemon.
|
||||
*/
|
||||
static bool isRpcPortInUse();
|
||||
|
||||
/**
|
||||
* @brief Get the chain parameters for dragonxd
|
||||
* @return Command line arguments for dragonx chain
|
||||
*/
|
||||
static std::vector<std::string> getChainParams();
|
||||
|
||||
/**
|
||||
* @brief Set debug logging categories (appended as -debug= flags on next start)
|
||||
*/
|
||||
void setDebugCategories(const std::set<std::string>& cats) { debug_categories_ = cats; }
|
||||
const std::set<std::string>& getDebugCategories() const { return debug_categories_; }
|
||||
|
||||
/** Get number of consecutive daemon crashes (resets on successful start or manual reset) */
|
||||
int getCrashCount() const { return crash_count_.load(); }
|
||||
/** Reset crash counter (call on successful connection or manual restart) */
|
||||
void resetCrashCount() { crash_count_ = 0; }
|
||||
|
||||
private:
|
||||
void setState(State s, const std::string& message = "");
|
||||
void monitorProcess();
|
||||
void drainOutput(); // read any pending stdout into process_output_
|
||||
void appendOutput(const char* data, size_t len); // append + trim (caller holds output_mutex_)
|
||||
bool startProcess(const std::string& binary_path, const std::vector<std::string>& args);
|
||||
|
||||
std::atomic<State> state_{State::Stopped};
|
||||
std::atomic<bool> external_daemon_detected_{false};
|
||||
std::string last_error_;
|
||||
mutable std::mutex output_mutex_; // protects process_output_
|
||||
std::string process_output_;
|
||||
StateCallback state_callback_;
|
||||
|
||||
// Process handle
|
||||
#ifdef _WIN32
|
||||
HANDLE process_handle_ = nullptr;
|
||||
HANDLE stdout_read_ = nullptr; // pipe handle (Linux-style pipe, unused when tailing debug.log)
|
||||
std::string debug_log_path_; // path to daemon's debug.log for output tailing
|
||||
size_t debug_log_offset_ = 0; // read offset into debug.log
|
||||
std::string launch_cmd_; // full command line used to launch daemon (for diagnostics)
|
||||
std::string launch_binary_; // binary path used (for diagnostics)
|
||||
std::string launch_workdir_; // working directory used (for diagnostics)
|
||||
#else
|
||||
pid_t process_pid_ = 0;
|
||||
int stdout_fd_ = -1;
|
||||
#endif
|
||||
|
||||
std::thread monitor_thread_;
|
||||
std::atomic<bool> should_stop_{false};
|
||||
std::set<std::string> debug_categories_;
|
||||
std::atomic<int> crash_count_{0}; // consecutive crash counter
|
||||
};
|
||||
|
||||
} // namespace daemon
|
||||
} // namespace dragonx
|
||||
Reference in New Issue
Block a user