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
This commit is contained in:
Andrew Chow 2018-03-31 13:37:27 -04:00
parent 2bcf2b52ae
commit 5c50e93d52
2 changed files with 31 additions and 2 deletions

View file

@ -4025,6 +4025,35 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
walletInstance->SetMaxVersion(nMaxVersion); 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) if (fFirstRun)
{ {
// ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key // 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)); InitError(strprintf(_("Error creating %s: You can't create non-HD wallets with this version."), walletFile));
return nullptr; return nullptr;
} }
walletInstance->SetMinVersion(FEATURE_NO_DEFAULT_KEY); walletInstance->SetMinVersion(FEATURE_LATEST);
// generate a new master key // generate a new master key
CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey();

View file

@ -89,7 +89,7 @@ enum WalletFeature
FEATURE_NO_DEFAULT_KEY = 159900, // Wallet without a default key written 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 { enum class OutputType {