fix(lite): keep a rejected import key out of the log and Settings
The backend's error for a key it doesn't recognize repeats the key
("'<key>' was not recognized as either a spending key or a viewing
key"). Import passed that text on as its error, so a mistyped private
key was written to the lite log (shown in the Console tab) and to the
Settings status line. A failed import now carries a fixed reason
(unrecognized format, wallet locked, key already exists, could not be
decoded, or rejected), which is all the log records. Settings shows
"Couldn't import the key — check it, unlock the wallet (if encrypted)
and try again." instead, translated in all eight languages.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8376,6 +8376,45 @@ void testLiteWalletControllerRetireStopsOpFollowUps()
|
||||
dragonx::test::g_liteFakeLocked = false;
|
||||
}
|
||||
|
||||
// The backend's import error for an unrecognized key repeats the key ("'<key>' was not recognized ..."): the controller
|
||||
// must never put that text in its result (shown in Settings) or in the lite log, only a fixed, non-secret reason.
|
||||
void testLiteWalletControllerImportErrorNeverRepeatsKey()
|
||||
{
|
||||
using namespace dragonx::wallet;
|
||||
const auto caps = makeWalletCapabilities(WalletBuildKind::Lite, false, true);
|
||||
const auto conn = defaultLiteConnectionSettings();
|
||||
dragonx::test::resetLiteFakeCounters();
|
||||
LiteWalletController c(caps, conn, LiteClientBridge::fromApi(dragonx::test::makeFakeLiteApi()));
|
||||
EXPECT_TRUE(c.createWallet(LiteWalletCreateRequest{}).walletReady);
|
||||
for (int i = 0; i < 400 && !c.syncComplete(); ++i) std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
dragonx::test::g_liteFakeImportFails = true;
|
||||
const auto logMentions = [](const std::string& needle) {
|
||||
for (const auto& line : LiteDiagnostics::instance().snapshot())
|
||||
if (line.find(needle) != std::string::npos) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
{ // synchronous: both attempts fail; neither the result nor the log carries the key
|
||||
const auto r = c.importKey("secret-extended-key-typoMARKSYNC");
|
||||
EXPECT_FALSE(r.ok);
|
||||
EXPECT_EQ(r.error, std::string("unrecognized key format"));
|
||||
EXPECT_TRUE(r.error.find("MARKSYNC") == std::string::npos);
|
||||
EXPECT_FALSE(logMentions("MARKSYNC"));
|
||||
EXPECT_TRUE(logMentions("Key import failed: unrecognized key format"));
|
||||
}
|
||||
{ // async (the Settings path)
|
||||
int n = 0; LiteImportResult got; got.ok = true;
|
||||
EXPECT_TRUE(c.importKeyAsync("Kx1typoMARKASYNC", [&](const LiteImportResult& r) { ++n; got = r; }));
|
||||
EXPECT_TRUE(c.waitWalletOpsIdle(std::chrono::milliseconds(3000)));
|
||||
c.pumpWalletOps();
|
||||
EXPECT_EQ(n, 1);
|
||||
EXPECT_FALSE(got.ok);
|
||||
EXPECT_TRUE(got.error.find("MARKASYNC") == std::string::npos);
|
||||
EXPECT_FALSE(logMentions("MARKASYNC"));
|
||||
}
|
||||
dragonx::test::g_liteFakeImportFails = false;
|
||||
}
|
||||
|
||||
void testLiteWalletControllerEncryptsBeforeSyncStarts()
|
||||
{
|
||||
using namespace dragonx::wallet;
|
||||
@@ -13597,6 +13636,7 @@ int main()
|
||||
testLiteWalletControllerWalletOpsAsync();
|
||||
testLiteWalletControllerRetire();
|
||||
testLiteWalletControllerRetireStopsOpFollowUps();
|
||||
testLiteWalletControllerImportErrorNeverRepeatsKey();
|
||||
testLiteWalletControllerEncryptsBeforeSyncStarts();
|
||||
testLiteWalletControllerWorkerBacksOffOnSyncReadFailure();
|
||||
testLiteWalletControllerDestroyWithBlockedOp();
|
||||
|
||||
Reference in New Issue
Block a user