From 08f083c5d982c75d775ad3b7ae97c90b99185bec Mon Sep 17 00:00:00 2001 From: Victor Shyba <victor.shyba@gmail.com> Date: Thu, 29 Oct 2020 19:10:08 -0300 Subject: [PATCH] recover invalid state described on #3026 --- lbry/wallet/wallet.py | 11 ++++++--- tests/unit/wallet/test_wallet.py | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/lbry/wallet/wallet.py b/lbry/wallet/wallet.py index 0c021af1f..61dede67b 100644 --- a/lbry/wallet/wallet.py +++ b/lbry/wallet/wallet.py @@ -145,14 +145,15 @@ class Wallet: elif not self.is_locked: log.warning( "Disk encryption requested but no password available for encryption. " - "Saving wallet in an unencrypted state." + "Resetting encryption preferences and saving wallet in an unencrypted state." ) + self.preferences[ENCRYPT_ON_DISK] = False return self.storage.write(self.to_dict()) @property def hash(self) -> bytes: h = sha256() - if self.preferences.get(ENCRYPT_ON_DISK, False): + if self.is_encrypted: assert self.encryption_password is not None, \ "Encryption is enabled but no password is available, cannot generate hash." h.update(self.encryption_password.encode()) @@ -219,7 +220,11 @@ class Wallet: @property def is_encrypted(self) -> bool: - return self.is_locked or self.preferences.get(ENCRYPT_ON_DISK, False) + # either its locked or it was unlocked using a password. + # if its set to encrypt on preferences but isnt encrypted and no password was given so far, + # then its not encrypted + return self.is_locked or ( + self.preferences.get(ENCRYPT_ON_DISK, False) and self.encryption_password is not None) def decrypt(self): assert not self.is_locked, "Cannot decrypt a locked wallet, unlock first." diff --git a/tests/unit/wallet/test_wallet.py b/tests/unit/wallet/test_wallet.py index 0cdfaa767..c2bc99812 100644 --- a/tests/unit/wallet/test_wallet.py +++ b/tests/unit/wallet/test_wallet.py @@ -74,6 +74,48 @@ class TestWalletCreation(AsyncioTestCase): decrypted = Wallet.unpack('password', encrypted) self.assertEqual(decrypted['accounts'][0]['name'], 'An Account') + def test_no_password_but_encryption_preferred(self): + wallet_dict = { + 'version': 1, + 'name': 'Main Wallet', + 'preferences': { + "encrypt-on-disk": { + "ts": 1571762543.351794, + "value": True + }, + }, + 'accounts': [ + { + 'certificates': {}, + 'name': 'An Account', + 'ledger': 'lbc_mainnet', + 'modified_on': 123, + 'seed': + "carbon smart garage balance margin twelve chest sword toast envelope bottom stomac" + "h absent", + 'encrypted': False, + 'private_key': + 'xprv9s21ZrQH143K42ovpZygnjfHdAqSd9jo7zceDfPRogM7bkkoNVv7' + 'DRNLEoB8HoirMgH969NrgL8jNzLEegqFzPRWM37GXd4uE8uuRkx4LAe', + 'public_key': + 'xpub661MyMwAqRbcGWtPvbWh9sc2BCfw2cTeVDYF23o3N1t6UZ5wv3EMm' + 'Dgp66FxHuDtWdft3B5eL5xQtyzAtkdmhhC95gjRjLzSTdkho95asu9', + 'address_generator': { + 'name': 'deterministic-chain', + 'receiving': {'gap': 17, 'maximum_uses_per_address': 3}, + 'change': {'gap': 10, 'maximum_uses_per_address': 3} + } + } + ] + } + + storage = WalletStorage(default=wallet_dict) + wallet = Wallet.from_storage(storage, self.manager) + self.assertEqual( + hexlify(wallet.hash), b'8cc6341885e6ad46f72a17364c65f8441f09e79996c55202196b399c75f8d751' + ) + self.assertFalse(wallet.is_encrypted) + def test_read_write(self): manager = WalletManager() config = {'data_path': '/tmp/wallet'}