Update CWallet::LoadWallet for proper return type.
[novacoin.git] / src / wallet.cpp
index 216ddc4..a60b0b4 100644 (file)
@@ -31,7 +31,13 @@ bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector
         return false;
     if (!fFileBacked)
         return true;
-    return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret);
+    CRITICAL_BLOCK(cs_pwalletdbEncryption)
+    {
+        if (pwalletdbEncryption)
+            return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
+        else
+            return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret);
+    }
 }
 
 bool CWallet::Unlock(const string& strWalletPassphrase)
@@ -102,12 +108,25 @@ bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const
     return false;
 }
 
+
+// This class implements an addrIncoming entry that causes pre-0.4
+// clients to crash on startup if reading a private-key-encrypted wallet.
+class CCorruptAddress
+{
+public:
+    IMPLEMENT_SERIALIZE
+    (
+        if (nType & SER_DISK)
+            READWRITE(nVersion);
+    )
+};
+
 bool CWallet::EncryptWallet(const string& strWalletPassphrase)
 {
-    //TODO: use db commits
     CRITICAL_BLOCK(cs_mapPubKeys)
     CRITICAL_BLOCK(cs_KeyStore)
     CRITICAL_BLOCK(cs_vMasterKey)
+    CRITICAL_BLOCK(cs_pwalletdbEncryption)
     {
         if (IsCrypted())
             return false;
@@ -146,13 +165,28 @@ bool CWallet::EncryptWallet(const string& strWalletPassphrase)
         mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
         if (fFileBacked)
         {
-            DBFlush(false);
-            CWalletDB(strWalletFile).WriteMasterKey(nMasterKeyMaxID, kMasterKey);
-            DBFlush(false);
+            pwalletdbEncryption = new CWalletDB(strWalletFile);
+            pwalletdbEncryption->TxnBegin();
+            pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
         }
 
         if (!EncryptKeys(vMasterKey))
-            exit(1); //We now probably have half of our keys encrypted, and half not...die and let the user ask someone with experience to recover their wallet.
+        {
+            if (fFileBacked)
+                pwalletdbEncryption->TxnAbort();
+            exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet.
+        }
+
+        if (fFileBacked)
+        {
+            CCorruptAddress corruptAddress;
+            pwalletdbEncryption->WriteSetting("addrIncoming", corruptAddress);
+            if (!pwalletdbEncryption->TxnCommit())
+                exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet.
+
+            pwalletdbEncryption->Close();
+            pwalletdbEncryption = NULL;
+        }
 
         Lock();
     }
@@ -688,8 +722,6 @@ void CWallet::ResendWalletTransactions()
 
 int64 CWallet::GetBalance() const
 {
-    int64 nStart = GetTimeMillis();
-
     int64 nTotal = 0;
     CRITICAL_BLOCK(cs_mapWallet)
     {
@@ -702,7 +734,6 @@ int64 CWallet::GetBalance() const
         }
     }
 
-    //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart);
     return nTotal;
 }
 
@@ -1091,13 +1122,14 @@ string CWallet::SendMoneyToBitcoinAddress(string strAddress, int64 nValue, CWall
 
 
 
-bool CWallet::LoadWallet(bool& fFirstRunRet)
+int CWallet::LoadWallet(bool& fFirstRunRet)
 {
     if (!fFileBacked)
         return false;
     fFirstRunRet = false;
-    if (!CWalletDB(strWalletFile,"cr+").LoadWallet(this))
-        return false;
+    int nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
+    if (nLoadWalletRet != DB_LOAD_OK)
+        return nLoadWalletRet;
     fFirstRunRet = vchDefaultKey.empty();
 
     if (!HaveKey(vchDefaultKey))
@@ -1107,11 +1139,11 @@ bool CWallet::LoadWallet(bool& fFirstRunRet)
 
         SetDefaultKey(GetOrReuseKeyFromPool());
         if (!SetAddressBookName(PubKeyToAddress(vchDefaultKey), ""))
-            return false;
+            return DB_LOAD_FAIL;
     }
 
     CreateThread(ThreadFlushWalletDB, &strWalletFile);
-    return true;
+    return DB_LOAD_OK;
 }