Use DB Transactions when encrypting wallet.

This speeds up the encryption process significantly.
This commit is contained in:
Matt Corallo 2011-07-08 15:08:27 +02:00
parent 0efda1a79e
commit 96f34cd5c4
2 changed files with 29 additions and 6 deletions

View File

@ -31,8 +31,14 @@ bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector
return false; return false;
if (!fFileBacked) if (!fFileBacked)
return true; return true;
CRITICAL_BLOCK(cs_pwalletdbEncryption)
{
if (pwalletdbEncryption)
return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret);
else
return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret); return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret);
} }
}
bool CWallet::Unlock(const string& strWalletPassphrase) bool CWallet::Unlock(const string& strWalletPassphrase)
{ {
@ -104,10 +110,10 @@ bool CWallet::ChangeWalletPassphrase(const string& strOldWalletPassphrase, const
bool CWallet::EncryptWallet(const string& strWalletPassphrase) bool CWallet::EncryptWallet(const string& strWalletPassphrase)
{ {
//TODO: use db commits
CRITICAL_BLOCK(cs_mapPubKeys) CRITICAL_BLOCK(cs_mapPubKeys)
CRITICAL_BLOCK(cs_KeyStore) CRITICAL_BLOCK(cs_KeyStore)
CRITICAL_BLOCK(cs_vMasterKey) CRITICAL_BLOCK(cs_vMasterKey)
CRITICAL_BLOCK(cs_pwalletdbEncryption)
{ {
if (IsCrypted()) if (IsCrypted())
return false; return false;
@ -146,13 +152,26 @@ bool CWallet::EncryptWallet(const string& strWalletPassphrase)
mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
if (fFileBacked) if (fFileBacked)
{ {
DBFlush(false); pwalletdbEncryption = new CWalletDB(strWalletFile);
CWalletDB(strWalletFile).WriteMasterKey(nMasterKeyMaxID, kMasterKey); pwalletdbEncryption->TxnBegin();
DBFlush(false); pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
} }
if (!EncryptKeys(vMasterKey)) 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)
{
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(); Lock();
} }

View File

@ -18,6 +18,8 @@ private:
bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const; bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const; bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
CWalletDB *pwalletdbEncryption;
CCriticalSection cs_pwalletdbEncryption;
public: public:
bool fFileBacked; bool fFileBacked;
@ -34,12 +36,14 @@ public:
{ {
fFileBacked = false; fFileBacked = false;
nMasterKeyMaxID = 0; nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL;
} }
CWallet(std::string strWalletFileIn) CWallet(std::string strWalletFileIn)
{ {
strWalletFile = strWalletFileIn; strWalletFile = strWalletFileIn;
fFileBacked = true; fFileBacked = true;
nMasterKeyMaxID = 0; nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL;
} }
mutable CCriticalSection cs_mapWallet; mutable CCriticalSection cs_mapWallet;