diff --git a/electrum/json_db.py b/electrum/json_db.py index b4b56a38d..cb1d8adb7 100644 --- a/electrum/json_db.py +++ b/electrum/json_db.py @@ -27,6 +27,7 @@ import copy import json from . import util +from .util import WalletFileException from .logging import Logger JsonDBJsonEncoder = util.MyEncoder @@ -166,8 +167,20 @@ class JsonDB(Logger): def __init__(self, data): Logger.__init__(self) self.lock = threading.RLock() - self.data = data self._modified = False + # load data + if data: + self.load_data(data) + else: + self.data = {} + + def load_data(self, s): + try: + self.data = json.loads(s) + except Exception: + raise WalletFileException("Cannot read wallet file. (parsing failed)") + if not isinstance(self.data, dict): + raise WalletFileException("Malformed wallet file (not dict)") def set_modified(self, b): with self.lock: @@ -250,3 +263,18 @@ class JsonDB(Logger): else: v = constructor(v) return v + + def write(self, storage: 'WalletStorage'): + with self.lock: + self._write(storage) + + def _write(self, storage: 'WalletStorage'): + if threading.current_thread().daemon: + self.logger.warning('daemon thread cannot write db') + return + if not self.modified(): + return + json_str = self.dump(human_readable=not storage.is_encrypted()) + storage.write(json_str) + self.set_modified(False) + diff --git a/electrum/wallet_db.py b/electrum/wallet_db.py index cf889d453..255faed4a 100644 --- a/electrum/wallet_db.py +++ b/electrum/wallet_db.py @@ -104,21 +104,27 @@ for key in ['locked_in', 'fails', 'settles']: class WalletDB(JsonDB): - def __init__(self, raw, *, manual_upgrades: bool): - JsonDB.__init__(self, {}) - self._manual_upgrades = manual_upgrades - self._called_after_upgrade_tasks = False - if raw: # loading existing db - self.load_data(raw) - self.load_plugins() - else: # creating new db + def __init__(self, data, *, manual_upgrades: bool): + JsonDB.__init__(self, data) + if not data: + # create new DB self.put('seed_version', FINAL_SEED_VERSION) self._add_db_creation_metadata() self._after_upgrade_tasks() + self._manual_upgrades = manual_upgrades + self._called_after_upgrade_tasks = False + if not self._manual_upgrades and self.requires_split(): + raise WalletFileException("This wallet has multiple accounts and must be split") + if not self.requires_upgrade(): + self._after_upgrade_tasks() + elif not self._manual_upgrades: + self.upgrade() + # load plugins that are conditional on wallet type + self.load_plugins() def load_data(self, s): try: - self.data = json.loads(s) + JsonDB.load_data(self, s) except Exception: try: d = ast.literal_eval(s) @@ -137,14 +143,6 @@ class WalletDB(JsonDB): if not isinstance(self.data, dict): raise WalletFileException("Malformed wallet file (not dict)") - if not self._manual_upgrades and self.requires_split(): - raise WalletFileException("This wallet has multiple accounts and must be split") - - if not self.requires_upgrade(): - self._after_upgrade_tasks() - elif not self._manual_upgrades: - self.upgrade() - def requires_split(self): d = self.get('accounts', {}) return len(d) > 1 @@ -1583,21 +1581,6 @@ class WalletDB(JsonDB): return False return True - def write(self, storage: 'WalletStorage'): - with self.lock: - self._write(storage) - - @profiler - def _write(self, storage: 'WalletStorage'): - if threading.current_thread().daemon: - self.logger.warning('daemon thread cannot write db') - return - if not self.modified(): - return - json_str = self.dump(human_readable=not storage.is_encrypted()) - storage.write(json_str) - self.set_modified(False) - def is_ready_to_be_used_by_wallet(self): return not self.requires_upgrade() and self._called_after_upgrade_tasks