fix: FAQ CJK glyphs, outgoing-tx history, lite encryption, migrate & sync safety
Bug-report fixes plus adversarial-audit follow-ups. Bumps full 2.0.1->2.0.2 and lite 1.1.0->1.1.1. i18n / fonts: - Rebuild the NotoSansCJK subset with the glyphs the FAQ back-fill introduced (什/么/门/做); Chinese FAQ titles rendered as "??" on zh (and ja/ko). Transaction history (enumeration gaps): - Surface outgoing shielded z->z sends via z_listsentbyaddress (listtransactions and z_listreceivedbyaddress never report them). - Surface z->t deshields by parsing z_listsentbyaddress transparentSends (which z_viewtransaction does not expose); dedupe t->t against listtransactions. - Key send-row dedup on address so equal-value multi-output sends aren't dropped. Lite wallet (key safety): - The async create/restore/open path the UI uses now applies the passphrase: encrypt a new/restored wallet, unlock an existing one. It previously discarded the passphrase, storing the seed/keys in PLAINTEXT (create/restore) or leaving an encrypted wallet locked (open). Migrate-to-seed (fund safety): - Persist a sweep-submitted marker at broadcast so a resumed migration can't treat a ~0 balance (an unconfirmed in-flight sweep) as an empty wallet and adopt (swap wallet.dat) before the sweep confirms; best-effort locate routes to the confirm gate. Sync / threading: - Gate isSynced() on a peer-derived tip (tip_known) so a peerless node isn't reported synced (Send against a stale balance); add a "no peers" status banner. - Guard daemon_status_ with a mutex (monitor-thread write vs UI-thread read). Tests: extends tests/test_phase4.cpp across all of the above; suite green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwycPDQSfEKtrTS2uC4JeT
This commit is contained in:
@@ -388,6 +388,20 @@ private:
|
||||
std::make_shared<std::optional<LiteWalletLifecycleResult>>();
|
||||
LiteWalletLifecycleResult lastLifecycleResult_; // main-thread only; last finalized request
|
||||
|
||||
// Passphrase to apply on the main thread once an async create/restore/open finalizes. The
|
||||
// backend wallet is not controller-"open" (walletOpen_) until pumpLifecycleResult() runs
|
||||
// onLifecycleResult(), and encryptWallet()/unlockWallet() gate on walletOpen_ — so the async
|
||||
// worker thread cannot do it. The passphrase is stashed here (main-thread only) and applied in
|
||||
// pumpLifecycleResult(), mirroring the synchronous createWallet()/restoreWallet()/openWallet()
|
||||
// wrappers. Without this the UI's async path silently discarded the passphrase, storing the
|
||||
// seed UNENCRYPTED (create/restore) or never unlocking an encrypted wallet (open) — audit C1/M1.
|
||||
enum class PendingSecurityOp { None, Encrypt, Unlock };
|
||||
std::string pendingLifecyclePassphrase_; // main-thread only; wiped after use
|
||||
PendingSecurityOp pendingLifecycleSecurityOp_ = PendingSecurityOp::None;
|
||||
void stashPendingLifecycleSecurity(const std::string& passphrase, PendingSecurityOp op);
|
||||
void applyPendingLifecycleSecurity(); // encrypt (create/restore) or unlock (open), then wipe
|
||||
void clearPendingLifecycleSecurity(); // wipe + reset (rejected request / failed open)
|
||||
|
||||
// Joinable background refresh worker (fast iterations: syncstatus, plus data once synced).
|
||||
std::thread worker_;
|
||||
std::atomic<bool> running_{false};
|
||||
|
||||
Reference in New Issue
Block a user