walletdb: Add KeyFilterFn to ReadKeyValue

Add a KeyFilterFn callback to ReadKeyValue which allows the caller to
specify which types to actually deserialize. A KeyFilterFn takes the
type as the parameter and returns a bool indicating whether
deserialization should continue.
This commit is contained in:
Andrew Chow
2020-08-25 13:10:32 -04:00
parent f8462a6d27
commit 544e12a4e8
2 changed files with 11 additions and 4 deletions

View File

@@ -263,13 +263,17 @@ public:
static bool static bool
ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
CWalletScanState &wss, std::string& strType, std::string& strErr) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet) CWalletScanState &wss, std::string& strType, std::string& strErr, const KeyFilterFn& filter_fn = nullptr) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
{ {
try { try {
// Unserialize // Unserialize
// Taking advantage of the fact that pair serialization // Taking advantage of the fact that pair serialization
// is just the two items serialized one after the other // is just the two items serialized one after the other
ssKey >> strType; ssKey >> strType;
// If we have a filter, check if this matches the filter
if (filter_fn && !filter_fn(strType)) {
return true;
}
if (strType == DBKeys::NAME) { if (strType == DBKeys::NAME) {
std::string strAddress; std::string strAddress;
ssKey >> strAddress; ssKey >> strAddress;
@@ -668,11 +672,11 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
return true; return true;
} }
bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, std::string& strType, std::string& strErr) bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, std::string& strType, std::string& strErr, const KeyFilterFn& filter_fn)
{ {
CWalletScanState dummy_wss; CWalletScanState dummy_wss;
LOCK(pwallet->cs_wallet); LOCK(pwallet->cs_wallet);
return ReadKeyValue(pwallet, ssKey, ssValue, dummy_wss, strType, strErr); return ReadKeyValue(pwallet, ssKey, ssValue, dummy_wss, strType, strErr, filter_fn);
} }
bool WalletBatch::IsKeyType(const std::string& strType) bool WalletBatch::IsKeyType(const std::string& strType)

View File

@@ -280,8 +280,11 @@ private:
//! Compacts BDB state so that wallet.dat is self-contained (if there are changes) //! Compacts BDB state so that wallet.dat is self-contained (if there are changes)
void MaybeCompactWalletDB(); void MaybeCompactWalletDB();
//! Callback for filtering key types to deserialize in ReadKeyValue
using KeyFilterFn = std::function<bool(const std::string&)>;
//! Unserialize a given Key-Value pair and load it into the wallet //! Unserialize a given Key-Value pair and load it into the wallet
bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, std::string& strType, std::string& strErr); bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, std::string& strType, std::string& strErr, const KeyFilterFn& filter_fn = nullptr);
/** Return whether a wallet database is currently loaded. */ /** Return whether a wallet database is currently loaded. */
bool IsWalletLoaded(const fs::path& wallet_path); bool IsWalletLoaded(const fs::path& wallet_path);