From 5c50e93d52c14fc7bc41130cdb1568f2c11e45de Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Sat, 31 Mar 2018 13:37:27 -0400 Subject: [PATCH] Allow -upgradewallet to upgradewallets to HD Changes the maximum upgradewallet version to the latest wallet version number, 159900. Non-HD wallets will be upgraded to use HD derivation. Non HD chain split wallets will be upgraded to HD chain split. If a non-HD wallet is upgraded to HD, the keypool will be entirely regenerated. Since upgradewallet is effectively run during a first run, all of the first run initial setup stuff is combined with the upgrade to HD --- src/wallet/wallet.cpp | 31 ++++++++++++++++++++++++++++++- src/wallet/wallet.h | 2 +- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3ca31ac9eb..57dc6c3b70 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4025,6 +4025,35 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& walletInstance->SetMaxVersion(nMaxVersion); } + // Upgrade to HD if explicit upgrade + if (gArgs.GetBoolArg("-upgradewallet", false)) { + LOCK(walletInstance->cs_wallet); + bool hd_upgrade = false; + if (walletInstance->CanSupportFeature(FEATURE_HD) && !walletInstance->IsHDEnabled()) { + LogPrintf("Upgrading wallet to HD\n"); + walletInstance->SetMinVersion(FEATURE_HD); + + // generate a new master key + CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); + if (!walletInstance->SetHDMasterKey(masterPubKey)) { + throw std::runtime_error(std::string(__func__) + ": Storing master key failed"); + } + hd_upgrade = true; + } + // Upgrade to HD chain split if necessary + if (walletInstance->CanSupportFeature(FEATURE_HD_SPLIT)) { + LogPrintf("Upgrading wallet to use HD chain split\n"); + walletInstance->SetMinVersion(FEATURE_HD_SPLIT); + } + // Regenerate the keypool if upgraded to HD + if (hd_upgrade) { + if (!walletInstance->NewKeyPool()) { + InitError(_("Unable to generate keys") += "\n"); + return nullptr; + } + } + } + if (fFirstRun) { // ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key @@ -4032,7 +4061,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& InitError(strprintf(_("Error creating %s: You can't create non-HD wallets with this version."), walletFile)); return nullptr; } - walletInstance->SetMinVersion(FEATURE_NO_DEFAULT_KEY); + walletInstance->SetMinVersion(FEATURE_LATEST); // generate a new master key CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b6cdf041a8..215145a62b 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -89,7 +89,7 @@ enum WalletFeature FEATURE_NO_DEFAULT_KEY = 159900, // Wallet without a default key written - FEATURE_LATEST = FEATURE_COMPRPUBKEY // HD is optional, use FEATURE_COMPRPUBKEY as latest version + FEATURE_LATEST = FEATURE_NO_DEFAULT_KEY }; enum class OutputType {