Logic running with -keypool=0 was wrong (empty keys were being returned). Fixes #445
authorGavin Andresen <gavinandresen@gmail.com>
Fri, 12 Aug 2011 20:32:07 +0000 (16:32 -0400)
committerGavin Andresen <gavinandresen@gmail.com>
Thu, 1 Sep 2011 14:12:59 +0000 (10:12 -0400)
Renames GetOrReuseKeyFromKeyPool to GetKeyFromPool, with fAllowReuse arg and bool result.

src/main.cpp
src/rpc.cpp
src/ui.cpp
src/wallet.cpp
src/wallet.h

index 36fdaa7..203b8d5 100644 (file)
@@ -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;
index 5eb5669..161606a 100644 (file)
@@ -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)
+            if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
                 throw JSONRPCError(-12, "Error: Keypool ran out, please call topupkeypool first");
-        }
-        else
-        {
-            account.vchPubKey = pwalletMain->GetOrReuseKeyFromPool();
+
             pwalletMain->SetAddressBookName(CBitcoinAddress(account.vchPubKey), strAccount);
             walletdb.WriteAccount(strAccount, account);
         }
index 5ca6661..c820cf7 100644 (file)
@@ -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();
index 1daec98..e861416 100644 (file)
@@ -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,25 @@ 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;
+    if (nIndex == -1)
+    {
+        if (fAllowReuse && !vchDefaultKey.empty())
+        {
+            result = vchDefaultKey;
+            return true;
+        }
+        if (IsLocked()) return false;
+        result = GenerateNewKey();
+        return true;
+    }
     KeepKey(nIndex);
-    return keypool.vchPubKey;
+    result = keypool.vchPubKey;
+    return true;
 }
 
 int64 CWallet::GetOldestKeyPoolTime()
index 032284d..1dd2e51 100644 (file)
@@ -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;