diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -186,12 +186,14 @@ bool addDestData(const CTxDestination &dest, const std::string &key, const std::string &value) override { LOCK(m_wallet->cs_wallet); - return m_wallet->AddDestData(dest, key, value); + WalletBatch batch{m_wallet->GetDatabase()}; + return m_wallet->AddDestData(batch, dest, key, value); } bool eraseDestData(const CTxDestination &dest, const std::string &key) override { LOCK(m_wallet->cs_wallet); - return m_wallet->EraseDestData(dest, key); + WalletBatch batch{m_wallet->GetDatabase()}; + return m_wallet->EraseDestData(batch, dest, key); } std::vector getDestValues(const std::string &prefix) override { diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -391,9 +391,10 @@ BOOST_AUTO_TEST_CASE(LoadReceiveRequests) { CTxDestination dest = PKHash(); LOCK(m_wallet.cs_wallet); - m_wallet.AddDestData(dest, "misc", "val_misc"); - m_wallet.AddDestData(dest, "rr0", "val_rr0"); - m_wallet.AddDestData(dest, "rr1", "val_rr1"); + WalletBatch batch{m_wallet.GetDatabase()}; + m_wallet.AddDestData(batch, dest, "misc", "val_misc"); + m_wallet.AddDestData(batch, dest, "rr0", "val_rr0"); + m_wallet.AddDestData(batch, dest, "rr1", "val_rr1"); auto values = m_wallet.GetDestValues("rr"); BOOST_CHECK_EQUAL(values.size(), 2U); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -906,7 +906,9 @@ // Whether this or any UTXO with the same CTxDestination has been spent. bool IsUsedDestination(const CTxDestination &dst) const; bool IsUsedDestination(const TxId &txid, unsigned int n) const; - void SetUsedDestinationState(const TxId &hash, unsigned int n, bool used); + void SetUsedDestinationState(WalletBatch &batch, const TxId &txid, + unsigned int n, bool used) + EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); std::vector GroupOutputs(const std::vector &outputs, bool single_coin) const; @@ -945,11 +947,12 @@ } //! Adds a destination data tuple to the store, and saves it to disk - bool AddDestData(const CTxDestination &dest, const std::string &key, - const std::string &value) + bool AddDestData(WalletBatch &batch, const CTxDestination &dest, + const std::string &key, const std::string &value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); //! Erases a destination data tuple in the store and on disk - bool EraseDestData(const CTxDestination &dest, const std::string &key) + bool EraseDestData(WalletBatch &batch, const CTxDestination &dest, + const std::string &key) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); //! Adds a destination data tuple to the store, without saving it to disk void LoadDestData(const CTxDestination &dest, const std::string &key, diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -759,9 +759,10 @@ } } -void CWallet::SetUsedDestinationState(const TxId &hash, unsigned int n, - bool used) { - const CWalletTx *srctx = GetWalletTx(hash); +void CWallet::SetUsedDestinationState(WalletBatch &batch, const TxId &txid, + unsigned int n, bool used) { + AssertLockHeld(cs_wallet); + const CWalletTx *srctx = GetWalletTx(txid); if (!srctx) { return; } @@ -769,12 +770,11 @@ CTxDestination dst; if (ExtractDestination(srctx->tx->vout[n].scriptPubKey, dst)) { if (IsMine(dst)) { - LOCK(cs_wallet); if (used && !GetDestData(dst, "used", nullptr)) { // p for "present", opposite of absent (null) - AddDestData(dst, "used", "p"); + AddDestData(batch, dst, "used", "p"); } else if (!used && GetDestData(dst, "used", nullptr)) { - EraseDestData(dst, "used"); + EraseDestData(batch, dst, "used"); } } } @@ -803,7 +803,7 @@ // Mark used destinations for (const CTxIn &txin : wtxIn.tx->vin) { const COutPoint &op = txin.prevout; - SetUsedDestinationState(op.GetTxId(), op.GetN(), true); + SetUsedDestinationState(batch, op.GetTxId(), op.GetN(), true); } } @@ -3824,23 +3824,23 @@ return nTimeSmart; } -bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, - const std::string &value) { +bool CWallet::AddDestData(WalletBatch &batch, const CTxDestination &dest, + const std::string &key, const std::string &value) { if (boost::get(&dest)) { return false; } mapAddressBook[dest].destdata.insert(std::make_pair(key, value)); - return WalletBatch(*database).WriteDestData(dest, key, value); + return batch.WriteDestData(dest, key, value); } -bool CWallet::EraseDestData(const CTxDestination &dest, +bool CWallet::EraseDestData(WalletBatch &batch, const CTxDestination &dest, const std::string &key) { if (!mapAddressBook[dest].destdata.erase(key)) { return false; } - return WalletBatch(*database).EraseDestData(dest, key); + return batch.EraseDestData(dest, key); } void CWallet::LoadDestData(const CTxDestination &dest, const std::string &key,