From 16ed48d52df28764fa52af2da53d8f67e9a13138 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Wed, 31 Aug 2016 13:50:46 +0200 Subject: [PATCH] Format upgrade: increment seed_version to make sure that old versions of Electrum refuse to open new wallet files. --- lib/storage.py | 34 +++++++++++++++++----------------- lib/version.py | 5 ++++- lib/wallet.py | 5 ++--- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/lib/storage.py b/lib/storage.py index 1d52bb653..c8ce8038f 100644 --- a/lib/storage.py +++ b/lib/storage.py @@ -37,7 +37,7 @@ from i18n import _ from util import NotEnoughFunds, PrintError, profiler from plugins import run_hook, plugin_loaders from keystore import bip44_derivation -from version import OLD_SEED_VERSION +from version import * def multisig_type(wallet_type): @@ -127,6 +127,8 @@ class WalletStorage(PrintError): self.data.pop(key) def write(self): + # this ensures that previous versions of electrum won't open the wallet + self.put('seed_version', FINAL_SEED_VERSION) with self.lock: self._write() self.file_exists = True @@ -206,23 +208,18 @@ class WalletStorage(PrintError): return result def requires_upgrade(self): - r = False - if self.file_exists: - r |= self.convert_wallet_type(True) - r |= self.convert_imported(True) - return r + return self.file_exists and self.get_seed_version() != FINAL_SEED_VERSION def upgrade(self): - self.convert_imported(False) - self.convert_wallet_type(False) + self.convert_imported() + self.convert_wallet_type() + self.convert_account() self.write() - def convert_wallet_type(self, is_test): + def convert_wallet_type(self): wallet_type = self.get('wallet_type') if self.get('keystore') or self.get('x1/') or wallet_type=='imported': return False - if is_test: - return True assert not self.requires_split() seed_version = self.get_seed_version() seed = self.get('seed') @@ -293,14 +290,11 @@ class WalletStorage(PrintError): self.put('keypairs', None) self.put('key_type', None) - - def convert_imported(self, test): + def convert_imported(self): # '/x' is the internal ID for imported accounts d = self.get('accounts', {}).get('/x', {}).get('imported',{}) if not d: return False - if test: - return True addresses = [] keypairs = {} for addr, v in d.items(): @@ -322,6 +316,13 @@ class WalletStorage(PrintError): else: raise BaseException('no addresses or privkeys') + def convert_account(self): + d = self.get('accounts', {}).get('0', {}) + if not d: + return False + self.put('accounts', None) + self.put('pubkeys', d) + def get_action(self): action = run_hook('get_action', self) if action: @@ -330,11 +331,10 @@ class WalletStorage(PrintError): return 'new' def get_seed_version(self): - from version import OLD_SEED_VERSION, NEW_SEED_VERSION seed_version = self.get('seed_version') if not seed_version: seed_version = OLD_SEED_VERSION if len(self.get('master_public_key','')) == 128 else NEW_SEED_VERSION - if seed_version not in [OLD_SEED_VERSION, NEW_SEED_VERSION]: + if seed_version not in [OLD_SEED_VERSION, NEW_SEED_VERSION, FINAL_SEED_VERSION]: msg = "Your wallet has an unsupported seed version." msg += '\n\nWallet file: %s' % os.path.abspath(self.path) if seed_version in [5, 7, 8, 9, 10]: diff --git a/lib/version.py b/lib/version.py index b71278f95..28454428a 100644 --- a/lib/version.py +++ b/lib/version.py @@ -1,7 +1,10 @@ ELECTRUM_VERSION = '2.7.0' # version of the client package PROTOCOL_VERSION = '0.10' # protocol version requested -NEW_SEED_VERSION = 11 # electrum versions >= 2.0 + OLD_SEED_VERSION = 4 # electrum versions < 2.0 +NEW_SEED_VERSION = 11 # electrum versions >= 2.0 +FINAL_SEED_VERSION = 12 # electrum >= 2.7 will set this to prevent + # old versions from overwriting new format # The hash of the mnemonic seed must begin with this diff --git a/lib/wallet.py b/lib/wallet.py index 32ea11ca0..82d6a2404 100644 --- a/lib/wallet.py +++ b/lib/wallet.py @@ -209,11 +209,10 @@ class Abstract_Wallet(PrintError): return os.path.basename(self.storage.path) def save_pubkeys(self): - # this name is inherited from old multi-account wallets - self.storage.put('accounts', {'0': {'receiving':self.receiving_pubkeys, 'change':self.change_pubkeys}}) + self.storage.put('pubkeys', {'receiving':self.receiving_pubkeys, 'change':self.change_pubkeys}) def load_addresses(self): - d = self.storage.get('accounts', {}).get('0', {}) + d = self.storage.get('pubkeys', {}) self.receiving_pubkeys = d.get('receiving', []) self.change_pubkeys = d.get('change', []) self.receiving_addresses = map(self.pubkeys_to_address, self.receiving_pubkeys)