- Explorer: the tip check runs every frame the Explorer tab is open, and it read both tip rows and rewrote them each time (two autocommit WAL writes per frame). A steady tip is now kept in memory and skips SQLite. A new tip writes both rows in one savepoint, so a crash between them can't pair a new height with the old hash. A test checks that 100 steady checks write nothing. - Console: while the daemon was in the Error state the Console tab added its error line on every poll, i.e. every frame, re-laying out the whole buffer each time. It prints once per error now: on entering Error, when the message changes, or after another crash (EmbeddedDaemon::getUnexpectedExitCount(), never reset). setState writes the message before the state, so a reader that sees Error sees that error's message. The stray " ===" suffix is gone. - perf.log: the profiler appended a block every 300 frames on every run and never rotated the file (tens of MB a day for a wallet left open). It is now off unless the app starts with DRAGONX_PERFLOG=1; otherwise its zone hooks are near no-ops. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
85 lines
3.1 KiB
C++
85 lines
3.1 KiB
C++
#include "console_tab_helpers.h"
|
|
|
|
#include <algorithm>
|
|
#include <cctype>
|
|
|
|
namespace dragonx {
|
|
namespace ui {
|
|
|
|
namespace {
|
|
// First tokens (lowercase) of console/RPC commands that carry a secret argument on the command line.
|
|
// Output-secret commands (dumpprivkey / z_exportkey / z_exportmnemonic) are deliberately absent —
|
|
// their secret is in the RESULT, which is a separate redaction concern.
|
|
const char* const kSecretConsoleCommands[] = {
|
|
"walletpassphrase", "walletpassphrasechange", "encryptwallet",
|
|
"importprivkey", "importwallet", "importmulti",
|
|
"z_importkey", "z_importviewingkey", "z_importwallet",
|
|
"signrawtransaction", "magicrecoverkey", "sethdseed", "importmnemonic",
|
|
};
|
|
|
|
std::string firstConsoleTokenLower(const std::string& cmd, size_t& tokenEnd) {
|
|
size_t b = cmd.find_first_not_of(" \t");
|
|
if (b == std::string::npos) { tokenEnd = cmd.size(); return {}; }
|
|
size_t e = cmd.find_first_of(" \t", b);
|
|
tokenEnd = (e == std::string::npos) ? cmd.size() : e;
|
|
std::string t = cmd.substr(b, tokenEnd - b);
|
|
std::transform(t.begin(), t.end(), t.begin(),
|
|
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
|
return t;
|
|
}
|
|
} // namespace
|
|
|
|
float ComputeConsoleInputHeight(float frameHeightWithSpacing,
|
|
float itemSpacingY,
|
|
float spacingSm,
|
|
float spacingXs,
|
|
float cursorOffset)
|
|
{
|
|
return spacingSm + itemSpacingY + frameHeightWithSpacing + spacingSm + spacingXs + cursorOffset;
|
|
}
|
|
|
|
float ComputeConsoleOutputHeight(float availableHeight,
|
|
float inputHeight,
|
|
float minHeight,
|
|
float minHeightRatio)
|
|
{
|
|
return std::max(availableHeight - inputHeight, std::max(minHeight, availableHeight * minHeightRatio));
|
|
}
|
|
|
|
float ClampConsoleWrapWidth(float contentWidth, float paddingX)
|
|
{
|
|
return std::max(50.0f, contentWidth - paddingX * 2.0f);
|
|
}
|
|
|
|
bool ShouldPrintDaemonErrorLine(bool wasError, bool isError,
|
|
const std::string& error, const std::string& lastPrinted,
|
|
bool newUnexpectedExit)
|
|
{
|
|
return isError && (!wasError || error != lastPrinted || newUnexpectedExit);
|
|
}
|
|
|
|
bool ConsoleCommandCarriesSecret(const std::string& cmd)
|
|
{
|
|
size_t end = 0;
|
|
const std::string name = firstConsoleTokenLower(cmd, end);
|
|
if (name.empty()) return false;
|
|
for (const char* s : kSecretConsoleCommands) if (name == s) return true;
|
|
return false;
|
|
}
|
|
|
|
std::string RedactConsoleCommand(const std::string& cmd)
|
|
{
|
|
size_t end = 0;
|
|
const std::string name = firstConsoleTokenLower(cmd, end);
|
|
if (name.empty()) return cmd;
|
|
bool secret = false;
|
|
for (const char* s : kSecretConsoleCommands) if (name == s) { secret = true; break; }
|
|
if (!secret) return cmd;
|
|
// Only redact if there are actually arguments after the command name.
|
|
if (cmd.find_first_not_of(" \t", end) == std::string::npos) return cmd;
|
|
return cmd.substr(0, end) + " ****";
|
|
}
|
|
|
|
} // namespace ui
|
|
} // namespace dragonx
|