changeset 733:099957ac6246 draft

Fix AddressBook syncrhonization between a CWallet and CWalletDB This problem was reported independently by laanwj in Issue #350.
author Stéphane Gimenez <dev@gim.name>
date Mon, 27 Jun 2011 23:22:30 +0200
parents 1eaf93557fe5
children 92207882a355
files src/rpc.cpp src/ui.cpp src/wallet.cpp src/wallet.h
diffstat 4 files changed, 45 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/rpc.cpp
+++ b/src/rpc.cpp
@@ -332,12 +332,15 @@
     // 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 @@
 
     CRITICAL_BLOCK(cs_main)
     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+    CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
     {
         ret = GetAccountAddress(strAccount);
     }
@@ -431,9 +435,10 @@
             if (strAddress == GetAccountAddress(strOldAccount))
                 GetAccountAddress(strOldAccount, true);
         }
+
+        pwalletMain->SetAddressBookName(strAddress, strAccount);
     }
 
-    pwalletMain->SetAddressBookName(strAddress, strAccount);
     return Value::null;
 }
 
--- a/src/ui.cpp
+++ b/src/ui.cpp
@@ -1186,7 +1186,8 @@
     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 @@
     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 @@
         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 @@
     }
 
     // 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 @@
     }
 
     // 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();
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -977,6 +977,24 @@
     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)
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -150,12 +150,11 @@
     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)
     {