Skip to content

Commit

Permalink
wallet: Add MakeBerkeleyDatabase function
Browse files Browse the repository at this point in the history
New function is not currently called but will be called in upcoming commits. It
moves database path checking, and existence checking, and already-loaded
checking, and verification into a single function so this logic does not need
to be repeated all over higher level wallet code, and so higher level code does
not need to change when SQLite support is added in
bitcoin#19077. This also lets higher level
wallet code make fewer assumptions about the contents of wallet directories.

This commit just adds the new function and does not change behavior in any way.
  • Loading branch information
ryanofsky committed Aug 4, 2020
1 parent 6989897 commit 9b15bf3
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/wallet/bdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -824,3 +824,50 @@ std::unique_ptr<DatabaseBatch> BerkeleyDatabase::MakeBatch(const char* mode, boo
{
return MakeUnique<BerkeleyBatch>(*this, mode, flush_on_close);
}

std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error)
{
status = DatabaseStatus::SUCCESS;

fs::path env_directory;
std::string data_filename;
try {
SplitWalletPath(path, env_directory, data_filename);
} 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;
}

fs::path data_path = env_directory / data_filename;
bool exists = fs::symlink_status(data_path).type() != fs::file_not_found;

if (exists && options.require_create) {
error = Untranslated(strprintf("Failed to create database. Data file '%s' already exists.", data_path.string()));
status = DatabaseStatus::FAILED_ALREADY_EXISTS;
return nullptr;
}

if (!exists && options.require_existing) {
error = Untranslated(strprintf("Failed to load database. Data file '%s' does not exist.", data_path.string()));
status = DatabaseStatus::FAILED_NOT_FOUND;
return nullptr;
}

LOCK(cs_db);
std::shared_ptr<BerkeleyEnvironment> env = GetWalletEnv(path, data_filename);
if (env->m_databases.count(data_filename)) {
error = Untranslated(strprintf("Refusing to load database. Data file '%s' is already loaded.", data_path.string()));
status = DatabaseStatus::FAILED_ALREADY_LOADED;
return nullptr;
}

auto db = MakeUnique<BerkeleyDatabase>(std::move(env), std::move(data_filename));

if (options.verify && !db->Verify(error)) {
status = DatabaseStatus::FAILED_VERIFY;
return nullptr;
}

return db;
}
3 changes: 3 additions & 0 deletions src/wallet/bdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,4 +224,7 @@ class BerkeleyBatch : public DatabaseBatch

std::string BerkeleyDatabaseVersion();

//! Return object giving access to Berkeley database at specified path.
std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);

#endif // BITCOIN_WALLET_BDB_H
17 changes: 17 additions & 0 deletions src/wallet/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,21 @@ class DummyDatabase : public WalletDatabase
std::unique_ptr<DatabaseBatch> MakeBatch(const char* mode = "r+", bool flush_on_close = true) override { return MakeUnique<DummyBatch>(); }
};

struct DatabaseOptions {
bool require_existing = false;
bool require_create = false;
bool verify = true;
};

enum class DatabaseStatus {
SUCCESS,
FAILED_BAD_PATH,
FAILED_ALREADY_LOADED,
FAILED_ALREADY_EXISTS,
FAILED_NOT_FOUND,
FAILED_VERIFY,
};

std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);

#endif // BITCOIN_WALLET_DB_H
6 changes: 6 additions & 0 deletions src/wallet/walletdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <util/bip32.h>
#include <util/system.h>
#include <util/time.h>
#include <wallet/bdb.h>
#include <wallet/wallet.h>

#include <atomic>
Expand Down Expand Up @@ -1006,6 +1007,11 @@ bool WalletBatch::TxnAbort()
return m_batch->TxnAbort();
}

std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error)
{
return MakeBerkeleyDatabase(path, options, status, error);
}

bool IsWalletLoaded(const fs::path& wallet_path)
{
return IsBDBWalletLoaded(wallet_path);
Expand Down

0 comments on commit 9b15bf3

Please sign in to comment.