aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2011-09-01 12:01:29 -0700
committerGavin Andresen <gavinandresen@gmail.com>2011-09-01 12:01:29 -0700
commit783c636c73182731ca12e6af67516767a989da66 (patch)
tree6e160958804c3f0b968a295b3bec7d2ed947b220
parentdd7868364d9a14349ff82f74fc451db5e6b6b7b9 (diff)
parented02c95d505ce48451b600ff40720841a000fd50 (diff)
Merge pull request #467 from gavinandresen/keypoolzero
Logic running with -keypool=0 was wrong (empty keys were being returned).
-rw-r--r--src/main.cpp2
-rw-r--r--src/rpc.cpp24
-rw-r--r--src/ui.cpp8
-rw-r--r--src/wallet.cpp38
-rw-r--r--src/wallet.h2
5 files changed, 47 insertions, 27 deletions
diff --git a/src/main.cpp b/src/main.cpp
index d6bfc63c3c..f68683e24b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2183,7 +2183,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
// Keep giving the same key to the same ip until they use it
if (!mapReuseKey.count(pfrom->addr.ip))
- mapReuseKey[pfrom->addr.ip] = pwalletMain->GetOrReuseKeyFromPool();
+ pwalletMain->GetKeyFromPool(mapReuseKey[pfrom->addr.ip], true);
// Send back approval of order and pubkey to use
CScript scriptPubKey;
diff --git a/src/rpc.cpp b/src/rpc.cpp
index 5eb5669acb..ec2bb2a97a 100644
--- a/src/rpc.cpp
+++ b/src/rpc.cpp
@@ -331,21 +331,20 @@ Value getnewaddress(const Array& params, bool fHelp)
"If [account] is specified (recommended), it is added to the address book "
"so payments received with the address will be credited to [account].");
- if (!pwalletMain->IsLocked())
- pwalletMain->TopUpKeyPool();
-
- if (pwalletMain->GetKeyPoolSize() < 1)
- throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
-
// Parse the account first so we don't generate a key if there's an error
string strAccount;
if (params.size() > 0)
strAccount = AccountFromValue(params[0]);
+ if (!pwalletMain->IsLocked())
+ pwalletMain->TopUpKeyPool();
+
// Generate a new key that is added to wallet
- CBitcoinAddress address(pwalletMain->GetOrReuseKeyFromPool());
+ std::vector<unsigned char> newKey;
+ if (!pwalletMain->GetKeyFromPool(newKey, false))
+ throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
+ CBitcoinAddress address(newKey);
- // This could be done in the same main CS as GetKeyFromKeyPool.
pwalletMain->SetAddressBookName(address, strAccount);
return address.ToString();
@@ -382,12 +381,9 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
{
if (pwalletMain->GetKeyPoolSize() < 1)
{
- if (bKeyUsed || bForceNew)
- throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first");
- }
- else
- {
- account.vchPubKey = pwalletMain->GetOrReuseKeyFromPool();
+ if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
+ throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
+
pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
walletdb.WriteAccount(strAccount, account);
}
diff --git a/src/ui.cpp b/src/ui.cpp
index 5ca666192a..c820cf7df5 100644
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -1391,7 +1391,9 @@ void CMainFrame::OnButtonNew(wxCommandEvent& event)
return;
// Generate new key
- strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString();
+ std::vector<unsigned char> newKey;
+ pwalletMain->GetKeyFromPool(newKey, true);
+ strAddress = CBitcoinAddress(newKey).ToString();
if (fWasLocked)
pwalletMain->Lock();
@@ -2826,7 +2828,9 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
return;
// Generate new key
- strAddress = CBitcoinAddress(pwalletMain->GetOrReuseKeyFromPool()).ToString();
+ std::vector<unsigned char> newKey;
+ pwalletMain->GetKeyFromPool(newKey, true);
+ strAddress = CBitcoinAddress(newKey).ToString();
if (fWasLocked)
pwalletMain->Lock();
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 1daec98d34..8bbb80cf25 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -268,8 +268,12 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
{
if (txout.scriptPubKey == scriptDefaultKey)
{
- SetDefaultKey(GetOrReuseKeyFromPool());
- SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
+ std::vector<unsigned char> newDefaultKey;
+ if (GetKeyFromPool(newDefaultKey, false))
+ {
+ SetDefaultKey(newDefaultKey);
+ SetAddressBookName(CBitcoinAddress(vchDefaultKey), "");
+ }
}
}
@@ -1126,7 +1130,10 @@ int CWallet::LoadWallet(bool& fFirstRunRet)
// Create new keyUser and set as default key
RandAddSeedPerfmon();
- SetDefaultKey(GetOrReuseKeyFromPool());
+ std::vector<unsigned char> newDefaultKey;
+ if (!GetKeyFromPool(newDefaultKey, false))
+ return DB_LOAD_FAIL;
+ SetDefaultKey(newDefaultKey);
if (!SetAddressBookName(CBitcoinAddress(vchDefaultKey), ""))
return DB_LOAD_FAIL;
}
@@ -1269,15 +1276,28 @@ void CWallet::ReturnKey(int64 nIndex)
printf("keypool return %"PRI64d"\n", nIndex);
}
-vector<unsigned char> CWallet::GetOrReuseKeyFromPool()
+bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
{
int64 nIndex = 0;
CKeyPool keypool;
- ReserveKeyFromKeyPool(nIndex, keypool);
- if(nIndex == -1)
- return vchDefaultKey;
- KeepKey(nIndex);
- return keypool.vchPubKey;
+ CRITICAL_BLOCK(cs_wallet)
+ {
+ ReserveKeyFromKeyPool(nIndex, keypool);
+ if (nIndex == -1)
+ {
+ if (fAllowReuse && !vchDefaultKey.empty())
+ {
+ result = vchDefaultKey;
+ return true;
+ }
+ if (IsLocked()) return false;
+ result = GenerateNewKey();
+ return true;
+ }
+ KeepKey(nIndex);
+ result = keypool.vchPubKey;
+ }
+ return true;
}
int64 CWallet::GetOldestKeyPoolTime()
diff --git a/src/wallet.h b/src/wallet.h
index 032284dd3a..1dd2e51260 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -85,7 +85,7 @@ public:
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
void KeepKey(int64 nIndex);
void ReturnKey(int64 nIndex);
- std::vector<unsigned char> GetOrReuseKeyFromPool();
+ bool GetKeyFromPool(std::vector<unsigned char> &key, bool fAllowReuse=true);
int64 GetOldestKeyPoolTime();
bool IsMine(const CTxIn& txin) const;