fix: Windows identity, async address creation, mining UI, and chart artifacts
Windows identity: - Add VERSIONINFO resource (.rc) with ObsidianDragon file description - Embed application manifest for DPI awareness and shell identity - Patch libwinpthread/libpthread to remove competing VERSIONINFO - Set AppUserModelID and HWND property store to override Task Manager cache - Link patched pthread libs to eliminate "POSIX WinThreads" description Address creation (+New button): - Move z_getnewaddress/getnewaddress off UI thread to async worker - Inject new address into state immediately for instant UI selection - Trigger background refresh for balance updates Mining tab: - Add pool mining dropdown with saved URLs/workers and bookmarks - Add solo mining log panel from daemon output with chart/log toggle - Fix toggle button cursor (render after InputTextMultiline) - Auto-restart miner on pool config change - Migrate default pool URL to include stratum port Transactions: - Sort pending (0-conf) transactions to top of history - Fall back to timereceived when timestamp is missing Shutdown: - Replace blocking sleep_for calls with 100ms polling loops - Check shutting_down_ flag throughout daemon restart/bootstrap flows - Reduce daemon stop timeout from 30s to 10s Other: - Fix market chart fill artifact (single concave polygon vs per-segment quads) - Add bootstrap checksum verification state display - Rename daemon client identifier to ObsidianDragon
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace dragonx {
|
||||
namespace ui {
|
||||
@@ -45,6 +46,22 @@ static std::string ExtractIP(const std::string& addr)
|
||||
return ip;
|
||||
}
|
||||
|
||||
// Known seed/addnode IPs for the DragonX network.
|
||||
// These are the official seed nodes that the daemon connects to on startup.
|
||||
static bool IsSeedNode(const std::string& addr) {
|
||||
static const std::unordered_set<std::string> seeds = {
|
||||
"176.126.87.241", // embedded daemon -addnode
|
||||
"94.72.112.24", // node1.hush.is
|
||||
"37.60.252.160", // node2.hush.is
|
||||
"176.57.70.185", // node3.hush.is / node6.hush.is
|
||||
"185.213.209.89", // node4.hush.is
|
||||
"137.74.4.198", // node5.hush.is
|
||||
"18.193.113.121", // node7.hush.is
|
||||
"38.60.224.94", // node8.hush.is
|
||||
};
|
||||
return seeds.count(ExtractIP(addr)) > 0;
|
||||
}
|
||||
|
||||
void RenderPeersTab(App* app)
|
||||
{
|
||||
auto& S = schema::UI();
|
||||
@@ -149,10 +166,28 @@ void RenderPeersTab(App* app)
|
||||
// Blocks
|
||||
float cx = cardMin.x + pad;
|
||||
dl->AddText(capFont, capFont->LegacySize, ImVec2(cx, ry), OnSurfaceMedium(), "Blocks");
|
||||
int blocks = mining.blocks > 0 ? mining.blocks : state.sync.blocks;
|
||||
int blocks = state.sync.blocks;
|
||||
if (blocks > 0) {
|
||||
snprintf(buf, sizeof(buf), "%d", blocks);
|
||||
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurface(), buf);
|
||||
int blocksLeft = state.sync.headers - blocks;
|
||||
if (blocksLeft < 0) blocksLeft = 0;
|
||||
if (blocksLeft > 0) {
|
||||
snprintf(buf, sizeof(buf), "%d (%d left)", blocks, blocksLeft);
|
||||
float valY = ry + capFont->LegacySize + Layout::spacingXs();
|
||||
// Draw block number in normal color
|
||||
char blockStr[32];
|
||||
snprintf(blockStr, sizeof(blockStr), "%d ", blocks);
|
||||
ImVec2 numSz = sub1->CalcTextSizeA(sub1->LegacySize, FLT_MAX, 0, blockStr);
|
||||
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, valY), OnSurface(), blockStr);
|
||||
// Draw "(X left)" in warning color
|
||||
char leftStr[32];
|
||||
snprintf(leftStr, sizeof(leftStr), "(%d left)", blocksLeft);
|
||||
dl->AddText(capFont, capFont->LegacySize,
|
||||
ImVec2(cx + numSz.x, valY + (sub1->LegacySize - capFont->LegacySize) * 0.5f),
|
||||
Warning(), leftStr);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%d", blocks);
|
||||
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurface(), buf);
|
||||
}
|
||||
} else {
|
||||
dl->AddText(sub1, sub1->LegacySize, ImVec2(cx, ry + capFont->LegacySize + Layout::spacingXs()), OnSurfaceDisabled(), "\xE2\x80\x94");
|
||||
}
|
||||
@@ -680,7 +715,16 @@ void RenderPeersTab(App* app)
|
||||
float pingDotR = S.drawElement("tabs.peers", "ping-dot-radius-base").size + S.drawElement("tabs.peers", "ping-dot-radius-scale").size * hs;
|
||||
dl->AddCircleFilled(ImVec2(cx + S.drawElement("tabs.peers", "ping-dot-x-offset").size, cy + body2->LegacySize * 0.5f), pingDotR, dotCol);
|
||||
|
||||
dl->AddText(body2, body2->LegacySize, ImVec2(cx + S.drawElement("tabs.peers", "address-x-offset").size, cy), OnSurface(), peer.addr.c_str());
|
||||
float addrX = cx + S.drawElement("tabs.peers", "address-x-offset").size;
|
||||
dl->AddText(body2, body2->LegacySize, ImVec2(addrX, cy), OnSurface(), peer.addr.c_str());
|
||||
|
||||
// Seed node icon — rendered right after the IP address
|
||||
if (IsSeedNode(peer.addr)) {
|
||||
ImVec2 addrSz = body2->CalcTextSizeA(body2->LegacySize, FLT_MAX, 0, peer.addr.c_str());
|
||||
ImFont* iconFont = Type().iconSmall();
|
||||
float iconY = cy + (body2->LegacySize - iconFont->LegacySize) * 0.5f;
|
||||
dl->AddText(iconFont, iconFont->LegacySize, ImVec2(addrX + addrSz.x + Layout::spacingSm(), iconY), WithAlpha(Success(), 200), ICON_MD_GRASS);
|
||||
}
|
||||
|
||||
{
|
||||
const char* dirLabel = peer.inbound ? "In" : "Out";
|
||||
|
||||
Reference in New Issue
Block a user