aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/init.cpp57
-rw-r--r--src/wallet/wallet.cpp53
-rw-r--r--src/wallet/wallet.h6
3 files changed, 72 insertions, 44 deletions
diff --git a/src/init.cpp b/src/init.cpp
index a930a97a94..95ec45015f 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -24,7 +24,6 @@
#include "util.h"
#include "utilmoneystr.h"
#ifdef ENABLE_WALLET
-#include "wallet/db.h"
#include "wallet/wallet.h"
#include "wallet/walletdb.h"
#endif
@@ -151,7 +150,7 @@ void Shutdown()
StopRPCThreads();
#ifdef ENABLE_WALLET
if (pwalletMain)
- bitdb.Flush(false);
+ pwalletMain->Flush(false);
GenerateBitcoins(false, NULL, 0);
#endif
StopNode();
@@ -184,7 +183,7 @@ void Shutdown()
}
#ifdef ENABLE_WALLET
if (pwalletMain)
- bitdb.Flush(true);
+ pwalletMain->Flush(true);
#endif
#ifndef WIN32
boost::filesystem::remove(GetPidFile());
@@ -852,47 +851,17 @@ bool AppInit2(boost::thread_group& threadGroup)
LogPrintf("Using wallet %s\n", strWalletFile);
uiInterface.InitMessage(_("Verifying wallet..."));
- 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!"), strDataDir);
- return InitError(msg);
- }
- }
-
- if (GetBoolArg("-salvagewallet", false))
- {
- // Recover readable keypairs:
- if (!CWalletDB::Recover(bitdb, strWalletFile, true))
- return false;
- }
-
- if (boost::filesystem::exists(GetDataDir() / strWalletFile))
- {
- CDBEnv::VerifyResult r = bitdb.Verify(strWalletFile, CWalletDB::Recover);
- if (r == CDBEnv::RECOVER_OK)
- {
- string msg = 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."), strDataDir);
- InitWarning(msg);
- }
- if (r == CDBEnv::RECOVER_FAIL)
- return InitError(_("wallet.dat corrupt, salvage failed"));
- }
+ std::string warningString;
+ std::string errorString;
+
+ if (!CWallet::Verify(strWalletFile, warningString, errorString))
+ return false;
+
+ if (!warningString.empty())
+ InitWarning(warningString);
+ if (!errorString.empty())
+ return InitError(warningString);
+
} // (!fDisableWallet)
#endif // ENABLE_WALLET
// ********************************************************* Step 6: network initialization
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.