diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/wallet.cpp | 53 | ||||
-rw-r--r-- | src/wallet/wallet.h | 6 |
2 files changed, 59 insertions, 0 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index dd33109267..44b416d496 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -18,6 +18,7 @@ #include <assert.h> #include <boost/algorithm/string/replace.hpp> +#include <boost/filesystem.hpp> #include <boost/thread.hpp> using namespace std; @@ -339,6 +340,58 @@ set<uint256> CWallet::GetConflicts(const uint256& txid) const return result; } +void CWallet::Flush(bool shutdown) +{ + bitdb.Flush(shutdown); +} + +bool CWallet::Verify(const string walletFile, string& warningString, string& errorString) +{ + if (!bitdb.Open(GetDataDir())) + { + // try moving the database env out of the way + boost::filesystem::path pathDatabase = GetDataDir() / "database"; + boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime()); + try { + boost::filesystem::rename(pathDatabase, pathDatabaseBak); + LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); + } catch (const boost::filesystem::filesystem_error&) { + // failure is ok (well, not really, but it's not worse than what we started with) + } + + // try again + if (!bitdb.Open(GetDataDir())) { + // if it still fails, it probably means we can't even create the database env + string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir()); + errorString += msg; + return true; + } + } + + if (GetBoolArg("-salvagewallet", false)) + { + // Recover readable keypairs: + if (!CWalletDB::Recover(bitdb, walletFile, true)) + return false; + } + + if (boost::filesystem::exists(GetDataDir() / walletFile)) + { + CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); + if (r == CDBEnv::RECOVER_OK) + { + warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!" + " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if" + " your balance or transactions are incorrect you should" + " restore from a backup."), GetDataDir()); + } + if (r == CDBEnv::RECOVER_FAIL) + errorString += _("wallet.dat corrupt, salvage failed"); + } + + return true; +} + void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range) { // We want all the wallet transactions in range to have the same metadata as diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b2973250a4..1a9feff9f3 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -743,6 +743,12 @@ public: //! Get wallet transactions that conflict with given transaction (spend same outputs) std::set<uint256> GetConflicts(const uint256& txid) const; + //! Flush wallet (bitdb flush) + void Flush(bool shutdown=false); + + //! Verify the wallet database and perform salvage if required + static bool Verify(const std::string walletFile, std::string& warningString, std::string& errorString); + /** * Address book entry changed. * @note called with lock cs_wallet held. |