aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/walletdb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/walletdb.cpp')
-rw-r--r--src/wallet/walletdb.cpp53
1 files changed, 42 insertions, 11 deletions
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index f25acee1e9..5bf21eb91f 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -13,6 +13,8 @@
#include <util/bip32.h>
#include <util/system.h>
#include <util/time.h>
+#include <util/translation.h>
+#include <wallet/bdb.h>
#include <wallet/wallet.h>
#include <atomic>
@@ -263,13 +265,17 @@ public:
static bool
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 {
// Unserialize
// Taking advantage of the fact that pair serialization
// is just the two items serialized one after the other
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) {
std::string strAddress;
ssKey >> strAddress;
@@ -668,11 +674,11 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
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;
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)
@@ -989,16 +995,41 @@ bool WalletBatch::TxnAbort()
return m_batch->TxnAbort();
}
-bool IsWalletLoaded(const fs::path& wallet_path)
+std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error)
{
- return IsBDBWalletLoaded(wallet_path);
-}
+ bool exists;
+ try {
+ exists = fs::symlink_status(path).type() != fs::file_not_found;
+ } catch (const fs::filesystem_error& e) {
+ error = Untranslated(strprintf("Failed to access database path '%s': %s", path.string(), fsbridge::get_filesystem_error_message(e)));
+ status = DatabaseStatus::FAILED_BAD_PATH;
+ return nullptr;
+ }
-/** Return object for accessing database at specified path. */
-std::unique_ptr<WalletDatabase> CreateWalletDatabase(const fs::path& path)
-{
- std::string filename;
- return MakeUnique<BerkeleyDatabase>(GetWalletEnv(path, filename), std::move(filename));
+ Optional<DatabaseFormat> format;
+ if (exists) {
+ if (ExistsBerkeleyDatabase(path)) {
+ format = DatabaseFormat::BERKELEY;
+ }
+ } else if (options.require_existing) {
+ error = Untranslated(strprintf("Failed to load database path '%s'. Path does not exist.", path.string()));
+ status = DatabaseStatus::FAILED_NOT_FOUND;
+ return nullptr;
+ }
+
+ if (!format && options.require_existing) {
+ error = Untranslated(strprintf("Failed to load database path '%s'. Data is not in recognized format.", path.string()));
+ status = DatabaseStatus::FAILED_BAD_FORMAT;
+ return nullptr;
+ }
+
+ if (format && options.require_create) {
+ error = Untranslated(strprintf("Failed to create database path '%s'. Database already exists.", path.string()));
+ status = DatabaseStatus::FAILED_ALREADY_EXISTS;
+ return nullptr;
+ }
+
+ return MakeBerkeleyDatabase(path, options, status, error);
}
/** Return object for accessing dummy database with no read/write capabilities. */