fix: large-wallet sync starvation + shutdown/console-flash UX (Windows full node) #2

Open
DanS wants to merge 12 commits from fix/balance-poll-sync-contention into dev
3 changed files with 46 additions and 2 deletions
Showing only changes of commit 29274c2f48 - Show all commits

View File

@@ -5742,6 +5742,39 @@ void App::beginShutdown()
});
}
std::vector<std::string> App::tailDaemonDebugLog(int maxLines) const
{
std::vector<std::string> out;
if (maxLines <= 0) return out;
const std::string path = util::Platform::getDataDir() + "debug.log";
std::error_code ec;
const auto sz = std::filesystem::file_size(path, ec);
if (ec || sz == 0) return out;
std::ifstream f(path, std::ios::binary);
if (!f) return out;
// Read only the last ~16 KB — plenty for a handful of lines, cheap even for a multi-GB log.
const std::uintmax_t kTailBytes = 16 * 1024;
const std::uintmax_t start = sz > kTailBytes ? sz - kTailBytes : 0;
f.seekg(static_cast<std::streamoff>(start), std::ios::beg);
std::string chunk(static_cast<std::size_t>(sz - start), '\0');
f.read(&chunk[0], static_cast<std::streamsize>(chunk.size()));
chunk.resize(static_cast<std::size_t>(f.gcount()));
std::vector<std::string> lines;
std::string cur;
for (char c : chunk) {
if (c == '\n') { if (!cur.empty()) lines.push_back(cur); cur.clear(); }
else if (c != '\r') cur.push_back(c);
}
if (!cur.empty()) lines.push_back(cur);
// When we seeked into the middle of the file the first line is a fragment — drop it.
if (start > 0 && !lines.empty()) lines.erase(lines.begin());
if (static_cast<int>(lines.size()) > maxLines)
lines.erase(lines.begin(), lines.end() - static_cast<std::ptrdiff_t>(maxLines));
return lines;
}
void App::renderShutdownScreen()
{
using namespace ui::material;
@@ -5974,6 +6007,10 @@ void App::renderShutdownScreen()
// -------------------------------------------------------------------
if (daemon_controller_) {
auto lines = daemon_controller_->recentLines(8);
// External daemon (attached, not spawned) has no captured stdout — tail its debug.log directly
// so the user can still watch the node flush the block index and exit.
if (lines.empty())
lines = tailDaemonDebugLog(8);
if (!lines.empty()) {
float panelW = vp_size.x * shutElem("panel-width-fraction", 0.70f);
float panelX = cx - panelW * 0.5f;

View File

@@ -175,6 +175,13 @@ public:
*/
void renderShutdownScreen();
/**
* @brief Tail the last N lines of the daemon's debug.log (best-effort, reads only the file tail).
* Fallback for the shutdown screen when we have no captured stdout — e.g. an external daemon we
* attached to rather than spawned — so the user can still see the node flushing/exiting.
*/
std::vector<std::string> tailDaemonDebugLog(int maxLines) const;
/**
* @brief Render loading overlay in content area while daemon is starting/syncing
* @param contentH Height of the content area child window

View File

@@ -1456,8 +1456,8 @@ void I18n::loadBuiltinEnglish()
strings_["sb_daemon_extract_failed"] = "Failed to write daemon files — check free disk space and permissions.";
strings_["sb_daemon_files_failed"] = "Failed to write daemon files to %s — check free disk space and permissions.";
strings_["loading_stall_title"] = "Taking longer than expected";
strings_["loading_stall_body"] = "The daemon has been initializing for %.0fs. This can be normal after an update or on first launch (loading the block index or rescanning) — it will connect automatically once ready.";
strings_["loading_stall_hint"] = "Still stuck? Open Settings and use Restart Daemon, or check the Console for details.";
strings_["loading_stall_body"] = "Initializing for %.0fs normal after an update or first launch. Connects automatically when ready.";
strings_["loading_stall_hint"] = "Stuck? Settings Restart Daemon, or check the Console.";
strings_["sb_plaintext_remote_blocked"] = "Refusing to send RPC credentials over plaintext to a remote host. Add rpcallowplaintext=1 to DRAGONX.conf to allow it, or enable TLS with rpctls=1.";
strings_["rpc_plaintext_remote_warning"] = "Remote RPC is using plaintext HTTP. Add rpctls=1 to DRAGONX.conf if your daemon supports TLS.";
strings_["settings_open_log_folder"] = "Open log folder";