fix(app): stop the seed-backup nudge and chat identity retrying every frame
The one-time "back up your seed phrase" nudge only stopped probing on a
success or the exact "not derived from a mnemonic" error. Any other
answer re-armed it for the next frame, so a daemon without the RPC
("Method not found", e.g. the older bundled binary) was sent
z_exportmnemonic at frame rate: ~2,300 requests/s against a test node.
Chat identity setup re-posted its fetch on the next frame after a
transient failure in the same way.
An inconclusive nudge probe now waits 5 minutes before the next; a
transient identity-fetch failure waits 10 seconds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -769,6 +769,7 @@ private:
|
|||||||
chat::ChatDatabase chat_db_; // persistent backing (seed-derived encryption at rest)
|
chat::ChatDatabase chat_db_; // persistent backing (seed-derived encryption at rest)
|
||||||
bool chat_identity_provisioned_ = false; // identity set on the service this session
|
bool chat_identity_provisioned_ = false; // identity set on the service this session
|
||||||
bool chat_identity_fetch_in_flight_ = false; // a z_exportmnemonic worker job is pending
|
bool chat_identity_fetch_in_flight_ = false; // a z_exportmnemonic worker job is pending
|
||||||
|
std::chrono::steady_clock::time_point chat_identity_retry_at_{}; // after a transient failure
|
||||||
// Bumped by resetChatSession() on every wallet change; an in-flight identity fetch captures the
|
// Bumped by resetChatSession() on every wallet change; an in-flight identity fetch captures the
|
||||||
// value at post time and its completion callback discards its (previous-wallet) secret if the id
|
// value at post time and its completion callback discards its (previous-wallet) secret if the id
|
||||||
// no longer matches — so wallet A's seed can't be provisioned under wallet B via a stale job.
|
// no longer matches — so wallet A's seed can't be provisioned under wallet B via a stale job.
|
||||||
@@ -1098,6 +1099,7 @@ private:
|
|||||||
bool seed_backup_loading_ = false;
|
bool seed_backup_loading_ = false;
|
||||||
bool seed_backup_no_mnemonic_ = false;
|
bool seed_backup_no_mnemonic_ = false;
|
||||||
bool seed_backup_reminder_in_flight_ = false; // guards the one-time backup nudge probe
|
bool seed_backup_reminder_in_flight_ = false; // guards the one-time backup nudge probe
|
||||||
|
std::chrono::steady_clock::time_point seed_backup_reminder_retry_at_{}; // after an inconclusive probe
|
||||||
bool large_wallet_checked_ = false; // gate: stat wallet.dat for the bloat nudge once per launch
|
bool large_wallet_checked_ = false; // gate: stat wallet.dat for the bloat nudge once per launch
|
||||||
|
|
||||||
// Cached mnemonic status of the current wallet, driving the Migrate-to-seed button glow. Probed
|
// Cached mnemonic status of the current wallet, driving the Migrate-to-seed button glow. Probed
|
||||||
|
|||||||
@@ -3136,6 +3136,9 @@ void App::maybeProvisionChatIdentity()
|
|||||||
|
|
||||||
if (chat_service_.hasIdentity() || chat_identity_provisioned_ ||
|
if (chat_service_.hasIdentity() || chat_identity_provisioned_ ||
|
||||||
chat_identity_fetch_in_flight_ || chat_identity_unavailable_) return;
|
chat_identity_fetch_in_flight_ || chat_identity_unavailable_) return;
|
||||||
|
// After a transient failure (connection blip, a busy node) wait before asking again: retrying on the
|
||||||
|
// next frame re-sent the request continuously.
|
||||||
|
if (std::chrono::steady_clock::now() < chat_identity_retry_at_) return;
|
||||||
|
|
||||||
if (supportsLiteBackend()) {
|
if (supportsLiteBackend()) {
|
||||||
// Lite: the backend's `seed` command returns the 24-word mnemonic synchronously.
|
// Lite: the backend's `seed` command returns the 24-word mnemonic synchronously.
|
||||||
@@ -3206,6 +3209,7 @@ void App::maybeProvisionChatIdentity()
|
|||||||
}
|
}
|
||||||
chat_identity_fetch_in_flight_ = false;
|
chat_identity_fetch_in_flight_ = false;
|
||||||
if (unavailable) chat_identity_unavailable_ = true;
|
if (unavailable) chat_identity_unavailable_ = true;
|
||||||
|
if (transientFail) chat_identity_retry_at_ = std::chrono::steady_clock::now() + std::chrono::seconds(10);
|
||||||
// Provision only on success AND while still unlocked: a lock (e.g. auto-lock) can
|
// Provision only on success AND while still unlocked: a lock (e.g. auto-lock) can
|
||||||
// land during the blocking fetch, and provisioning then would unlock the chat DB +
|
// land during the blocking fetch, and provisioning then would unlock the chat DB +
|
||||||
// load decrypted history while the wallet is locked. Leaving the flag cleared here
|
// load decrypted history while the wallet is locked. Leaving the flag cleared here
|
||||||
@@ -4451,6 +4455,9 @@ void App::maybeRemindSeedBackup()
|
|||||||
if (!state_.connected || !state_.encryption_state_known) return;
|
if (!state_.connected || !state_.encryption_state_known) return;
|
||||||
if (state_.isLocked()) return; // wait until unlocked to read it
|
if (state_.isLocked()) return; // wait until unlocked to read it
|
||||||
if (seed_backup_reminder_in_flight_) return;
|
if (seed_backup_reminder_in_flight_) return;
|
||||||
|
// An inconclusive answer (an error other than "not derived from a mnemonic" — e.g. a daemon without
|
||||||
|
// the RPC, or a busy one) used to re-fire this probe on the very next frame, hammering the daemon.
|
||||||
|
if (std::chrono::steady_clock::now() < seed_backup_reminder_retry_at_) return;
|
||||||
seed_backup_reminder_in_flight_ = true;
|
seed_backup_reminder_in_flight_ = true;
|
||||||
exportSeedPhrase([this](bool ok, bool noMnemonic, const std::string& /*phrase*/,
|
exportSeedPhrase([this](bool ok, bool noMnemonic, const std::string& /*phrase*/,
|
||||||
const std::string& /*error*/) {
|
const std::string& /*error*/) {
|
||||||
@@ -4460,6 +4467,8 @@ void App::maybeRemindSeedBackup()
|
|||||||
if (ok || noMnemonic) {
|
if (ok || noMnemonic) {
|
||||||
settings_->setSeedBackupReminded(true);
|
settings_->setSeedBackupReminded(true);
|
||||||
settings_->save();
|
settings_->save();
|
||||||
|
} else {
|
||||||
|
seed_backup_reminder_retry_at_ = std::chrono::steady_clock::now() + std::chrono::minutes(5);
|
||||||
}
|
}
|
||||||
if (ok)
|
if (ok)
|
||||||
ui::Notifications::instance().info(TR("seed_backup_reminder"), 12.0f);
|
ui::Notifications::instance().info(TR("seed_backup_reminder"), 12.0f);
|
||||||
|
|||||||
Reference in New Issue
Block a user