aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2022-03-24 07:40:27 +0100
committerMarcoFalke <falke.marco@gmail.com>2022-03-24 07:40:42 +0100
commit98e9d8e8e2e3e65e6f1e14be26457a9f9090c092 (patch)
tree144a905f0377558dd68f9d506a4c4a0aed096405 /src/wallet
parentcea230eec40054a82fcd31fa97cf46f1585c4a35 (diff)
parent39b1763730177cd7d6a32fd9321da640b0d65e0e (diff)
downloadbitcoin-98e9d8e8e2e3e65e6f1e14be26457a9f9090c092.tar.xz
Merge bitcoin/bitcoin#23732: refactor: Remove `gArgs` from `bdb.h` and `sqlite.h`
39b1763730177cd7d6a32fd9321da640b0d65e0e Replace use of `ArgsManager` with `DatabaseOptions` (Kiminuo) Pull request description: Contributes to #21005. The goal of this PR is to remove `gArgs` from database classes (i.e. `bdb.h` and `sqlite.h`) so that they can be tested without relying on `gArgs` in tests. Notes: * My goal is to enable unit-testing without relying on `gArgs` as much as possible. Global variables are hard to reason about which in turn makes it slightly harder to contribute to this codebase. When the compiler does the heavy lifting for us and allows us only to construct an object (or call a method) with valid parameters, we may also save some time in code reviews. The cost for this is passing an argument which is not for free but the cost is very miniscule compared to benefits, I think. * GUI code is an exception because it seems fine to have `gArgs` there so I don't plan to make changes in `src/qt` folder, for example. * My approach to removal of `gArgs` uses is moving from lower levels to upper ones and pass `ArgsManager` as an argument as needed. The approach is very similar to what #20158. ACKs for top commit: achow101: ACK 39b1763730177cd7d6a32fd9321da640b0d65e0e ryanofsky: Code review ACK 39b1763730177cd7d6a32fd9321da640b0d65e0e. Just the two small ReadDatabaseArgs and Berkeley open changes that were discussed since the last review Tree-SHA512: aa066b314db593e46c18698fe8cdd500f558b405dc04e4a9a3ff57b52b5b3a81a6cb090e0e661785d1d02c1bf18958c1f4cd715ff233aab63381e3f80960622d
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/bdb.cpp17
-rw-r--r--src/wallet/bdb.h12
-rw-r--r--src/wallet/db.cpp10
-rw-r--r--src/wallet/db.h9
-rw-r--r--src/wallet/dump.cpp11
-rw-r--r--src/wallet/dump.h5
-rw-r--r--src/wallet/init.cpp4
-rw-r--r--src/wallet/interfaces.cpp2
-rw-r--r--src/wallet/load.cpp3
-rw-r--r--src/wallet/rpc/wallet.cpp3
-rw-r--r--src/wallet/salvage.cpp3
-rw-r--r--src/wallet/salvage.h3
-rw-r--r--src/wallet/sqlite.cpp8
-rw-r--r--src/wallet/sqlite.h3
-rw-r--r--src/wallet/test/db_tests.cpp10
-rw-r--r--src/wallet/test/init_test_fixture.cpp9
-rw-r--r--src/wallet/test/init_tests.cpp8
-rw-r--r--src/wallet/test/wallet_tests.cpp18
-rw-r--r--src/wallet/wallet.cpp1
-rw-r--r--src/wallet/walletdb.cpp5
-rw-r--r--src/wallet/wallettool.cpp9
21 files changed, 93 insertions, 60 deletions
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index 49f0abf9e7..0d0456af4b 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -60,12 +60,12 @@ bool WalletDatabaseFileId::operator==(const WalletDatabaseFileId& rhs) const
* erases the weak pointer from the g_dbenvs map.
* @post A new BerkeleyEnvironment weak pointer is inserted into g_dbenvs if the directory path key was not already in the map.
*/
-std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory)
+std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory, bool use_shared_memory)
{
LOCK(cs_db);
auto inserted = g_dbenvs.emplace(fs::PathToString(env_directory), std::weak_ptr<BerkeleyEnvironment>());
if (inserted.second) {
- auto env = std::make_shared<BerkeleyEnvironment>(env_directory);
+ auto env = std::make_shared<BerkeleyEnvironment>(env_directory, use_shared_memory);
inserted.first->second = env;
return env;
}
@@ -113,7 +113,7 @@ void BerkeleyEnvironment::Reset()
fMockDb = false;
}
-BerkeleyEnvironment::BerkeleyEnvironment(const fs::path& dir_path) : strPath(fs::PathToString(dir_path))
+BerkeleyEnvironment::BerkeleyEnvironment(const fs::path& dir_path, bool use_shared_memory) : strPath(fs::PathToString(dir_path)), m_use_shared_memory(use_shared_memory)
{
Reset();
}
@@ -145,8 +145,9 @@ bool BerkeleyEnvironment::Open(bilingual_str& err)
LogPrintf("BerkeleyEnvironment::Open: LogDir=%s ErrorFile=%s\n", fs::PathToString(pathLogDir), fs::PathToString(pathErrorFile));
unsigned int nEnvFlags = 0;
- if (gArgs.GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB))
+ if (!m_use_shared_memory) {
nEnvFlags |= DB_PRIVATE;
+ }
dbenv->set_lg_dir(fs::PathToString(pathLogDir).c_str());
dbenv->set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet
@@ -188,7 +189,7 @@ bool BerkeleyEnvironment::Open(bilingual_str& err)
}
//! Construct an in-memory mock Berkeley environment for testing
-BerkeleyEnvironment::BerkeleyEnvironment()
+BerkeleyEnvironment::BerkeleyEnvironment() : m_use_shared_memory(false)
{
Reset();
@@ -377,7 +378,7 @@ void BerkeleyBatch::Flush()
nMinutes = 1;
if (env) { // env is nullptr for dummy databases (i.e. in tests). Don't actually flush if env is nullptr so we don't segfault
- env->dbenv->txn_checkpoint(nMinutes ? gArgs.GetIntArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0);
+ env->dbenv->txn_checkpoint(nMinutes ? m_database.m_max_log_mb * 1024 : 0, nMinutes, 0);
}
}
@@ -831,13 +832,13 @@ std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, con
{
LOCK(cs_db); // Lock env.m_databases until insert in BerkeleyDatabase constructor
std::string data_filename = fs::PathToString(data_file.filename());
- std::shared_ptr<BerkeleyEnvironment> env = GetBerkeleyEnv(data_file.parent_path());
+ std::shared_ptr<BerkeleyEnvironment> env = GetBerkeleyEnv(data_file.parent_path(), options.use_shared_memory);
if (env->m_databases.count(data_filename)) {
error = Untranslated(strprintf("Refusing to load database. Data file '%s' is already loaded.", fs::PathToString(env->Directory() / data_filename)));
status = DatabaseStatus::FAILED_ALREADY_LOADED;
return nullptr;
}
- db = std::make_unique<BerkeleyDatabase>(std::move(env), std::move(data_filename));
+ db = std::make_unique<BerkeleyDatabase>(std::move(env), std::move(data_filename), options);
}
if (options.verify && !db->Verify(error)) {
diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h
index b924890d81..fd6c76183e 100644
--- a/src/wallet/bdb.h
+++ b/src/wallet/bdb.h
@@ -32,8 +32,6 @@
struct bilingual_str;
namespace wallet {
-static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
-static const bool DEFAULT_WALLET_PRIVDB = true;
struct WalletDatabaseFileId {
u_int8_t value[DB_FILE_ID_LEN];
@@ -56,8 +54,9 @@ public:
std::map<std::string, std::reference_wrapper<BerkeleyDatabase>> m_databases;
std::unordered_map<std::string, WalletDatabaseFileId> m_fileids;
std::condition_variable_any m_db_in_use;
+ bool m_use_shared_memory;
- explicit BerkeleyEnvironment(const fs::path& env_directory);
+ explicit BerkeleyEnvironment(const fs::path& env_directory, bool use_shared_memory);
BerkeleyEnvironment();
~BerkeleyEnvironment();
void Reset();
@@ -85,7 +84,7 @@ public:
};
/** Get BerkeleyEnvironment given a directory path. */
-std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory);
+std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory, bool use_shared_memory);
class BerkeleyBatch;
@@ -98,8 +97,8 @@ public:
BerkeleyDatabase() = delete;
/** Create DB handle to real database */
- BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, std::string filename) :
- WalletDatabase(), env(std::move(env)), strFile(std::move(filename))
+ BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, std::string filename, const DatabaseOptions& options) :
+ WalletDatabase(), env(std::move(env)), strFile(std::move(filename)), m_max_log_mb(options.max_log_mb)
{
auto inserted = this->env->m_databases.emplace(strFile, std::ref(*this));
assert(inserted.second);
@@ -160,6 +159,7 @@ public:
std::unique_ptr<Db> m_db;
std::string strFile;
+ int64_t m_max_log_mb;
/** Make a BerkeleyBatch connected to this database */
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index 0ed2658129..8e79ee678e 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -6,6 +6,7 @@
#include <chainparams.h>
#include <fs.h>
#include <logging.h>
+#include <util/system.h>
#include <wallet/db.h>
#include <exception>
@@ -137,4 +138,13 @@ bool IsSQLiteFile(const fs::path& path)
// Check the application id matches our network magic
return memcmp(Params().MessageStart(), app_id, 4) == 0;
}
+
+void ReadDatabaseArgs(const ArgsManager& args, DatabaseOptions& options)
+{
+ // Override current options with args values, if any were specified
+ options.use_unsafe_sync = args.GetBoolArg("-unsafesqlitesync", options.use_unsafe_sync);
+ options.use_shared_memory = !args.GetBoolArg("-privdb", !options.use_shared_memory);
+ options.max_log_mb = args.GetIntArg("-dblogsize", options.max_log_mb);
+}
+
} // namespace wallet
diff --git a/src/wallet/db.h b/src/wallet/db.h
index 5825b00e3a..f09844c37e 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -16,6 +16,7 @@
#include <optional>
#include <string>
+class ArgsManager;
struct bilingual_str;
namespace wallet {
@@ -207,7 +208,12 @@ struct DatabaseOptions {
std::optional<DatabaseFormat> require_format;
uint64_t create_flags = 0;
SecureString create_passphrase;
- bool verify = true;
+
+ // Specialized options. Not every option is supported by every backend.
+ bool verify = true; //!< Check data integrity on load.
+ bool use_unsafe_sync = false; //!< Disable file sync for faster performance.
+ bool use_shared_memory = false; //!< Let other processes access the database.
+ int64_t max_log_mb = 100; //!< Max log size to allow before consolidating.
};
enum class DatabaseStatus {
@@ -227,6 +233,7 @@ enum class DatabaseStatus {
/** Recursively list database paths in directory. */
std::vector<fs::path> ListDatabases(const fs::path& path);
+void ReadDatabaseArgs(const ArgsManager& args, DatabaseOptions& options);
std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
fs::path BDBDataFile(const fs::path& path);
diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp
index 6d8508fc72..d80c3e25b0 100644
--- a/src/wallet/dump.cpp
+++ b/src/wallet/dump.cpp
@@ -19,10 +19,10 @@ namespace wallet {
static const std::string DUMP_MAGIC = "BITCOIN_CORE_WALLET_DUMP";
uint32_t DUMP_VERSION = 1;
-bool DumpWallet(CWallet& wallet, bilingual_str& error)
+bool DumpWallet(const ArgsManager& args, CWallet& wallet, bilingual_str& error)
{
// Get the dumpfile
- std::string dump_filename = gArgs.GetArg("-dumpfile", "");
+ std::string dump_filename = args.GetArg("-dumpfile", "");
if (dump_filename.empty()) {
error = _("No dump file provided. To use dump, -dumpfile=<filename> must be provided.");
return false;
@@ -114,10 +114,10 @@ static void WalletToolReleaseWallet(CWallet* wallet)
delete wallet;
}
-bool CreateFromDump(const std::string& name, const fs::path& wallet_path, bilingual_str& error, std::vector<bilingual_str>& warnings)
+bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs::path& wallet_path, bilingual_str& error, std::vector<bilingual_str>& warnings)
{
// Get the dumpfile
- std::string dump_filename = gArgs.GetArg("-dumpfile", "");
+ std::string dump_filename = args.GetArg("-dumpfile", "");
if (dump_filename.empty()) {
error = _("No dump file provided. To use createfromdump, -dumpfile=<filename> must be provided.");
return false;
@@ -171,7 +171,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
return false;
}
// Get the data file format with format_value as the default
- std::string file_format = gArgs.GetArg("-format", format_value);
+ std::string file_format = args.GetArg("-format", format_value);
if (file_format.empty()) {
error = _("No wallet file format provided. To use createfromdump, -format=<format> must be provided.");
return false;
@@ -193,6 +193,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
DatabaseOptions options;
DatabaseStatus status;
+ ReadDatabaseArgs(args, options);
options.require_create = true;
options.require_format = data_format;
std::unique_ptr<WalletDatabase> database = MakeDatabase(wallet_path, options, status, error);
diff --git a/src/wallet/dump.h b/src/wallet/dump.h
index a879c4db35..bf683e9843 100644
--- a/src/wallet/dump.h
+++ b/src/wallet/dump.h
@@ -11,11 +11,12 @@
#include <vector>
struct bilingual_str;
+class ArgsManager;
namespace wallet {
class CWallet;
-bool DumpWallet(CWallet& wallet, bilingual_str& error);
-bool CreateFromDump(const std::string& name, const fs::path& wallet_path, bilingual_str& error, std::vector<bilingual_str>& warnings);
+bool DumpWallet(const ArgsManager& args, CWallet& wallet, bilingual_str& error);
+bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs::path& wallet_path, bilingual_str& error, std::vector<bilingual_str>& warnings);
} // namespace wallet
#endif // BITCOIN_WALLET_DUMP_H
diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp
index 7a83dbc35d..7e21126298 100644
--- a/src/wallet/init.cpp
+++ b/src/wallet/init.cpp
@@ -80,9 +80,9 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const
argsman.AddArg("-walletrbf", strprintf("Send transactions with full-RBF opt-in enabled (RPC only, default: %u)", DEFAULT_WALLET_RBF), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
#ifdef USE_BDB
- argsman.AddArg("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST);
+ argsman.AddArg("-dblogsize=<n>", strprintf("Flush wallet database activity from memory to disk log every <n> megabytes (default: %u)", DatabaseOptions().max_log_mb), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST);
argsman.AddArg("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST);
- argsman.AddArg("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST);
+ argsman.AddArg("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", !DatabaseOptions().use_shared_memory), ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::WALLET_DEBUG_TEST);
#else
argsman.AddHiddenArgs({"-dblogsize", "-flushwallet", "-privdb"});
#endif
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
index 9083c304b2..1fb8085661 100644
--- a/src/wallet/interfaces.cpp
+++ b/src/wallet/interfaces.cpp
@@ -544,6 +544,7 @@ public:
std::shared_ptr<CWallet> wallet;
DatabaseOptions options;
DatabaseStatus status;
+ ReadDatabaseArgs(*m_context.args, options);
options.require_create = true;
options.create_flags = wallet_creation_flags;
options.create_passphrase = passphrase;
@@ -553,6 +554,7 @@ public:
{
DatabaseOptions options;
DatabaseStatus status;
+ ReadDatabaseArgs(*m_context.args, options);
options.require_existing = true;
return MakeWallet(m_context, LoadWallet(m_context, name, true /* load_on_start */, options, status, error, warnings));
}
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
index 633d8c5450..98ce95dcd1 100644
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -57,6 +57,7 @@ bool VerifyWallets(WalletContext& context)
if (!args.IsArgSet("wallet")) {
DatabaseOptions options;
DatabaseStatus status;
+ ReadDatabaseArgs(args, options);
bilingual_str error_string;
options.require_existing = true;
options.verify = false;
@@ -84,6 +85,7 @@ bool VerifyWallets(WalletContext& context)
DatabaseOptions options;
DatabaseStatus status;
+ ReadDatabaseArgs(args, options);
options.require_existing = true;
options.verify = true;
bilingual_str error_string;
@@ -112,6 +114,7 @@ bool LoadWallets(WalletContext& context)
}
DatabaseOptions options;
DatabaseStatus status;
+ ReadDatabaseArgs(*context.args, options);
options.require_existing = true;
options.verify = false; // No need to verify, assuming verified earlier in VerifyWallets()
bilingual_str error;
diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp
index 1380f1a77a..804331eb5d 100644
--- a/src/wallet/rpc/wallet.cpp
+++ b/src/wallet/rpc/wallet.cpp
@@ -8,6 +8,7 @@
#include <rpc/server.h>
#include <rpc/util.h>
#include <util/translation.h>
+#include <wallet/context.h>
#include <wallet/receive.h>
#include <wallet/rpc/wallet.h>
#include <wallet/rpc/util.h>
@@ -220,6 +221,7 @@ static RPCHelpMan loadwallet()
DatabaseOptions options;
DatabaseStatus status;
+ ReadDatabaseArgs(*context.args, options);
options.require_existing = true;
bilingual_str error;
std::vector<bilingual_str> warnings;
@@ -381,6 +383,7 @@ static RPCHelpMan createwallet()
DatabaseOptions options;
DatabaseStatus status;
+ ReadDatabaseArgs(*context.args, options);
options.require_create = true;
options.create_flags = flags;
options.create_passphrase = passphrase;
diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp
index 1ecc96fe0e..9ba3c7fd2c 100644
--- a/src/wallet/salvage.cpp
+++ b/src/wallet/salvage.cpp
@@ -23,10 +23,11 @@ static bool KeyFilter(const std::string& type)
return WalletBatch::IsKeyType(type) || type == DBKeys::HDCHAIN;
}
-bool RecoverDatabaseFile(const fs::path& file_path, bilingual_str& error, std::vector<bilingual_str>& warnings)
+bool RecoverDatabaseFile(const ArgsManager& args, const fs::path& file_path, bilingual_str& error, std::vector<bilingual_str>& warnings)
{
DatabaseOptions options;
DatabaseStatus status;
+ ReadDatabaseArgs(args, options);
options.require_existing = true;
options.verify = false;
options.require_format = DatabaseFormat::BERKELEY;
diff --git a/src/wallet/salvage.h b/src/wallet/salvage.h
index 332aceb262..e4822c3c75 100644
--- a/src/wallet/salvage.h
+++ b/src/wallet/salvage.h
@@ -9,10 +9,11 @@
#include <fs.h>
#include <streams.h>
+class ArgsManager;
struct bilingual_str;
namespace wallet {
-bool RecoverDatabaseFile(const fs::path& file_path, bilingual_str& error, std::vector<bilingual_str>& warnings);
+bool RecoverDatabaseFile(const ArgsManager& args, const fs::path& file_path, bilingual_str& error, std::vector<bilingual_str>& warnings);
} // namespace wallet
#endif // BITCOIN_WALLET_SALVAGE_H
diff --git a/src/wallet/sqlite.cpp b/src/wallet/sqlite.cpp
index 55949e6e7a..3f860289f9 100644
--- a/src/wallet/sqlite.cpp
+++ b/src/wallet/sqlite.cpp
@@ -83,8 +83,8 @@ static void SetPragma(sqlite3* db, const std::string& key, const std::string& va
}
}
-SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, bool mock)
- : WalletDatabase(), m_mock(mock), m_dir_path(fs::PathToString(dir_path)), m_file_path(fs::PathToString(file_path))
+SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, const DatabaseOptions& options, bool mock)
+ : WalletDatabase(), m_mock(mock), m_dir_path(fs::PathToString(dir_path)), m_file_path(fs::PathToString(file_path)), m_use_unsafe_sync(options.use_unsafe_sync)
{
{
LOCK(g_sqlite_mutex);
@@ -255,7 +255,7 @@ void SQLiteDatabase::Open()
// Enable fullfsync for the platforms that use it
SetPragma(m_db, "fullfsync", "true", "Failed to enable fullfsync");
- if (gArgs.GetBoolArg("-unsafesqlitesync", false)) {
+ if (m_use_unsafe_sync) {
// Use normal synchronous mode for the journal
LogPrintf("WARNING SQLite is configured to not wait for data to be flushed to disk. Data loss and corruption may occur.\n");
SetPragma(m_db, "synchronous", "OFF", "Failed to set synchronous mode to OFF");
@@ -546,7 +546,7 @@ std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const D
{
try {
fs::path data_file = SQLiteDataFile(path);
- auto db = std::make_unique<SQLiteDatabase>(data_file.parent_path(), data_file);
+ auto db = std::make_unique<SQLiteDatabase>(data_file.parent_path(), data_file, options);
if (options.verify && !db->Verify(error)) {
status = DatabaseStatus::FAILED_VERIFY;
return nullptr;
diff --git a/src/wallet/sqlite.h b/src/wallet/sqlite.h
index 3ed598d0d2..47b7ebb0ec 100644
--- a/src/wallet/sqlite.h
+++ b/src/wallet/sqlite.h
@@ -69,7 +69,7 @@ public:
SQLiteDatabase() = delete;
/** Create DB handle to real database */
- SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, bool mock = false);
+ SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, const DatabaseOptions& options, bool mock = false);
~SQLiteDatabase();
@@ -113,6 +113,7 @@ public:
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
sqlite3* m_db{nullptr};
+ bool m_use_unsafe_sync;
};
std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp
index 35ae3707f8..fbf1e0efd3 100644
--- a/src/wallet/test/db_tests.cpp
+++ b/src/wallet/test/db_tests.cpp
@@ -19,13 +19,13 @@ static std::shared_ptr<BerkeleyEnvironment> GetWalletEnv(const fs::path& path, s
{
fs::path data_file = BDBDataFile(path);
database_filename = fs::PathToString(data_file.filename());
- return GetBerkeleyEnv(data_file.parent_path());
+ return GetBerkeleyEnv(data_file.parent_path(), false);
}
BOOST_AUTO_TEST_CASE(getwalletenv_file)
{
std::string test_name = "test_name.dat";
- const fs::path datadir = gArgs.GetDataDirNet();
+ const fs::path datadir = m_args.GetDataDirNet();
fs::path file_path = datadir / test_name;
std::ofstream f{file_path};
f.close();
@@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(getwalletenv_file)
BOOST_AUTO_TEST_CASE(getwalletenv_directory)
{
std::string expected_name = "wallet.dat";
- const fs::path datadir = gArgs.GetDataDirNet();
+ const fs::path datadir = m_args.GetDataDirNet();
std::string filename;
std::shared_ptr<BerkeleyEnvironment> env = GetWalletEnv(datadir, filename);
@@ -49,8 +49,8 @@ BOOST_AUTO_TEST_CASE(getwalletenv_directory)
BOOST_AUTO_TEST_CASE(getwalletenv_g_dbenvs_multiple)
{
- fs::path datadir = gArgs.GetDataDirNet() / "1";
- fs::path datadir_2 = gArgs.GetDataDirNet() / "2";
+ fs::path datadir = m_args.GetDataDirNet() / "1";
+ fs::path datadir_2 = m_args.GetDataDirNet() / "2";
std::string filename;
std::shared_ptr<BerkeleyEnvironment> env_1 = GetWalletEnv(datadir, filename);
diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp
index be38cebafd..34c22a9c0d 100644
--- a/src/wallet/test/init_test_fixture.cpp
+++ b/src/wallet/test/init_test_fixture.cpp
@@ -15,12 +15,12 @@
namespace wallet {
InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
{
- m_wallet_loader = MakeWalletLoader(*m_node.chain, *Assert(m_node.args));
+ m_wallet_loader = MakeWalletLoader(*m_node.chain, m_args);
std::string sep;
sep += fs::path::preferred_separator;
- m_datadir = gArgs.GetDataDirNet();
+ m_datadir = m_args.GetDataDirNet();
m_cwd = fs::current_path();
m_walletdir_path_cases["default"] = m_datadir / "wallets";
@@ -42,14 +42,11 @@ InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainNam
InitWalletDirTestingSetup::~InitWalletDirTestingSetup()
{
- gArgs.LockSettings([&](util::Settings& settings) {
- settings.forced_settings.erase("walletdir");
- });
fs::current_path(m_cwd);
}
void InitWalletDirTestingSetup::SetWalletDir(const fs::path& walletdir_path)
{
- gArgs.ForceSetArg("-walletdir", fs::PathToString(walletdir_path));
+ m_args.ForceSetArg("-walletdir", fs::PathToString(walletdir_path));
}
} // namespace wallet
diff --git a/src/wallet/test/init_tests.cpp b/src/wallet/test/init_tests.cpp
index 7fdecc5642..fb0a07e181 100644
--- a/src/wallet/test/init_tests.cpp
+++ b/src/wallet/test/init_tests.cpp
@@ -18,7 +18,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_default)
SetWalletDir(m_walletdir_path_cases["default"]);
bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
- fs::path walletdir = gArgs.GetPathArg("-walletdir");
+ fs::path walletdir = m_args.GetPathArg("-walletdir");
fs::path expected_path = fs::canonical(m_walletdir_path_cases["default"]);
BOOST_CHECK_EQUAL(walletdir, expected_path);
}
@@ -28,7 +28,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_custom)
SetWalletDir(m_walletdir_path_cases["custom"]);
bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
- fs::path walletdir = gArgs.GetPathArg("-walletdir");
+ fs::path walletdir = m_args.GetPathArg("-walletdir");
fs::path expected_path = fs::canonical(m_walletdir_path_cases["custom"]);
BOOST_CHECK_EQUAL(walletdir, expected_path);
}
@@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing)
SetWalletDir(m_walletdir_path_cases["trailing"]);
bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
- fs::path walletdir = gArgs.GetPathArg("-walletdir");
+ fs::path walletdir = m_args.GetPathArg("-walletdir");
fs::path expected_path = fs::canonical(m_walletdir_path_cases["default"]);
BOOST_CHECK_EQUAL(walletdir, expected_path);
}
@@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing2)
SetWalletDir(m_walletdir_path_cases["trailing2"]);
bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
- fs::path walletdir = gArgs.GetPathArg("-walletdir");
+ fs::path walletdir = m_args.GetPathArg("-walletdir");
fs::path expected_path = fs::canonical(m_walletdir_path_cases["default"]);
BOOST_CHECK_EQUAL(walletdir, expected_path);
}
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index c59f7e6f05..7d2b769ae6 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -221,7 +221,7 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
wallet->SetupLegacyScriptPubKeyMan();
WITH_LOCK(wallet->cs_wallet, wallet->SetLastBlockProcessed(newTip->nHeight, newTip->GetBlockHash()));
WalletContext context;
- context.args = &gArgs;
+ context.args = &m_args;
AddWallet(context, wallet);
UniValue keys;
keys.setArray();
@@ -277,12 +277,12 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
SetMockTime(KEY_TIME);
m_coinbase_txns.emplace_back(CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
- std::string backup_file = fs::PathToString(gArgs.GetDataDirNet() / "wallet.backup");
+ std::string backup_file = fs::PathToString(m_args.GetDataDirNet() / "wallet.backup");
// Import key into wallet and call dumpwallet to create backup file.
{
WalletContext context;
- context.args = &gArgs;
+ context.args = &m_args;
const std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(m_node.chain.get(), "", m_args, CreateDummyWalletDatabase());
{
auto spk_man = wallet->GetOrCreateLegacyScriptPubKeyMan();
@@ -310,7 +310,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
wallet->SetupLegacyScriptPubKeyMan();
WalletContext context;
- context.args = &gArgs;
+ context.args = &m_args;
JSONRPCRequest request;
request.context = &context;
request.params.setArray();
@@ -716,10 +716,10 @@ BOOST_FIXTURE_TEST_CASE(wallet_descriptor_test, BasicTestingSetup)
//! rescanning where new transactions in new blocks could be lost.
BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
{
- gArgs.ForceSetArg("-unsafesqlitesync", "1");
+ m_args.ForceSetArg("-unsafesqlitesync", "1");
// Create new wallet with known key and unload it.
WalletContext context;
- context.args = &gArgs;
+ context.args = &m_args;
context.chain = m_node.chain.get();
auto wallet = TestLoadWallet(context);
CKey key;
@@ -812,7 +812,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
BOOST_FIXTURE_TEST_CASE(CreateWalletWithoutChain, BasicTestingSetup)
{
WalletContext context;
- context.args = &gArgs;
+ context.args = &m_args;
auto wallet = TestLoadWallet(context);
BOOST_CHECK(wallet);
UnloadWallet(std::move(wallet));
@@ -820,9 +820,9 @@ BOOST_FIXTURE_TEST_CASE(CreateWalletWithoutChain, BasicTestingSetup)
BOOST_FIXTURE_TEST_CASE(ZapSelectTx, TestChain100Setup)
{
- gArgs.ForceSetArg("-unsafesqlitesync", "1");
+ m_args.ForceSetArg("-unsafesqlitesync", "1");
WalletContext context;
- context.args = &gArgs;
+ context.args = &m_args;
context.chain = m_node.chain.get();
auto wallet = TestLoadWallet(context);
CKey key;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 261d042529..be64b4cdbb 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -366,6 +366,7 @@ std::shared_ptr<CWallet> CreateWallet(WalletContext& context, const std::string&
std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const fs::path& backup_file, const std::string& wallet_name, std::optional<bool> load_on_start, DatabaseStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings)
{
DatabaseOptions options;
+ ReadDatabaseArgs(*context.args, options);
options.require_existing = true;
if (!fs::exists(backup_file)) {
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 6e100524a4..1251c9f37e 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -1189,10 +1189,11 @@ std::unique_ptr<WalletDatabase> CreateDummyWalletDatabase()
/** Return object for accessing temporary in-memory database. */
std::unique_ptr<WalletDatabase> CreateMockWalletDatabase()
{
+ DatabaseOptions options;
#ifdef USE_SQLITE
- return std::make_unique<SQLiteDatabase>("", "", true);
+ return std::make_unique<SQLiteDatabase>("", "", options, true);
#elif USE_BDB
- return std::make_unique<BerkeleyDatabase>(std::make_shared<BerkeleyEnvironment>(), "");
+ return std::make_unique<BerkeleyDatabase>(std::make_shared<BerkeleyEnvironment>(), "", options);
#endif
}
} // namespace wallet
diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp
index 9cd18dd0a5..769175b5a8 100644
--- a/src/wallet/wallettool.cpp
+++ b/src/wallet/wallettool.cpp
@@ -140,6 +140,7 @@ bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)
if (command == "create") {
DatabaseOptions options;
+ ReadDatabaseArgs(args, options);
options.require_create = true;
// If -legacy is set, use it. Otherwise default to false.
bool make_legacy = args.GetBoolArg("-legacy", false);
@@ -165,6 +166,7 @@ bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)
}
} else if (command == "info") {
DatabaseOptions options;
+ ReadDatabaseArgs(args, options);
options.require_existing = true;
const std::shared_ptr<CWallet> wallet_instance = MakeWallet(name, path, args, options);
if (!wallet_instance) return false;
@@ -174,7 +176,7 @@ bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)
#ifdef USE_BDB
bilingual_str error;
std::vector<bilingual_str> warnings;
- bool ret = RecoverDatabaseFile(path, error, warnings);
+ bool ret = RecoverDatabaseFile(args, path, error, warnings);
if (!ret) {
for (const auto& warning : warnings) {
tfm::format(std::cerr, "%s\n", warning.original);
@@ -190,11 +192,12 @@ bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)
#endif
} else if (command == "dump") {
DatabaseOptions options;
+ ReadDatabaseArgs(args, options);
options.require_existing = true;
const std::shared_ptr<CWallet> wallet_instance = MakeWallet(name, path, args, options);
if (!wallet_instance) return false;
bilingual_str error;
- bool ret = DumpWallet(*wallet_instance, error);
+ bool ret = DumpWallet(args, *wallet_instance, error);
if (!ret && !error.empty()) {
tfm::format(std::cerr, "%s\n", error.original);
return ret;
@@ -204,7 +207,7 @@ bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)
} else if (command == "createfromdump") {
bilingual_str error;
std::vector<bilingual_str> warnings;
- bool ret = CreateFromDump(name, path, error, warnings);
+ bool ret = CreateFromDump(args, name, path, error, warnings);
for (const auto& warning : warnings) {
tfm::format(std::cout, "%s\n", warning.original);
}