0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-08 10:31:50 -05:00

interfaces: Stop exposing wallet destdata to gui

Stop giving GUI access to destdata rows in database. Replace with narrow
API just for saving and reading receive request information.

This simplifies code and should prevent the GUI from interfering with
other destdata like address-used status.

Note: No user-visible behavior is changing in this commit. New
CWallet::SetAddressReceiveRequest() implementation avoids a bug in
CWallet::AddDestData() where a modification would leave the previous
value in memory while writing the new value to disk. But it doesn't
matter because the GUI doesn't currently expose the ability to modify
receive requests, only to add and erase them.
This commit is contained in:
Russell Yanofsky 2020-04-12 13:40:43 -04:00
parent 985430d9b2
commit 62252c95e5
9 changed files with 41 additions and 56 deletions

View file

@ -112,14 +112,11 @@ public:
//! Get wallet address list. //! Get wallet address list.
virtual std::vector<WalletAddress> getAddresses() = 0; virtual std::vector<WalletAddress> getAddresses() = 0;
//! Add dest data. //! Get receive requests.
virtual bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) = 0; virtual std::vector<std::string> getAddressReceiveRequests() = 0;
//! Erase dest data. //! Save or remove receive request.
virtual bool eraseDestData(const CTxDestination& dest, const std::string& key) = 0; virtual bool setAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& value) = 0;
//! Get dest values with prefix.
virtual std::vector<std::string> getDestValues(const std::string& prefix) = 0;
//! Lock coin. //! Lock coin.
virtual void lockCoin(const COutPoint& output) = 0; virtual void lockCoin(const COutPoint& output) = 0;

View file

@ -10,7 +10,10 @@
#include <qt/walletmodel.h> #include <qt/walletmodel.h>
#include <clientversion.h> #include <clientversion.h>
#include <interfaces/wallet.h>
#include <key_io.h>
#include <streams.h> #include <streams.h>
#include <util/string.h>
#include <utility> #include <utility>
@ -18,10 +21,9 @@ RecentRequestsTableModel::RecentRequestsTableModel(WalletModel *parent) :
QAbstractTableModel(parent), walletModel(parent) QAbstractTableModel(parent), walletModel(parent)
{ {
// Load entries from wallet // Load entries from wallet
std::vector<std::string> vReceiveRequests; for (const std::string& request : parent->wallet().getAddressReceiveRequests()) {
parent->loadReceiveRequests(vReceiveRequests);
for (const std::string& request : vReceiveRequests)
addNewRequest(request); addNewRequest(request);
}
/* These columns must match the indices in the ColumnIndex enumeration */ /* These columns must match the indices in the ColumnIndex enumeration */
columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle(); columns << tr("Date") << tr("Label") << tr("Message") << getAmountTitle();
@ -143,7 +145,7 @@ bool RecentRequestsTableModel::removeRows(int row, int count, const QModelIndex
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
const RecentRequestEntry* rec = &list[row+i]; const RecentRequestEntry* rec = &list[row+i];
if (!walletModel->saveReceiveRequest(rec->recipient.address.toStdString(), rec->id, "")) if (!walletModel->wallet().setAddressReceiveRequest(DecodeDestination(rec->recipient.address.toStdString()), ToString(rec->id), ""))
return false; return false;
} }
@ -172,7 +174,7 @@ void RecentRequestsTableModel::addNewRequest(const SendCoinsRecipient &recipient
CDataStream ss(SER_DISK, CLIENT_VERSION); CDataStream ss(SER_DISK, CLIENT_VERSION);
ss << newEntry; ss << newEntry;
if (!walletModel->saveReceiveRequest(recipient.address.toStdString(), newEntry.id, ss.str())) if (!walletModel->wallet().setAddressReceiveRequest(DecodeDestination(recipient.address.toStdString()), ToString(newEntry.id), ss.str()))
return; return;
addNewRequest(newEntry); addNewRequest(newEntry);

View file

@ -264,7 +264,7 @@ void TestGUI(interfaces::Node& node)
QCOMPARE(currentRowCount, initialRowCount+1); QCOMPARE(currentRowCount, initialRowCount+1);
// Check addition to wallet // Check addition to wallet
std::vector<std::string> requests = walletModel.wallet().getDestValues("rr"); std::vector<std::string> requests = walletModel.wallet().getAddressReceiveRequests();
QCOMPARE(requests.size(), size_t{1}); QCOMPARE(requests.size(), size_t{1});
RecentRequestEntry entry; RecentRequestEntry entry;
CDataStream{MakeUCharSpan(requests[0]), SER_DISK, CLIENT_VERSION} >> entry; CDataStream{MakeUCharSpan(requests[0]), SER_DISK, CLIENT_VERSION} >> entry;
@ -286,7 +286,7 @@ void TestGUI(interfaces::Node& node)
QCOMPARE(requestTableModel->rowCount({}), currentRowCount-1); QCOMPARE(requestTableModel->rowCount({}), currentRowCount-1);
// Check removal from wallet // Check removal from wallet
QCOMPARE(walletModel.wallet().getDestValues("rr").size(), size_t{0}); QCOMPARE(walletModel.wallet().getAddressReceiveRequests().size(), size_t{0});
} }
} // namespace } // namespace

View file

@ -463,25 +463,6 @@ void WalletModel::UnlockContext::CopyFrom(UnlockContext&& rhs)
rhs.relock = false; rhs.relock = false;
} }
void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests)
{
vReceiveRequests = m_wallet->getDestValues("rr"); // receive request
}
bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
{
CTxDestination dest = DecodeDestination(sAddress);
std::stringstream ss;
ss << nId;
std::string key = "rr" + ss.str(); // "rr" prefix = "receive request" in destdata
if (sRequest.empty())
return m_wallet->eraseDestData(dest, key);
else
return m_wallet->addDestData(dest, key, sRequest);
}
bool WalletModel::bumpFee(uint256 hash, uint256& new_hash) bool WalletModel::bumpFee(uint256 hash, uint256& new_hash)
{ {
CCoinControl coin_control; CCoinControl coin_control;

View file

@ -135,9 +135,6 @@ public:
UnlockContext requestUnlock(); UnlockContext requestUnlock();
void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);
bool bumpFee(uint256 hash, uint256& new_hash); bool bumpFee(uint256 hash, uint256& new_hash);
static bool isWalletEnabled(); static bool isWalletEnabled();

View file

@ -199,22 +199,14 @@ public:
} }
return result; return result;
} }
bool addDestData(const CTxDestination& dest, const std::string& key, const std::string& value) override std::vector<std::string> getAddressReceiveRequests() override {
{ LOCK(m_wallet->cs_wallet);
return m_wallet->GetAddressReceiveRequests();
}
bool setAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& value) override {
LOCK(m_wallet->cs_wallet); LOCK(m_wallet->cs_wallet);
WalletBatch batch{m_wallet->GetDatabase()}; WalletBatch batch{m_wallet->GetDatabase()};
return m_wallet->AddDestData(batch, dest, key, value); return m_wallet->SetAddressReceiveRequest(batch, dest, id, value);
}
bool eraseDestData(const CTxDestination& dest, const std::string& key) override
{
LOCK(m_wallet->cs_wallet);
WalletBatch batch{m_wallet->GetDatabase()};
return m_wallet->EraseDestData(batch, dest, key);
}
std::vector<std::string> getDestValues(const std::string& prefix) override
{
LOCK(m_wallet->cs_wallet);
return m_wallet->GetDestValues(prefix);
} }
void lockCoin(const COutPoint& output) override void lockCoin(const COutPoint& output) override
{ {

View file

@ -391,10 +391,10 @@ BOOST_AUTO_TEST_CASE(LoadReceiveRequests)
LOCK(m_wallet.cs_wallet); LOCK(m_wallet.cs_wallet);
WalletBatch batch{m_wallet.GetDatabase()}; WalletBatch batch{m_wallet.GetDatabase()};
m_wallet.AddDestData(batch, dest, "misc", "val_misc"); m_wallet.AddDestData(batch, dest, "misc", "val_misc");
m_wallet.AddDestData(batch, dest, "rr0", "val_rr0"); m_wallet.SetAddressReceiveRequest(batch, dest, "0", "val_rr0");
m_wallet.AddDestData(batch, dest, "rr1", "val_rr1"); m_wallet.SetAddressReceiveRequest(batch, dest, "1", "val_rr1");
auto values = m_wallet.GetDestValues("rr"); auto values = m_wallet.GetAddressReceiveRequests();
BOOST_CHECK_EQUAL(values.size(), 2U); BOOST_CHECK_EQUAL(values.size(), 2U);
BOOST_CHECK_EQUAL(values[0], "val_rr0"); BOOST_CHECK_EQUAL(values[0], "val_rr0");
BOOST_CHECK_EQUAL(values[1], "val_rr1"); BOOST_CHECK_EQUAL(values[1], "val_rr1");

View file

@ -3798,8 +3798,9 @@ bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, st
return false; return false;
} }
std::vector<std::string> CWallet::GetDestValues(const std::string& prefix) const std::vector<std::string> CWallet::GetAddressReceiveRequests() const
{ {
const std::string prefix{"rr"};
std::vector<std::string> values; std::vector<std::string> values;
for (const auto& address : m_address_book) { for (const auto& address : m_address_book) {
for (const auto& data : address.second.destdata) { for (const auto& data : address.second.destdata) {
@ -3811,6 +3812,20 @@ std::vector<std::string> CWallet::GetDestValues(const std::string& prefix) const
return values; return values;
} }
bool CWallet::SetAddressReceiveRequest(WalletBatch& batch, const CTxDestination& dest, const std::string& id, const std::string& value)
{
const std::string key{"rr" + id}; // "rr" prefix = "receive request" in destdata
CAddressBookData& data = m_address_book.at(dest);
if (value.empty()) {
if (!batch.EraseDestData(EncodeDestination(dest), key)) return false;
data.destdata.erase(key);
} else {
if (!batch.WriteDestData(EncodeDestination(dest), key, value)) return false;
data.destdata[key] = value;
}
return true;
}
std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error_string) std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error_string)
{ {
// Do some checking on wallet path. It should be either a: // Do some checking on wallet path. It should be either a:

View file

@ -876,8 +876,6 @@ public:
void LoadDestData(const CTxDestination& dest, const std::string& key, const std::string& value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); void LoadDestData(const CTxDestination& dest, const std::string& key, const std::string& value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
//! Look up a destination data tuple in the store, return true if found false otherwise //! Look up a destination data tuple in the store, return true if found false otherwise
bool GetDestData(const CTxDestination& dest, const std::string& key, std::string* value) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool GetDestData(const CTxDestination& dest, const std::string& key, std::string* value) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
//! Get all destination values matching a prefix.
std::vector<std::string> GetDestValues(const std::string& prefix) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
//! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock(). //! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock().
int64_t nRelockTime GUARDED_BY(cs_wallet){0}; int64_t nRelockTime GUARDED_BY(cs_wallet){0};
@ -1084,6 +1082,9 @@ public:
bool DelAddressBook(const CTxDestination& address); bool DelAddressBook(const CTxDestination& address);
std::vector<std::string> GetAddressReceiveRequests() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
bool SetAddressReceiveRequest(WalletBatch& batch, const CTxDestination& dest, const std::string& id, const std::string& value) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
unsigned int GetKeyPoolSize() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); unsigned int GetKeyPoolSize() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
//! signify that a particular wallet feature is now used. //! signify that a particular wallet feature is now used.