Only remove database log files on shutdown after wallet encryption/rewrite
[novacoin.git] / src / wallet.cpp
index 3ed880f..87882a3 100644 (file)
@@ -187,10 +187,15 @@ bool CWallet::EncryptWallet(const string& strWalletPassphrase)
         }
 
         Lock();
-    }
+        Unlock(strWalletPassphrase);
+        NewKeyPool();
+        Lock();
 
-    if (Resilver(strWalletFile))
-        CWalletDB(strWalletFile, "r+").WriteSetting("fIsResilvered", true);
+        // Need to completely rewrite the wallet file; if we don't, bdb might keep
+        // bits of the unencrypted private key in slack space in the database file.
+        if (CDB::Rewrite(strWalletFile))
+            RemoveLogFilesOnShutdown(true);
+    }
 
     return true;
 }
@@ -1145,11 +1150,17 @@ int CWallet::LoadWallet(bool& fFirstRunRet)
         return false;
     fFirstRunRet = false;
     int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
-    if (nLoadWalletRet == DB_NEED_RESILVER)
+    if (nLoadWalletRet == DB_NEED_REWRITE)
     {
-        if (Resilver(strWalletFile))
-            CWalletDB(strWalletFile, "r+").WriteSetting("fIsResilvered", true);
-        nLoadWalletRet = DB_LOAD_OK;
+        if (CDB::Rewrite(strWalletFile, "\x04pool"))
+        {
+            RemoveLogFilesOnShutdown(true);
+            setKeyPool.clear();
+            // Note: can't top-up keypool here, because wallet is locked.
+            // User will be prompted to unlock wallet the next operation
+            // the requires a new key.
+        }
+        nLoadWalletRet = DB_NEED_REWRITE;
     }
 
     if (nLoadWalletRet != DB_LOAD_OK)
@@ -1237,6 +1248,34 @@ bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
     return true;
 }
 
+//
+// Mark old keypool keys as used,
+// and generate all new keys
+//
+bool CWallet::NewKeyPool()
+{
+    CRITICAL_BLOCK(cs_wallet)
+    {
+        CWalletDB walletdb(strWalletFile);
+        BOOST_FOREACH(int64 nIndex, setKeyPool)
+            walletdb.ErasePool(nIndex);
+        setKeyPool.clear();
+
+        if (IsLocked())
+            return false;
+
+        int64 nKeys = max(GetArg("-keypool", 100), (int64)0);
+        for (int i = 0; i < nKeys; i++)
+        {
+            int64 nIndex = i+1;
+            walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
+            setKeyPool.insert(nIndex);
+        }
+        printf("CWallet::NewKeyPool wrote %"PRI64d" new keys\n", nKeys);
+    }
+    return true;
+}
+
 bool CWallet::TopUpKeyPool()
 {
     CRITICAL_BLOCK(cs_wallet)