feat(lite): async wallet creation with server failover
Mirror the async-open path for wallet creation. beginOpenExisting() and beginCreateWallet() now both delegate to beginAsyncLifecycle(bool create), which runs the backend init on a detached thread and walks the failover server list (preferred server first, then all usable defaults), reporting the preferred server's error on total failure. The first-run wizard's Create button drives this through a non-blocking "creating" poll state so the UI no longer freezes while the backend contacts a (possibly flaky) lightwalletd. The created seed response is securely wiped immediately and read back via exportSeed for the reveal/verify steps. Safe because litelib_initialize_new contacts the server before writing any wallet file and LightClient::new errors if a wallet already exists, so a failed candidate leaves no partial state. Tests: fake backend's initialize_new now honors the dead/warmup server substrings; testLiteWalletControllerOpenFailover gains a create-failover case (preferred dead, fallback good -> walletOpen). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -64,8 +64,20 @@ inline bool liteFakeWalletExists(const char*) { return g_liteFakeWalletExists; }
|
||||
// Match the real litelib_* return shapes so tests exercise the production walletReady path:
|
||||
// create/restore return a seed object ({"seed":..,"birthday":..}); open returns the bare
|
||||
// string "OK" (NOT JSON) — see litelib_initialize_existing.
|
||||
inline char* liteFakeInitNew(bool, const char*)
|
||||
inline char* liteFakeInitNew(bool, const char* server)
|
||||
{
|
||||
// Honor the dead/warmup substrings so create-with-failover can be exercised (mirrors how the
|
||||
// real initialize_new contacts the server first and fails before writing a wallet).
|
||||
if (server) {
|
||||
const std::string s(server);
|
||||
if (!g_liteFakeWarmupServerSubstr.empty() &&
|
||||
s.find(g_liteFakeWarmupServerSubstr) != std::string::npos)
|
||||
return liteFakeDup("Error: grpc-message: \"error requesting block: -28: "
|
||||
"Activating best chain...\"");
|
||||
if (!g_liteFakeDeadServerSubstr.empty() &&
|
||||
s.find(g_liteFakeDeadServerSubstr) != std::string::npos)
|
||||
return liteFakeDup("Error: could not connect to server");
|
||||
}
|
||||
return liteFakeDup("{\"seed\":\"fake seed phrase words\",\"birthday\":0}");
|
||||
}
|
||||
inline char* liteFakeInitFromPhrase(bool, const char*, const char*,
|
||||
|
||||
@@ -3578,7 +3578,7 @@ void testLiteWalletControllerOpenFailover()
|
||||
bool sawConnecting = false, sawOpened = false;
|
||||
for (const auto& l : log) {
|
||||
if (l.find("connecting to") != std::string::npos) sawConnecting = true;
|
||||
if (l.find("Wallet opened via") != std::string::npos) sawOpened = true;
|
||||
if (l.find("Wallet ready via") != std::string::npos) sawOpened = true;
|
||||
}
|
||||
EXPECT_TRUE(sawConnecting);
|
||||
EXPECT_TRUE(sawOpened);
|
||||
@@ -3616,6 +3616,23 @@ void testLiteWalletControllerOpenFailover()
|
||||
EXPECT_TRUE(controller.lastOpenWasWarmup());
|
||||
}
|
||||
|
||||
// Create also fails over: preferred dead, fallback good -> a new wallet is created via the
|
||||
// fallback (no existing wallet beforehand).
|
||||
{
|
||||
dragonx::test::resetLiteFakeCounters();
|
||||
dragonx::test::g_liteFakeWalletExists = false; // creating fresh
|
||||
dragonx::test::g_liteFakeDeadServerSubstr = "dead.example";
|
||||
LiteWalletController controller(liteCaps, conn,
|
||||
LiteClientBridge::fromApi(dragonx::test::makeFakeLiteApi()));
|
||||
EXPECT_FALSE(controller.walletOpen());
|
||||
EXPECT_TRUE(controller.beginCreateWallet());
|
||||
for (int i = 0; i < 400 && controller.openInProgress(); ++i)
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||
controller.pumpAsyncOpen();
|
||||
EXPECT_TRUE(controller.walletOpen());
|
||||
EXPECT_TRUE(controller.lastOpenError().empty());
|
||||
}
|
||||
|
||||
dragonx::test::g_liteFakeWalletExists = false;
|
||||
dragonx::test::g_liteFakeDeadServerSubstr.clear();
|
||||
dragonx::test::g_liteFakeWarmupServerSubstr.clear();
|
||||
|
||||
Reference in New Issue
Block a user