refactor: Remove CAddressBookData::destdata

This is cleanup that doesn't change external behavior.

- Removes awkward `StringMap` intermediate representation
- Simplifies CWallet code, deals with used address and received request
  serialization in walletdb.cpp
- Adds test coverage and documentation
- Reduces memory usage

This PR doesn't change externally observable behavior. Internally, only change
in behavior is that EraseDestData deletes directly from database because the
`StringMap` is gone. This is more direct and efficient because it uses a single
btree lookup and scan instead of multiple lookups

Motivation for this cleanup is making changes like #18550, #18192, #13756
easier to reason about and less likely to result in unintended behavior and
bugs

Co-authored-by: furszy <matiasfurszyfer@protonmail.com>
This commit is contained in:
Ryan Ofsky
2020-04-12 13:40:43 -04:00
parent 5938ad0bdb
commit a5986e82dd
6 changed files with 164 additions and 86 deletions

View File

@@ -615,7 +615,20 @@ ReadKeyValue(CWallet* pwallet, DataStream& ssKey, CDataStream& ssValue,
ssKey >> strAddress;
ssKey >> strKey;
ssValue >> strValue;
pwallet->LoadDestData(DecodeDestination(strAddress), strKey, strValue);
const CTxDestination& dest{DecodeDestination(strAddress)};
if (strKey.compare("used") == 0) {
// Load "used" key indicating if an IsMine address has
// previously been spent from with avoid_reuse option enabled.
// The strValue is not used for anything currently, but could
// hold more information in the future. Current values are just
// "1" or "p" for present (which was written prior to
// f5ba424cd44619d9b9be88b8593d69a7ba96db26).
pwallet->LoadAddressPreviouslySpent(dest);
} else if (strKey.compare(0, 2, "rr") == 0) {
// Load "rr##" keys where ## is a decimal number, and strValue
// is a serialized RecentRequestEntry object.
pwallet->LoadAddressReceiveRequest(dest, strKey.substr(2), strValue);
}
} else if (strType == DBKeys::HDCHAIN) {
CHDChain chain;
ssValue >> chain;
@@ -1088,16 +1101,28 @@ void MaybeCompactWalletDB(WalletContext& context)
fOneThread = false;
}
bool WalletBatch::WriteDestData(const std::string &address, const std::string &key, const std::string &value)
bool WalletBatch::WriteAddressPreviouslySpent(const CTxDestination& dest, bool previously_spent)
{
return WriteIC(std::make_pair(DBKeys::DESTDATA, std::make_pair(address, key)), value);
auto key{std::make_pair(DBKeys::DESTDATA, std::make_pair(EncodeDestination(dest), std::string("used")))};
return previously_spent ? WriteIC(key, std::string("1")) : EraseIC(key);
}
bool WalletBatch::EraseDestData(const std::string &address, const std::string &key)
bool WalletBatch::WriteAddressReceiveRequest(const CTxDestination& dest, const std::string& id, const std::string& receive_request)
{
return EraseIC(std::make_pair(DBKeys::DESTDATA, std::make_pair(address, key)));
return WriteIC(std::make_pair(DBKeys::DESTDATA, std::make_pair(EncodeDestination(dest), "rr" + id)), receive_request);
}
bool WalletBatch::EraseAddressReceiveRequest(const CTxDestination& dest, const std::string& id)
{
return EraseIC(std::make_pair(DBKeys::DESTDATA, std::make_pair(EncodeDestination(dest), "rr" + id)));
}
bool WalletBatch::EraseAddressData(const CTxDestination& dest)
{
DataStream prefix;
prefix << DBKeys::DESTDATA << EncodeDestination(dest);
return m_batch->ErasePrefix(prefix);
}
bool WalletBatch::WriteHDChain(const CHDChain& chain)
{