Fix AddressBook syncrhonization between a CWallet and CWalletDB
authorStéphane Gimenez <dev@gim.name>
Mon, 27 Jun 2011 21:22:30 +0000 (23:22 +0200)
committerStéphane Gimenez <dev@gim.name>
Mon, 27 Jun 2011 21:22:30 +0000 (23:22 +0200)
This problem was reported independently by laanwj in Issue #350.

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

index dabd99d..f2a0db0 100644 (file)
@@ -332,12 +332,15 @@ Value getnewaddress(const Array& params, bool fHelp)
     // Generate a new key that is added to wallet
     string strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool());
 
-    pwalletMain->SetAddressBookName(strAddress, strAccount);
+    // This could be done in the same main CS as GetKeyFromKeyPool.
+    CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+       pwalletMain->SetAddressBookName(strAddress, strAccount);
+
     return strAddress;
 }
 
 
-// requires cs_main, cs_mapWallet locks
+// requires cs_main, cs_mapWallet, cs_mapAddressBook locks
 string GetAccountAddress(string strAccount, bool bForceNew=false)
 {
     string strAddress;
@@ -393,6 +396,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
 
     CRITICAL_BLOCK(cs_main)
     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+    CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
     {
         ret = GetAccountAddress(strAccount);
     }
@@ -431,9 +435,10 @@ Value setaccount(const Array& params, bool fHelp)
             if (strAddress == GetAccountAddress(strOldAccount))
                 GetAccountAddress(strOldAccount, true);
         }
+
+        pwalletMain->SetAddressBookName(strAddress, strAccount);
     }
 
-    pwalletMain->SetAddressBookName(strAddress, strAccount);
     return Value::null;
 }
 
index a49741f..2cbcfd5 100644 (file)
@@ -1186,7 +1186,8 @@ void CMainFrame::OnButtonNew(wxCommandEvent& event)
     string strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool());
 
     // Save
-    pwalletMain->SetAddressBookName(strAddress, strName);
+    CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+        pwalletMain->SetAddressBookName(strAddress, strName);
     SetDefaultReceivingAddress(strAddress);
 }
 
@@ -2444,7 +2445,8 @@ void CAddressBookDialog::OnListEndLabelEdit(wxListEvent& event)
     if (event.IsEditCancelled())
         return;
     string strAddress = (string)GetItemText(m_listCtrl, event.GetIndex(), 1);
-    pwalletMain->SetAddressBookName(strAddress, string(event.GetText()));
+    CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+        pwalletMain->SetAddressBookName(strAddress, string(event.GetText()));
     pframeMain->RefreshListCtrl();
 }
 
@@ -2479,7 +2481,8 @@ void CAddressBookDialog::OnButtonDelete(wxCommandEvent& event)
         if (m_listCtrl->GetItemState(nIndex, wxLIST_STATE_SELECTED))
         {
             string strAddress = (string)GetItemText(m_listCtrl, nIndex, 1);
-            CWalletDB(pwalletMain->strWalletFile).EraseName(strAddress);
+            CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+                pwalletMain->DelAddressBookName(strAddress);
             m_listCtrl->DeleteItem(nIndex);
         }
     }
@@ -2538,9 +2541,12 @@ void CAddressBookDialog::OnButtonEdit(wxCommandEvent& event)
     }
 
     // Write back
-    if (strAddress != strAddressOrg)
-        CWalletDB(pwalletMain->strWalletFile).EraseName(strAddressOrg);
-    pwalletMain->SetAddressBookName(strAddress, strName);
+    CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+    {
+        if (strAddress != strAddressOrg)
+            pwalletMain->DelAddressBookName(strAddressOrg);
+        pwalletMain->SetAddressBookName(strAddress, strName);
+    }
     m_listCtrl->SetItem(nIndex, 1, strAddress);
     m_listCtrl->SetItemText(nIndex, strName);
     pframeMain->RefreshListCtrl();
@@ -2580,7 +2586,8 @@ void CAddressBookDialog::OnButtonNew(wxCommandEvent& event)
     }
 
     // Add to list and select it
-    pwalletMain->SetAddressBookName(strAddress, strName);
+    CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+        pwalletMain->SetAddressBookName(strAddress, strName);
     int nIndex = InsertLine(m_listCtrl, strName, strAddress);
     SetSelection(m_listCtrl, nIndex);
     m_listCtrl->SetFocus();
index e35bce6..e54bbb3 100644 (file)
@@ -977,6 +977,24 @@ bool CWallet::LoadWallet(bool& fFirstRunRet)
     return true;
 }
 
+
+bool CWallet::SetAddressBookName(const string& strAddress, const string& strName)
+{
+    mapAddressBook[strAddress] = strName;
+    if (!fFileBacked)
+        return false;
+    return CWalletDB(strWalletFile).WriteName(strAddress, strName);
+}
+
+bool CWallet::DelAddressBookName(const string& strAddress)
+{
+    mapAddressBook.erase(strAddress);
+    if (!fFileBacked)
+        return false;
+    return CWalletDB(strWalletFile).EraseName(strAddress);
+}
+
+
 void CWallet::PrintWallet(const CBlock& block)
 {
     CRITICAL_BLOCK(cs_mapWallet)
index b069d31..bf7d8cc 100644 (file)
@@ -150,12 +150,11 @@ public:
     bool LoadWallet(bool& fFirstRunRet);
 //    bool BackupWallet(const std::string& strDest);
 
-    bool SetAddressBookName(const std::string& strAddress, const std::string& strName)
-    {
-        if (!fFileBacked)
-            return false;
-        return CWalletDB(strWalletFile).WriteName(strAddress, strName);
-    }
+    // requires cs_mapAddressBook lock
+    bool SetAddressBookName(const std::string& strAddress, const std::string& strName);
+
+    // requires cs_mapAddressBook lock
+    bool DelAddressBookName(const std::string& strAddress);
 
     void UpdatedTransaction(const uint256 &hashTx)
     {