Merge #20490: [backport] wallet: upgradewallet fixes, improvements, test coverage

ca8cd893bb wallet: fix and improve upgradewallet error responses (Jon Atack)
99d56e3571 wallet: fix and improve upgradewallet result responses (Jon Atack)
2498b04ce8 Don't upgrade to HD split if it is already supported (Andrew Chow)
c46c18b788 wallet: refactor GetClosestWalletFeature() (Jon Atack)

Pull request description:

  Github-Pull: #20403
  Rebased-From: c46c18b788

  Github-Pull: #20403
  Rebased-From: 2498b04ce8

  Github-Pull: #20403
  Rebased-From: 99d56e3571

  Github-Pull: #20403
  Rebased-From: ca8cd893bb

Top commit has no ACKs.

Tree-SHA512: b18a1d015c963298740c585385eaa056988464112c88a519fe619be22dc78a8f6a102365cf799c50b781a77a09bec82b58ce411ab007b48f8b5de876e9c75060
This commit is contained in:
MarcoFalke
2020-11-25 18:03:39 +01:00
4 changed files with 74 additions and 50 deletions

View File

@@ -4239,7 +4239,7 @@ static RPCHelpMan sethdseed()
// Do not do anything to non-HD wallets
if (!pwallet->CanSupportFeature(FEATURE_HD)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot set a HD seed on a non-HD wallet. Use the upgradewallet RPC in order to upgrade a non-HD wallet to HD");
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot set an HD seed on a non-HD wallet. Use the upgradewallet RPC in order to upgrade a non-HD wallet to HD");
}
EnsureWalletIsUnlocked(pwallet);
@@ -4470,14 +4470,18 @@ static RPCHelpMan walletcreatefundedpsbt()
static RPCHelpMan upgradewallet()
{
return RPCHelpMan{"upgradewallet",
"\nUpgrade the wallet. Upgrades to the latest version if no version number is specified\n"
"\nUpgrade the wallet. Upgrades to the latest version if no version number is specified.\n"
"New keys may be generated and a new wallet backup will need to be made.",
{
{"version", RPCArg::Type::NUM, /* default */ strprintf("%d", FEATURE_LATEST), "The version number to upgrade to. Default is the latest wallet version"}
{"version", RPCArg::Type::NUM, /* default */ strprintf("%d", FEATURE_LATEST), "The version number to upgrade to. Default is the latest wallet version."}
},
RPCResult{
RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR, "wallet_name", "Name of wallet this operation was performed on"},
{RPCResult::Type::NUM, "previous_version", "Version of wallet before this operation"},
{RPCResult::Type::NUM, "current_version", "Version of wallet after this operation"},
{RPCResult::Type::STR, "result", /* optional */ true, "Description of result, if no error"},
{RPCResult::Type::STR, "error", /* optional */ true, "Error message (if there is one)"}
},
},
@@ -4500,11 +4504,27 @@ static RPCHelpMan upgradewallet()
version = request.params[0].get_int();
}
bilingual_str error;
if (!pwallet->UpgradeWallet(version, error)) {
throw JSONRPCError(RPC_WALLET_ERROR, error.original);
const int previous_version{pwallet->GetVersion()};
const bool wallet_upgraded{pwallet->UpgradeWallet(version, error)};
const int current_version{pwallet->GetVersion()};
std::string result;
if (wallet_upgraded) {
if (previous_version == current_version) {
result = "Already at latest version. Wallet version unchanged.";
} else {
result = strprintf("Wallet upgraded successfully from version %i to version %i.", previous_version, current_version);
}
}
UniValue obj(UniValue::VOBJ);
if (!error.empty()) {
obj.pushKV("wallet_name", pwallet->GetName());
obj.pushKV("previous_version", previous_version);
obj.pushKV("current_version", current_version);
if (!result.empty()) {
obj.pushKV("result", result);
} else {
CHECK_NONFATAL(!error.empty());
obj.pushKV("error", error.original);
}
return obj;

View File

@@ -453,7 +453,7 @@ bool LegacyScriptPubKeyMan::Upgrade(int prev_version, int new_version, bilingual
hd_upgrade = true;
}
// Upgrade to HD chain split if necessary
if (IsFeatureSupported(new_version, FEATURE_HD_SPLIT)) {
if (!IsFeatureSupported(prev_version, FEATURE_HD_SPLIT) && IsFeatureSupported(new_version, FEATURE_HD_SPLIT)) {
WalletLogPrintf("Upgrading wallet to use HD chain split\n");
m_storage.SetMinVersion(FEATURE_PRE_SPLIT_KEYPOOL);
split_upgrade = FEATURE_HD_SPLIT > prev_version;

View File

@@ -87,13 +87,9 @@ bool IsFeatureSupported(int wallet_version, int feature_version)
WalletFeature GetClosestWalletFeature(int version)
{
if (version >= FEATURE_LATEST) return FEATURE_LATEST;
if (version >= FEATURE_PRE_SPLIT_KEYPOOL) return FEATURE_PRE_SPLIT_KEYPOOL;
if (version >= FEATURE_NO_DEFAULT_KEY) return FEATURE_NO_DEFAULT_KEY;
if (version >= FEATURE_HD_SPLIT) return FEATURE_HD_SPLIT;
if (version >= FEATURE_HD) return FEATURE_HD;
if (version >= FEATURE_COMPRPUBKEY) return FEATURE_COMPRPUBKEY;
if (version >= FEATURE_WALLETCRYPT) return FEATURE_WALLETCRYPT;
if (version >= FEATURE_BASE) return FEATURE_BASE;
const std::array<WalletFeature, 8> wallet_features{{FEATURE_LATEST, FEATURE_PRE_SPLIT_KEYPOOL, FEATURE_NO_DEFAULT_KEY, FEATURE_HD_SPLIT, FEATURE_HD, FEATURE_COMPRPUBKEY, FEATURE_WALLETCRYPT, FEATURE_BASE}};
for (const WalletFeature& wf : wallet_features) {
if (version >= wf) return wf;
}
return static_cast<WalletFeature>(0);
}