key pool for safer wallet backup

git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@163 1a98c847-1fd6-4fd8-948a-caf3550aa51b
This commit is contained in:
s_nakamoto
2010-10-09 19:33:35 +00:00
parent 0a27bd065e
commit 103849419a
8 changed files with 198 additions and 57 deletions

65
db.cpp
View File

@@ -576,6 +576,9 @@ bool LoadAddresses()
// CWalletDB
//
static set<int64> setKeyPool;
static CCriticalSection cs_setKeyPool;
bool CWalletDB::LoadWallet()
{
vchDefaultKey.clear();
@@ -654,6 +657,12 @@ bool CWalletDB::LoadWallet()
{
ssValue >> vchDefaultKey;
}
else if (strType == "pool")
{
int64 nIndex;
ssKey >> nIndex;
setKeyPool.insert(nIndex);
}
else if (strType == "version")
{
ssValue >> nFileVersion;
@@ -836,3 +845,59 @@ void BackupWallet(const string& strDest)
Sleep(100);
}
}
void CWalletDB::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
{
nIndex = -1;
keypool.vchPubKey.clear();
CRITICAL_BLOCK(cs_setKeyPool)
{
// Top up key pool
int64 nTargetSize = max(GetArg("-keypool", 100), (int64)0);
while (setKeyPool.size() < nTargetSize+1)
{
int64 nEnd = 1;
if (!setKeyPool.empty())
nEnd = *(--setKeyPool.end()) + 1;
if (!Write(make_pair(string("pool"), nEnd), CKeyPool(GenerateNewKey())))
throw runtime_error("ReserveKeyFromKeyPool() : writing generated key failed");
setKeyPool.insert(nEnd);
printf("keypool added key %"PRI64d", size=%d\n", nEnd, setKeyPool.size());
}
// Get the oldest key
assert(!setKeyPool.empty());
nIndex = *(setKeyPool.begin());
setKeyPool.erase(setKeyPool.begin());
if (!Read(make_pair(string("pool"), nIndex), keypool))
throw runtime_error("ReserveKeyFromKeyPool() : read failed");
if (!mapKeys.count(keypool.vchPubKey))
throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
assert(!keypool.vchPubKey.empty());
printf("keypool reserve %"PRI64d"\n", nIndex);
}
}
void CWalletDB::KeepKey(int64 nIndex)
{
// Remove from key pool
Erase(make_pair(string("pool"), nIndex));
printf("keypool keep %"PRI64d"\n", nIndex);
}
void CWalletDB::ReturnKey(int64 nIndex)
{
// Return to key pool
CRITICAL_BLOCK(cs_setKeyPool)
setKeyPool.insert(nIndex);
printf("keypool return %"PRI64d"\n", nIndex);
}
vector<unsigned char> CWalletDB::GetKeyFromKeyPool()
{
int64 nIndex = 0;
CKeyPool keypool;
ReserveKeyFromKeyPool(nIndex, keypool);
KeepKey(nIndex);
return keypool.vchPubKey;
}