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:
@@ -168,8 +168,14 @@ public:
|
||||
// already open, an open is already in progress, no wallet exists, or the rollout gate blocks
|
||||
// lite. On all-servers-fail, status()/lastOpenError() report the reason.
|
||||
bool beginOpenExisting();
|
||||
// Finalize a completed async open on the calling (main) thread: flips walletOpen()/status and
|
||||
// starts sync, or records the failure. Cheap no-op when nothing is pending. Call each tick.
|
||||
// Asynchronously CREATE a new wallet (new seed) with the same server failover as open:
|
||||
// initialize_new contacts the server before writing any file, so an unreachable server fails
|
||||
// cleanly and the next is tried. On success the seed lives in the wallet — read it back with
|
||||
// exportSeed(). Non-blocking; finalized by pumpAsyncOpen(). Returns false if a wallet is open,
|
||||
// an open/create is in progress, the rollout gate blocks lite, or no usable server exists.
|
||||
bool beginCreateWallet();
|
||||
// Finalize a completed async open/create on the calling (main) thread: flips walletOpen()/status
|
||||
// and starts sync, or records the failure. Cheap no-op when nothing is pending. Call each tick.
|
||||
void pumpAsyncOpen();
|
||||
bool openInProgress() const { return openRunning_ && openRunning_->load(); }
|
||||
const std::string& lastOpenError() const { return lastOpenError_; }
|
||||
@@ -294,6 +300,8 @@ private:
|
||||
// the detached thread captures only shared_ptrs + value copies, never `this`, so it can
|
||||
// safely outlive the controller). pumpAsyncOpen() finalizes the result on the main thread.
|
||||
std::vector<std::string> failoverServerUrls() const;
|
||||
// Shared async open/create-with-failover core (create=true uses initialize_new).
|
||||
bool beginAsyncLifecycle(bool create);
|
||||
struct OpenOutcome { bool ok = false; bool warming = false; std::string serverUrl; std::string error; };
|
||||
std::thread openThread_;
|
||||
std::shared_ptr<std::atomic<bool>> openRunning_ = std::make_shared<std::atomic<bool>>(false);
|
||||
|
||||
Reference in New Issue
Block a user