wallet: Include actual backup filename in recovery warning message

This commit is contained in:
Luke Dashjr 2017-06-05 22:01:48 +00:00
parent 84dcb45017
commit b823a4c9f6
5 changed files with 20 additions and 17 deletions

View file

@ -143,7 +143,7 @@ void CDBEnv::MakeMock()
fMockDb = true; fMockDb = true;
} }
CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFunc)(const std::string& strFile)) CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type recoverFunc, std::string& out_backup_filename)
{ {
LOCK(cs_db); LOCK(cs_db);
assert(mapFileUseCount.count(strFile) == 0); assert(mapFileUseCount.count(strFile) == 0);
@ -156,11 +156,11 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, bool (*recoverFu
return RECOVER_FAIL; return RECOVER_FAIL;
// Try to recover: // Try to recover:
bool fRecovered = (*recoverFunc)(strFile); bool fRecovered = (*recoverFunc)(strFile, out_backup_filename);
return (fRecovered ? RECOVER_OK : RECOVER_FAIL); return (fRecovered ? RECOVER_OK : RECOVER_FAIL);
} }
bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue)) bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename)
{ {
// Recovery procedure: // Recovery procedure:
// move wallet file to wallet.timestamp.bak // move wallet file to wallet.timestamp.bak
@ -170,7 +170,7 @@ bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*reco
// Set -rescan so any missing transactions will be // Set -rescan so any missing transactions will be
// found. // found.
int64_t now = GetTime(); int64_t now = GetTime();
std::string newFilename = strprintf("wallet.%d.bak", now); newFilename = strprintf("wallet.%d.bak", now);
int result = bitdb.dbenv->dbrename(NULL, filename.c_str(), NULL, int result = bitdb.dbenv->dbrename(NULL, filename.c_str(), NULL,
newFilename.c_str(), DB_AUTO_COMMIT); newFilename.c_str(), DB_AUTO_COMMIT);
@ -261,18 +261,19 @@ bool CDB::VerifyEnvironment(const std::string& walletFile, const fs::path& dataD
return true; return true;
} }
bool CDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, bool (*recoverFunc)(const std::string& strFile)) bool CDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc)
{ {
if (fs::exists(dataDir / walletFile)) if (fs::exists(dataDir / walletFile))
{ {
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, recoverFunc); std::string backup_filename;
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, recoverFunc, backup_filename);
if (r == CDBEnv::RECOVER_OK) if (r == CDBEnv::RECOVER_OK)
{ {
warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!" warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!"
" Original %s saved as %s in %s; if" " Original %s saved as %s in %s; if"
" your balance or transactions are incorrect you should" " your balance or transactions are incorrect you should"
" restore from a backup."), " restore from a backup."),
walletFile, "wallet.{timestamp}.bak", dataDir); walletFile, backup_filename, dataDir);
} }
if (r == CDBEnv::RECOVER_FAIL) if (r == CDBEnv::RECOVER_FAIL)
{ {

View file

@ -55,7 +55,8 @@ public:
enum VerifyResult { VERIFY_OK, enum VerifyResult { VERIFY_OK,
RECOVER_OK, RECOVER_OK,
RECOVER_FAIL }; RECOVER_FAIL };
VerifyResult Verify(const std::string& strFile, bool (*recoverFunc)(const std::string& strFile)); typedef bool (*recoverFunc_type)(const std::string& strFile, std::string& out_backup_filename);
VerifyResult Verify(const std::string& strFile, recoverFunc_type recoverFunc, std::string& out_backup_filename);
/** /**
* Salvage data from a file that Verify says is bad. * Salvage data from a file that Verify says is bad.
* fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation). * fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation).
@ -156,7 +157,7 @@ public:
void Flush(); void Flush();
void Close(); void Close();
static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue)); static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename);
/* flush the wallet passively (TRY_LOCK) /* flush the wallet passively (TRY_LOCK)
ideal to be called periodically */ ideal to be called periodically */
@ -164,7 +165,7 @@ public:
/* verifies the database environment */ /* verifies the database environment */
static bool VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr); static bool VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr);
/* verifies the database file */ /* verifies the database file */
static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, bool (*recoverFunc)(const std::string& strFile)); static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc);
private: private:
CDB(const CDB&); CDB(const CDB&);

View file

@ -459,7 +459,8 @@ bool CWallet::Verify()
{ {
// Recover readable keypairs: // Recover readable keypairs:
CWallet dummyWallet; CWallet dummyWallet;
if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter)) std::string backup_filename;
if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename))
return false; return false;
} }

View file

@ -783,16 +783,16 @@ void MaybeCompactWalletDB()
// //
// Try to (very carefully!) recover wallet file if there is a problem. // Try to (very carefully!) recover wallet file if there is a problem.
// //
bool CWalletDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue)) bool CWalletDB::Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename)
{ {
return CDB::Recover(filename, callbackDataIn, recoverKVcallback); return CDB::Recover(filename, callbackDataIn, recoverKVcallback, out_backup_filename);
} }
bool CWalletDB::Recover(const std::string& filename) bool CWalletDB::Recover(const std::string& filename, std::string& out_backup_filename)
{ {
// recover without a key filter callback // recover without a key filter callback
// results in recovering all record types // results in recovering all record types
return CWalletDB::Recover(filename, NULL, NULL); return CWalletDB::Recover(filename, NULL, NULL, out_backup_filename);
} }
bool CWalletDB::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue) bool CWalletDB::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)

View file

@ -218,9 +218,9 @@ public:
DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx); DBErrors ZapWalletTx(std::vector<CWalletTx>& vWtx);
DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut); DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut);
/* Try to (very carefully!) recover wallet database (with a possible key type filter) */ /* Try to (very carefully!) recover wallet database (with a possible key type filter) */
static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue)); static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename);
/* Recover convenience-function to bypass the key filter callback, called when verify fails, recovers everything */ /* Recover convenience-function to bypass the key filter callback, called when verify fails, recovers everything */
static bool Recover(const std::string& filename); static bool Recover(const std::string& filename, std::string& out_backup_filename);
/* Recover filter (used as callback), will only let keys (cryptographical keys) as KV/key-type pass through */ /* Recover filter (used as callback), will only let keys (cryptographical keys) as KV/key-type pass through */
static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue); static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue);
/* Function to determine if a certain KV/key-type is a key (cryptographical key) type */ /* Function to determine if a certain KV/key-type is a key (cryptographical key) type */