fix(security): only a real wrong passphrase counts toward unlock lockout
A failed wallet unlock was always treated as a wrong guess: the lockout counter was bumped and the back-off curve armed no matter why the RPC failed. A busy or warming-up node, a transport timeout, or a wallet that is not actually encrypted would all eat an attempt and could push a user into a lockout without a single mistyped passphrase. The failed call is now classified before it is acted on: - Only the daemon's "passphrase incorrect" error counts as a wrong guess and advances the lockout. - A warming-up or unreachable node, a reply timeout, or a full queue is reported as a transient busy-node condition with no attempt charged. - A "wallet is not encrypted" reply refreshes the local encryption state instead of penalising the user. - Any unknown error surfaces its message without touching the counter. The PIN path got the same treatment: when the vault decrypts correctly but the unlock RPC then fails for a non-credential reason, the attempt is no longer counted. Tests cover the classification of each failure kind. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2705,6 +2705,7 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["sec_unlock_button"] = "Unlock";
|
||||
strings_["sec_not_connected_to_daemon"] = "Not connected to daemon";
|
||||
strings_["sec_unlock_failed_prefix"] = "Unlock failed: ";
|
||||
strings_["sec_unlock_node_busy"] = "The node is busy; try again in a moment.";
|
||||
strings_["sec_incorrect_passphrase_decrypt"] = "Incorrect passphrase";
|
||||
strings_["sec_importing_keys_rescanning"] = "Importing keys & rescanning blockchain — wallet is usable while this runs";
|
||||
strings_["sec_encrypted_backup_suffix"] = "\nEncrypted backup: wallet.dat.encrypted.bak";
|
||||
|
||||
Reference in New Issue
Block a user