1
0

Merge pull request #10419 from SomberNight/202601_qml_wallet_unlocked

qml: QEDaemon.setPassword to restore invariant wallets are unlocked
This commit is contained in:
ghost43
2026-01-19 17:10:21 +00:00
committed by GitHub
3 changed files with 30 additions and 5 deletions

View File

@@ -231,7 +231,7 @@ class QEDaemon(AuthMixin, QObject):
return
if self.daemon.config.WALLET_SHOULD_USE_SINGLE_PASSWORD:
self._use_single_password = self.daemon.update_password_for_directory(old_password=local_password, new_password=local_password)
self._use_single_password = self._update_password_for_directory_and_unlock_wallets(old_password=local_password, new_password=local_password)
if not self._use_single_password and self.daemon.config.WALLET_ANDROID_USE_BIOMETRIC_AUTHENTICATION:
# we need to disable biometric auth if the user creates wallets with different passwords as
# we only store one encrypted password which is not associated to a specific wallet
@@ -399,11 +399,24 @@ class QEDaemon(AuthMixin, QObject):
def setPassword(self, password):
assert self._use_single_password
assert password
if not self.daemon.update_password_for_directory(old_password=self._password, new_password=password):
if not self._update_password_for_directory_and_unlock_wallets(old_password=self._password, new_password=password):
return False
self._password = password
return True
def _update_password_for_directory_and_unlock_wallets(self, *, old_password, new_password):
# note: this assumes all wallet files are in a single directory.
# change wallet passwords:
ret = self.daemon.update_password_for_directory(old_password=old_password, new_password=new_password)
# If some wallets just had their password changed, they got "locked" by wallet.update_password().
# If the password is not unified yet, other loaded wallets might still be unlocked.
# restore the invariant that all loaded wallets in qml must be unlocked:
for w in self.daemon.get_wallets().values():
if not w.is_unlocked():
w.unlock(new_password)
assert w.is_unlocked()
return ret
@pyqtProperty(QENewWalletWizard, notify=newWalletWizardChanged)
def newWalletWizard(self):
if not self._new_wallet_wizard:

View File

@@ -765,6 +765,7 @@ class QEWallet(AuthMixin, QObject, QtEventListener):
try:
self._logger.info('setting new password')
self.wallet.update_password(current_password, password, encrypt_storage=True)
# restore the invariant that all loaded wallets in qml must be unlocked:
self.wallet.unlock(password)
return True
except InvalidPassword as e:

View File

@@ -3532,16 +3532,27 @@ class Abstract_Wallet(ABC, Logger, EventListener):
"""Returns the number of new addresses we generated."""
return 0
def unlock(self, password):
def unlock(self, password: Optional[str]) -> None:
self.logger.info(f'unlocking wallet')
password = password or None
self.check_password(password)
self._password_in_memory = password
def lock_wallet(self):
self._password_in_memory = None
def get_unlocked_password(self):
return self._password_in_memory
def get_unlocked_password(self) -> Optional[str]:
pw = self._password_in_memory
if not self.is_unlocked():
return None
try:
self.check_password(pw)
except InvalidPassword as e:
raise Exception("inconsistent _password_in_memory") from e
return pw
def is_unlocked(self) -> bool:
return self._password_in_memory is not None or not self.has_password()
def get_text_not_enough_funds_mentioning_frozen(
self,