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:
116
src/util/bootstrap.h
Normal file
116
src/util/bootstrap.h
Normal file
@@ -0,0 +1,116 @@
|
||||
// DragonX Wallet - ImGui Edition
|
||||
// Copyright 2024-2026 The Hush Developers
|
||||
// Released under the GPLv3
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
namespace dragonx {
|
||||
namespace util {
|
||||
|
||||
/**
|
||||
* @brief Bootstrap downloader + extractor for DRAGONX blockchain data.
|
||||
*
|
||||
* Downloads a blockchain snapshot zip from bootstrap.dragonx.is, verifies
|
||||
* SHA-256 / MD5 checksums, extracts it into the DRAGONX data directory
|
||||
* (skipping wallet.dat), and cleans old chain data before extraction.
|
||||
* All work runs on a background thread; progress is queried thread-safely
|
||||
* from the UI thread.
|
||||
*/
|
||||
class Bootstrap {
|
||||
public:
|
||||
enum class State {
|
||||
Idle,
|
||||
Downloading,
|
||||
Extracting,
|
||||
Completed,
|
||||
Failed
|
||||
};
|
||||
|
||||
struct Progress {
|
||||
State state = State::Idle;
|
||||
double downloaded_bytes = 0;
|
||||
double total_bytes = 0; // 0 if server doesn't send Content-Length
|
||||
float percent = 0.0f; // 0..100
|
||||
std::string status_text; // human-readable status
|
||||
std::string error; // non-empty on failure
|
||||
};
|
||||
|
||||
Bootstrap() = default;
|
||||
~Bootstrap();
|
||||
|
||||
// Non-copyable
|
||||
Bootstrap(const Bootstrap&) = delete;
|
||||
Bootstrap& operator=(const Bootstrap&) = delete;
|
||||
|
||||
/// Base URL for bootstrap downloads (zip + checksum files).
|
||||
static constexpr const char* kBaseUrl = "https://bootstrap.dragonx.is";
|
||||
static constexpr const char* kZipName = "DRAGONX.zip";
|
||||
|
||||
/// Start the bootstrap process on a background thread.
|
||||
/// @param dataDir Path to DRAGONX data dir (e.g. ~/.hush/DRAGONX/)
|
||||
/// @param url Bootstrap zip URL
|
||||
void start(const std::string& dataDir,
|
||||
const std::string& url = "https://bootstrap.dragonx.is/DRAGONX.zip");
|
||||
|
||||
/// Cancel an in-progress download/extract.
|
||||
void cancel();
|
||||
|
||||
/// Thread-safe read of current progress.
|
||||
Progress getProgress() const;
|
||||
|
||||
/// Whether the operation is finished (success or failure).
|
||||
bool isDone() const;
|
||||
|
||||
/// Format a byte count as human-readable string (e.g. "1.24 GB")
|
||||
static std::string formatSize(double bytes);
|
||||
|
||||
private:
|
||||
mutable std::mutex mutex_;
|
||||
Progress progress_;
|
||||
std::atomic<bool> cancel_requested_{false};
|
||||
std::thread worker_;
|
||||
std::atomic<bool> worker_running_{false};
|
||||
|
||||
bool download(const std::string& url, const std::string& destZip);
|
||||
bool extract(const std::string& zipPath, const std::string& dataDir);
|
||||
void cleanChainData(const std::string& dataDir);
|
||||
void setProgress(State state, const std::string& text, double downloaded = 0, double total = 0);
|
||||
|
||||
/// Download a small text file (checksum) into a string. Returns empty on failure.
|
||||
std::string downloadSmallFile(const std::string& url);
|
||||
|
||||
/// Compute SHA-256 of a file, return lowercase hex digest.
|
||||
/// Updates progress with "Verifying SHA-256..." status during computation.
|
||||
std::string computeSHA256(const std::string& filePath);
|
||||
|
||||
/// Compute MD5 of a file, return lowercase hex digest.
|
||||
/// Updates progress with "Verifying MD5..." status during computation.
|
||||
std::string computeMD5(const std::string& filePath);
|
||||
|
||||
/// Parse the first hex token from a checksum file (handles "<hash> <filename>" format).
|
||||
static std::string parseChecksumFile(const std::string& content);
|
||||
|
||||
/// Verify downloaded zip against remote checksums. Returns true if valid.
|
||||
bool verifyChecksums(const std::string& zipPath, const std::string& baseUrl);
|
||||
|
||||
/// Perform a HEAD request to get remote file size.
|
||||
/// Returns -1 on failure.
|
||||
long long getRemoteFileSize(const std::string& url);
|
||||
|
||||
/// Byte offset of the partial file when resuming a download.
|
||||
/// Added to dlnow in progress reports so the bar reflects true total.
|
||||
double resume_offset_{0};
|
||||
|
||||
// libcurl progress callback (static → calls into instance via clientp)
|
||||
static int progressCallback(void* clientp, long long dltotal, long long dlnow,
|
||||
long long ultotal, long long ulnow);
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace dragonx
|
||||
Reference in New Issue
Block a user