From 4d410cfce967a42cca7db13288b72baec29423d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Gimenez?= Date: Mon, 27 Jun 2011 23:22:30 +0200 Subject: [PATCH] Fix AddressBook syncrhonization between a CWallet and CWalletDB This problem was reported independently by laanwj in Issue #350. --- src/rpc.cpp | 11 ++++++++--- src/ui.cpp | 21 ++++++++++++++------- src/wallet.cpp | 18 ++++++++++++++++++ src/wallet.h | 11 +++++------ 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/rpc.cpp b/src/rpc.cpp index dabd99d07..f2a0db0fc 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -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; } diff --git a/src/ui.cpp b/src/ui.cpp index a49741f54..2cbcfd5bd 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -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(); diff --git a/src/wallet.cpp b/src/wallet.cpp index e35bce61e..e54bbb3f4 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -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) diff --git a/src/wallet.h b/src/wallet.h index b069d31ce..bf7d8cc51 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -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) {