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'}