aboutsummaryrefslogtreecommitdiff
path: root/db.cpp
diff options
context:
space:
mode:
authors_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2010-10-09 19:33:35 +0000
committers_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2010-10-09 19:33:35 +0000
commit103849419a9c014a69c76b6f96e48b66cbc838ca (patch)
tree73bce9b5c3d96304138b25d1e714222ea3d4a384 /db.cpp
parent0a27bd065e4803a35e436c610bedb06fe39123c6 (diff)
downloadbitcoin-103849419a9c014a69c76b6f96e48b66cbc838ca.tar.xz
key pool for safer wallet backup
git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@163 1a98c847-1fd6-4fd8-948a-caf3550aa51b
Diffstat (limited to 'db.cpp')
-rw-r--r--db.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/db.cpp b/db.cpp
index a7c18a6ffc..336d5a5ec0 100644
--- a/db.cpp
+++ b/db.cpp
@@ -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;
+}