diff options
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r-- | src/wallet/wallet.cpp | 87 |
1 files changed, 37 insertions, 50 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 56bd25b90a..caf95a3f03 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -967,11 +967,11 @@ void CWallet::SetSpentKeyState(WalletBatch& batch, const uint256& hash, unsigned CTxDestination dst; if (ExtractDestination(srctx->tx->vout[n].scriptPubKey, dst)) { if (IsMine(dst)) { - if (used != IsAddressUsed(dst)) { + if (used != IsAddressPreviouslySpent(dst)) { if (used) { tx_destinations.insert(dst); } - SetAddressUsed(batch, dst, used); + SetAddressPreviouslySpent(batch, dst, used); } } } @@ -984,7 +984,7 @@ bool CWallet::IsSpentKey(const CScript& scriptPubKey) const if (!ExtractDestination(scriptPubKey, dest)) { return false; } - if (IsAddressUsed(dest)) { + if (IsAddressPreviouslySpent(dest)) { return true; } if (IsLegacy()) { @@ -992,15 +992,15 @@ bool CWallet::IsSpentKey(const CScript& scriptPubKey) const assert(spk_man != nullptr); for (const auto& keyid : GetAffectedKeys(scriptPubKey, *spk_man)) { WitnessV0KeyHash wpkh_dest(keyid); - if (IsAddressUsed(wpkh_dest)) { + if (IsAddressPreviouslySpent(wpkh_dest)) { return true; } ScriptHash sh_wpkh_dest(GetScriptForDestination(wpkh_dest)); - if (IsAddressUsed(sh_wpkh_dest)) { + if (IsAddressPreviouslySpent(sh_wpkh_dest)) { return true; } PKHash pkh_dest(keyid); - if (IsAddressUsed(pkh_dest)) { + if (IsAddressPreviouslySpent(pkh_dest)) { return true; } } @@ -2403,19 +2403,15 @@ bool CWallet::DelAddressBook(const CTxDestination& address) WalletBatch batch(GetDatabase()); { LOCK(cs_wallet); - // If we want to delete receiving addresses, we need to take care that DestData "used" (and possibly newer DestData) gets preserved (and the "deleted" address transformed into a change entry instead of actually being deleted) - // NOTE: This isn't a problem for sending addresses because they never have any DestData yet! - // When adding new DestData, it should be considered here whether to retain or delete it (or move it?). + // If we want to delete receiving addresses, we should avoid calling EraseAddressData because it will delete the previously_spent value. Could instead just erase the label so it becomes a change address, and keep the data. + // NOTE: This isn't a problem for sending addresses because they don't have any data that needs to be kept. + // When adding new address data, it should be considered here whether to retain or delete it. if (IsMine(address)) { WalletLogPrintf("%s called with IsMine address, NOT SUPPORTED. Please report this bug! %s\n", __func__, PACKAGE_BUGREPORT); return false; } - // Delete destdata tuples associated with address - std::string strAddress = EncodeDestination(address); - for (const std::pair<const std::string, std::string> &item : m_address_book[address].destdata) - { - batch.EraseDestData(strAddress, item.first); - } + // Delete data rows associated with this address + batch.EraseAddressData(address); m_address_book.erase(address); } @@ -2790,51 +2786,42 @@ unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx, bool rescanning_old return nTimeSmart; } -bool CWallet::SetAddressUsed(WalletBatch& batch, const CTxDestination& dest, bool used) +bool CWallet::SetAddressPreviouslySpent(WalletBatch& batch, const CTxDestination& dest, bool used) { - const std::string key{"used"}; if (std::get_if<CNoDestination>(&dest)) return false; if (!used) { - if (auto* data = util::FindKey(m_address_book, dest)) data->destdata.erase(key); - return batch.EraseDestData(EncodeDestination(dest), key); + if (auto* data{util::FindKey(m_address_book, dest)}) data->previously_spent = false; + return batch.WriteAddressPreviouslySpent(dest, false); } - const std::string value{"1"}; - m_address_book[dest].destdata.insert(std::make_pair(key, value)); - return batch.WriteDestData(EncodeDestination(dest), key, value); + LoadAddressPreviouslySpent(dest); + return batch.WriteAddressPreviouslySpent(dest, true); } -void CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value) +void CWallet::LoadAddressPreviouslySpent(const CTxDestination& dest) { - m_address_book[dest].destdata.insert(std::make_pair(key, value)); + m_address_book[dest].previously_spent = true; } -bool CWallet::IsAddressUsed(const CTxDestination& dest) const +void CWallet::LoadAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& request) { - const std::string key{"used"}; - std::map<CTxDestination, CAddressBookData>::const_iterator i = m_address_book.find(dest); - if(i != m_address_book.end()) - { - CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key); - if(j != i->second.destdata.end()) - { - return true; - } - } + m_address_book[dest].receive_requests[id] = request; +} + +bool CWallet::IsAddressPreviouslySpent(const CTxDestination& dest) const +{ + if (auto* data{util::FindKey(m_address_book, dest)}) return data->previously_spent; return false; } std::vector<std::string> CWallet::GetAddressReceiveRequests() const { - const std::string prefix{"rr"}; std::vector<std::string> values; - for (const auto& address : m_address_book) { - for (const auto& data : address.second.destdata) { - if (!data.first.compare(0, prefix.size(), prefix)) { - values.emplace_back(data.second); - } + for (const auto& [dest, entry] : m_address_book) { + for (const auto& [id, request] : entry.receive_requests) { + values.emplace_back(request); } } return values; @@ -2842,15 +2829,15 @@ std::vector<std::string> CWallet::GetAddressReceiveRequests() const 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; - } + if (!batch.WriteAddressReceiveRequest(dest, id, value)) return false; + m_address_book[dest].receive_requests[id] = value; + return true; +} + +bool CWallet::EraseAddressReceiveRequest(WalletBatch& batch, const CTxDestination& dest, const std::string& id) +{ + if (!batch.EraseAddressReceiveRequest(dest, id)) return false; + m_address_book[dest].receive_requests.erase(id); return true; } |