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)
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;
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();
}
int64 CWallet::GetBalance() const
{
- int64 nStart = GetTimeMillis();
-
int64 nTotal = 0;
CRITICAL_BLOCK(cs_mapWallet)
{
}
}
- //printf("GetBalance() %"PRI64d"ms\n", GetTimeMillis() - nStart);
return nTotal;
}
-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))
SetDefaultKey(GetOrReuseKeyFromPool());
if (!SetAddressBookName(PubKeyToAddress(vchDefaultKey), ""))
- return false;
+ return DB_LOAD_FAIL;
}
CreateThread(ThreadFlushWalletDB, &strWalletFile);
- return true;
+ return DB_LOAD_OK;
}