aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/db.cpp41
-rw-r--r--src/wallet/db.h4
-rw-r--r--src/wallet/rpcwallet.cpp7
-rw-r--r--src/wallet/wallet.cpp5
4 files changed, 49 insertions, 8 deletions
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index 025ae29753..a7bf89c572 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -556,6 +556,7 @@ void BerkeleyBatch::Close()
LOCK(cs_db);
--env->mapFileUseCount[strFile];
}
+ env->m_db_in_use.notify_all();
}
void BerkeleyEnvironment::CloseDb(const std::string& strFile)
@@ -572,6 +573,32 @@ void BerkeleyEnvironment::CloseDb(const std::string& strFile)
}
}
+void BerkeleyEnvironment::ReloadDbEnv()
+{
+ // Make sure that no Db's are in use
+ AssertLockNotHeld(cs_db);
+ std::unique_lock<CCriticalSection> lock(cs_db);
+ m_db_in_use.wait(lock, [this](){
+ for (auto& count : mapFileUseCount) {
+ if (count.second > 0) return false;
+ }
+ return true;
+ });
+
+ std::vector<std::string> filenames;
+ for (auto it : mapDb) {
+ filenames.push_back(it.first);
+ }
+ // Close the individual Db's
+ for (const std::string& filename : filenames) {
+ CloseDb(filename);
+ }
+ // Reset the environment
+ Flush(true); // This will flush and close the environment
+ Reset();
+ Open(true);
+}
+
bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
{
if (database.IsDummy()) {
@@ -697,7 +724,6 @@ void BerkeleyEnvironment::Flush(bool fShutdown)
if (!fMockDb) {
fs::remove_all(fs::path(strPath) / "database");
}
- g_dbenvs.erase(strPath);
}
}
}
@@ -796,6 +822,17 @@ void BerkeleyDatabase::Flush(bool shutdown)
{
if (!IsDummy()) {
env->Flush(shutdown);
- if (shutdown) env = nullptr;
+ if (shutdown) {
+ LOCK(cs_db);
+ g_dbenvs.erase(env->Directory().string());
+ env = nullptr;
+ }
+ }
+}
+
+void BerkeleyDatabase::ReloadDbEnv()
+{
+ if (!IsDummy()) {
+ env->ReloadDbEnv();
}
}
diff --git a/src/wallet/db.h b/src/wallet/db.h
index b078edab7b..467ed13b45 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -38,6 +38,7 @@ public:
std::unique_ptr<DbEnv> dbenv;
std::map<std::string, int> mapFileUseCount;
std::map<std::string, Db*> mapDb;
+ std::condition_variable_any m_db_in_use;
BerkeleyEnvironment(const fs::path& env_directory);
~BerkeleyEnvironment();
@@ -75,6 +76,7 @@ public:
void CheckpointLSN(const std::string& strFile);
void CloseDb(const std::string& strFile);
+ void ReloadDbEnv();
DbTxn* TxnBegin(int flags = DB_TXN_WRITE_NOSYNC)
{
@@ -145,6 +147,8 @@ public:
void IncrementUpdateCounter();
+ void ReloadDbEnv();
+
std::atomic<unsigned int> nUpdateCounter;
unsigned int nLastSeen;
unsigned int nLastFlushed;
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 15f3e5947e..1a2dff9a96 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2121,7 +2121,6 @@ static UniValue encryptwallet(const JSONRPCRequest& request)
"will require the passphrase to be set prior the making these calls.\n"
"Use the walletpassphrase call for this, and then walletlock call.\n"
"If the wallet is already encrypted, use the walletpassphrasechange call.\n"
- "Note that this will shutdown the server.\n"
"\nArguments:\n"
"1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
"\nExamples:\n"
@@ -2159,11 +2158,7 @@ static UniValue encryptwallet(const JSONRPCRequest& request)
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
}
- // BDB seems to have a bad habit of writing old data into
- // slack space in .dat files; that is bad if the old data is
- // unencrypted private keys. So:
- StartShutdown();
- return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup.";
+ return "wallet encrypted; The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup.";
}
static UniValue lockunspent(const JSONRPCRequest& request)
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index f3d6d0056d..7f7a88e986 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -722,6 +722,11 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
// bits of the unencrypted private key in slack space in the database file.
database->Rewrite();
+ // BDB seems to have a bad habit of writing old data into
+ // slack space in .dat files; that is bad if the old data is
+ // unencrypted private keys. So:
+ database->ReloadDbEnv();
+
}
NotifyStatusChanged(this);