Merge pull request #5342 from LarryRuane/2021-10-wallet-network-info-error

better wallet network info error handling
This commit is contained in:
Marshall Gaucher 2021-10-15 18:12:44 -07:00 committed by GitHub
commit d6fc064018
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 19 deletions

View File

@ -138,9 +138,15 @@ TEST(WalletTests, WalletNetworkSerialization) {
// create a new testnet wallet and generate a seed
CWallet wallet(Params(), "wallet.dat");
wallet.InitLoadWallet(Params(), true);
wallet.GenerateNewSeed();
wallet.Flush();
// Stay on TESTNET, make sure wallet can be successfully loaded.
{
CWallet restored(Params(), "wallet.dat");
bool fFirstRunRet;
EXPECT_EQ(restored.LoadWallet(fFirstRunRet), DB_LOAD_OK);
}
// now, switch to mainnet and attempt to restore the wallet
// using the same wallet.dat
SelectParams(CBaseChainParams::MAIN);
@ -148,7 +154,7 @@ TEST(WalletTests, WalletNetworkSerialization) {
// load should fail due to being associated with the wrong network
bool fFirstRunRet;
EXPECT_NE(restored.LoadWallet(fFirstRunRet), DB_LOAD_OK);
EXPECT_EQ(restored.LoadWallet(fFirstRunRet), DB_WRONG_NETWORK);
}
TEST(WalletTests, SproutNoteDataSerialisation) {

View File

@ -2295,17 +2295,11 @@ void CWallet::SetHDChain(const CHDChain& chain, bool memonly)
hdChain = chain;
}
void CWallet::CheckNetworkInfo(std::pair<std::string, std::string> readNetworkInfo)
bool CWallet::CheckNetworkInfo(std::pair<std::string, std::string> readNetworkInfo)
{
LOCK(cs_wallet);
std::pair<string, string> networkInfo(PACKAGE_NAME, networkIdString);
if (readNetworkInfo != networkInfo)
throw std::runtime_error(
strprintf("%s: this wallet is for a different network (%s, %s) than the node is configured for (%s, %s)",
std::string(__func__),
readNetworkInfo.first, readNetworkInfo.second,
networkInfo.first, networkInfo.second)
);
return readNetworkInfo == networkInfo;
}
uint32_t CWallet::BIP44CoinType() {
@ -4761,6 +4755,10 @@ bool CWallet::InitLoadWallet(const CChainParams& params, bool clearWitnessCaches
{
return UIError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)));
}
else if (nLoadWalletRet == DB_WRONG_NETWORK)
{
return UIError(strprintf(_("Wallet %s is not for %s %s network"), walletFile, _(PACKAGE_NAME), params.NetworkIDString()));
}
else
return UIError(strprintf(_("Error loading %s"), walletFile));
}

View File

@ -1296,7 +1296,7 @@ public:
void SetHDChain(const CHDChain& chain, bool memonly);
const CHDChain& GetHDChain() const { return hdChain; }
void CheckNetworkInfo(std::pair<std::string, std::string> networkInfo);
bool CheckNetworkInfo(std::pair<std::string, std::string> networkInfo);
uint32_t BIP44CoinType();
/* Set the current HD seed, without saving it to disk (used by LoadWallet) */

View File

@ -728,7 +728,10 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
{
std::pair<std::string, std::string> networkInfo;
ssValue >> networkInfo;
pwallet->CheckNetworkInfo(networkInfo);
if (!pwallet->CheckNetworkInfo(networkInfo)) {
strErr = "Error in wallet database: unexpected network";
return false;
}
}
} catch (...)
{
@ -790,17 +793,19 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
string strType, strErr;
if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr))
{
// losing keys is considered a catastrophic error, anything else
// we assume the user can live with:
if (IsKeyType(strType))
if (strType == "networkinfo") {
// example: running mainnet, but this wallet.dat is from testnet
result = DB_WRONG_NETWORK;
} else if (result != DB_WRONG_NETWORK && IsKeyType(strType)) {
// losing keys is considered a catastrophic error
result = DB_CORRUPT;
else
{
} else {
// Leave other errors alone, if we try to fix them we might make things worse.
fNoncriticalErrors = true; // ... but do warn the user there is something wrong.
if (strType == "tx")
if (strType == "tx") {
// Rescan if there is a bad transaction record:
SoftSetBoolArg("-rescan", true);
}
}
}
if (!strErr.empty())

View File

@ -37,7 +37,8 @@ enum DBErrors
DB_NONCRITICAL_ERROR,
DB_TOO_NEW,
DB_LOAD_FAIL,
DB_NEED_REWRITE
DB_NEED_REWRITE,
DB_WRONG_NETWORK,
};
/* simple hd chain data model */