Skip to content

Commit 39b1763

Browse files
kiminuoryanofsky
andcommitted
Replace use of ArgsManager with DatabaseOptions
Co-authored-by: Russell Yanofsky <[email protected]>
1 parent a7e8044 commit 39b1763

21 files changed

+93
-60
lines changed

src/wallet/bdb.cpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@ bool WalletDatabaseFileId::operator==(const WalletDatabaseFileId& rhs) const
6060
* erases the weak pointer from the g_dbenvs map.
6161
* @post A new BerkeleyEnvironment weak pointer is inserted into g_dbenvs if the directory path key was not already in the map.
6262
*/
63-
std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory)
63+
std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory, bool use_shared_memory)
6464
{
6565
LOCK(cs_db);
6666
auto inserted = g_dbenvs.emplace(fs::PathToString(env_directory), std::weak_ptr<BerkeleyEnvironment>());
6767
if (inserted.second) {
68-
auto env = std::make_shared<BerkeleyEnvironment>(env_directory);
68+
auto env = std::make_shared<BerkeleyEnvironment>(env_directory, use_shared_memory);
6969
inserted.first->second = env;
7070
return env;
7171
}
@@ -113,7 +113,7 @@ void BerkeleyEnvironment::Reset()
113113
fMockDb = false;
114114
}
115115

116-
BerkeleyEnvironment::BerkeleyEnvironment(const fs::path& dir_path) : strPath(fs::PathToString(dir_path))
116+
BerkeleyEnvironment::BerkeleyEnvironment(const fs::path& dir_path, bool use_shared_memory) : strPath(fs::PathToString(dir_path)), m_use_shared_memory(use_shared_memory)
117117
{
118118
Reset();
119119
}
@@ -145,8 +145,9 @@ bool BerkeleyEnvironment::Open(bilingual_str& err)
145145
LogPrintf("BerkeleyEnvironment::Open: LogDir=%s ErrorFile=%s\n", fs::PathToString(pathLogDir), fs::PathToString(pathErrorFile));
146146

147147
unsigned int nEnvFlags = 0;
148-
if (gArgs.GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB))
148+
if (!m_use_shared_memory) {
149149
nEnvFlags |= DB_PRIVATE;
150+
}
150151

151152
dbenv->set_lg_dir(fs::PathToString(pathLogDir).c_str());
152153
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)
188189
}
189190

190191
//! Construct an in-memory mock Berkeley environment for testing
191-
BerkeleyEnvironment::BerkeleyEnvironment()
192+
BerkeleyEnvironment::BerkeleyEnvironment() : m_use_shared_memory(false)
192193
{
193194
Reset();
194195

@@ -377,7 +378,7 @@ void BerkeleyBatch::Flush()
377378
nMinutes = 1;
378379

379380
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
380-
env->dbenv->txn_checkpoint(nMinutes ? gArgs.GetIntArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0);
381+
env->dbenv->txn_checkpoint(nMinutes ? m_database.m_max_log_mb * 1024 : 0, nMinutes, 0);
381382
}
382383
}
383384

@@ -831,13 +832,13 @@ std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, con
831832
{
832833
LOCK(cs_db); // Lock env.m_databases until insert in BerkeleyDatabase constructor
833834
std::string data_filename = fs::PathToString(data_file.filename());
834-
std::shared_ptr<BerkeleyEnvironment> env = GetBerkeleyEnv(data_file.parent_path());
835+
std::shared_ptr<BerkeleyEnvironment> env = GetBerkeleyEnv(data_file.parent_path(), options.use_shared_memory);
835836
if (env->m_databases.count(data_filename)) {
836837
error = Untranslated(strprintf("Refusing to load database. Data file '%s' is already loaded.", fs::PathToString(env->Directory() / data_filename)));
837838
status = DatabaseStatus::FAILED_ALREADY_LOADED;
838839
return nullptr;
839840
}
840-
db = std::make_unique<BerkeleyDatabase>(std::move(env), std::move(data_filename));
841+
db = std::make_unique<BerkeleyDatabase>(std::move(env), std::move(data_filename), options);
841842
}
842843

843844
if (options.verify && !db->Verify(error)) {

src/wallet/bdb.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
struct bilingual_str;
3333

3434
namespace wallet {
35-
static const unsigned int DEFAULT_WALLET_DBLOGSIZE = 100;
36-
static const bool DEFAULT_WALLET_PRIVDB = true;
3735

3836
struct WalletDatabaseFileId {
3937
u_int8_t value[DB_FILE_ID_LEN];
@@ -56,8 +54,9 @@ class BerkeleyEnvironment
5654
std::map<std::string, std::reference_wrapper<BerkeleyDatabase>> m_databases;
5755
std::unordered_map<std::string, WalletDatabaseFileId> m_fileids;
5856
std::condition_variable_any m_db_in_use;
57+
bool m_use_shared_memory;
5958

60-
explicit BerkeleyEnvironment(const fs::path& env_directory);
59+
explicit BerkeleyEnvironment(const fs::path& env_directory, bool use_shared_memory);
6160
BerkeleyEnvironment();
6261
~BerkeleyEnvironment();
6362
void Reset();
@@ -85,7 +84,7 @@ class BerkeleyEnvironment
8584
};
8685

8786
/** Get BerkeleyEnvironment given a directory path. */
88-
std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory);
87+
std::shared_ptr<BerkeleyEnvironment> GetBerkeleyEnv(const fs::path& env_directory, bool use_shared_memory);
8988

9089
class BerkeleyBatch;
9190

@@ -98,8 +97,8 @@ class BerkeleyDatabase : public WalletDatabase
9897
BerkeleyDatabase() = delete;
9998

10099
/** Create DB handle to real database */
101-
BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, std::string filename) :
102-
WalletDatabase(), env(std::move(env)), strFile(std::move(filename))
100+
BerkeleyDatabase(std::shared_ptr<BerkeleyEnvironment> env, std::string filename, const DatabaseOptions& options) :
101+
WalletDatabase(), env(std::move(env)), strFile(std::move(filename)), m_max_log_mb(options.max_log_mb)
103102
{
104103
auto inserted = this->env->m_databases.emplace(strFile, std::ref(*this));
105104
assert(inserted.second);
@@ -160,6 +159,7 @@ class BerkeleyDatabase : public WalletDatabase
160159
std::unique_ptr<Db> m_db;
161160

162161
std::string strFile;
162+
int64_t m_max_log_mb;
163163

164164
/** Make a BerkeleyBatch connected to this database */
165165
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;

src/wallet/db.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <chainparams.h>
77
#include <fs.h>
88
#include <logging.h>
9+
#include <util/system.h>
910
#include <wallet/db.h>
1011

1112
#include <exception>
@@ -137,4 +138,13 @@ bool IsSQLiteFile(const fs::path& path)
137138
// Check the application id matches our network magic
138139
return memcmp(Params().MessageStart(), app_id, 4) == 0;
139140
}
141+
142+
void ReadDatabaseArgs(const ArgsManager& args, DatabaseOptions& options)
143+
{
144+
// Override current options with args values, if any were specified
145+
options.use_unsafe_sync = args.GetBoolArg("-unsafesqlitesync", options.use_unsafe_sync);
146+
options.use_shared_memory = !args.GetBoolArg("-privdb", !options.use_shared_memory);
147+
options.max_log_mb = args.GetIntArg("-dblogsize", options.max_log_mb);
148+
}
149+
140150
} // namespace wallet

src/wallet/db.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <optional>
1717
#include <string>
1818

19+
class ArgsManager;
1920
struct bilingual_str;
2021

2122
namespace wallet {
@@ -207,7 +208,12 @@ struct DatabaseOptions {
207208
std::optional<DatabaseFormat> require_format;
208209
uint64_t create_flags = 0;
209210
SecureString create_passphrase;
210-
bool verify = true;
211+
212+
// Specialized options. Not every option is supported by every backend.
213+
bool verify = true; //!< Check data integrity on load.
214+
bool use_unsafe_sync = false; //!< Disable file sync for faster performance.
215+
bool use_shared_memory = false; //!< Let other processes access the database.
216+
int64_t max_log_mb = 100; //!< Max log size to allow before consolidating.
211217
};
212218

213219
enum class DatabaseStatus {
@@ -227,6 +233,7 @@ enum class DatabaseStatus {
227233
/** Recursively list database paths in directory. */
228234
std::vector<fs::path> ListDatabases(const fs::path& path);
229235

236+
void ReadDatabaseArgs(const ArgsManager& args, DatabaseOptions& options);
230237
std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
231238

232239
fs::path BDBDataFile(const fs::path& path);

src/wallet/dump.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ namespace wallet {
1919
static const std::string DUMP_MAGIC = "BITCOIN_CORE_WALLET_DUMP";
2020
uint32_t DUMP_VERSION = 1;
2121

22-
bool DumpWallet(CWallet& wallet, bilingual_str& error)
22+
bool DumpWallet(const ArgsManager& args, CWallet& wallet, bilingual_str& error)
2323
{
2424
// Get the dumpfile
25-
std::string dump_filename = gArgs.GetArg("-dumpfile", "");
25+
std::string dump_filename = args.GetArg("-dumpfile", "");
2626
if (dump_filename.empty()) {
2727
error = _("No dump file provided. To use dump, -dumpfile=<filename> must be provided.");
2828
return false;
@@ -114,10 +114,10 @@ static void WalletToolReleaseWallet(CWallet* wallet)
114114
delete wallet;
115115
}
116116

117-
bool CreateFromDump(const std::string& name, const fs::path& wallet_path, bilingual_str& error, std::vector<bilingual_str>& warnings)
117+
bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs::path& wallet_path, bilingual_str& error, std::vector<bilingual_str>& warnings)
118118
{
119119
// Get the dumpfile
120-
std::string dump_filename = gArgs.GetArg("-dumpfile", "");
120+
std::string dump_filename = args.GetArg("-dumpfile", "");
121121
if (dump_filename.empty()) {
122122
error = _("No dump file provided. To use createfromdump, -dumpfile=<filename> must be provided.");
123123
return false;
@@ -171,7 +171,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
171171
return false;
172172
}
173173
// Get the data file format with format_value as the default
174-
std::string file_format = gArgs.GetArg("-format", format_value);
174+
std::string file_format = args.GetArg("-format", format_value);
175175
if (file_format.empty()) {
176176
error = _("No wallet file format provided. To use createfromdump, -format=<format> must be provided.");
177177
return false;
@@ -193,6 +193,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
193193

194194
DatabaseOptions options;
195195
DatabaseStatus status;
196+
ReadDatabaseArgs(args, options);
196197
options.require_create = true;
197198
options.require_format = data_format;
198199
std::unique_ptr<WalletDatabase> database = MakeDatabase(wallet_path, options, status, error);

src/wallet/dump.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@
1111
#include <vector>
1212

1313
struct bilingual_str;
14+
class ArgsManager;
1415

1516
namespace wallet {
1617
class CWallet;
17-
bool DumpWallet(CWallet& wallet, bilingual_str& error);
18-
bool CreateFromDump(const std::string& name, const fs::path& wallet_path, bilingual_str& error, std::vector<bilingual_str>& warnings);
18+
bool DumpWallet(const ArgsManager& args, CWallet& wallet, bilingual_str& error);
19+
bool CreateFromDump(const ArgsManager& args, const std::string& name, const fs::path& wallet_path, bilingual_str& error, std::vector<bilingual_str>& warnings);
1920
} // namespace wallet
2021

2122
#endif // BITCOIN_WALLET_DUMP_H

src/wallet/init.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ void WalletInit::AddWalletOptions(ArgsManager& argsman) const
8080
argsman.AddArg("-walletrbf", strprintf("Send transactions with full-RBF opt-in enabled (RPC only, default: %u)", DEFAULT_WALLET_RBF), ArgsManager::ALLOW_ANY, OptionsCategory::WALLET);
8181

8282
#ifdef USE_BDB
83-
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);
83+
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);
8484
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);
85-
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);
85+
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);
8686
#else
8787
argsman.AddHiddenArgs({"-dblogsize", "-flushwallet", "-privdb"});
8888
#endif

src/wallet/interfaces.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ class WalletLoaderImpl : public WalletLoader
544544
std::shared_ptr<CWallet> wallet;
545545
DatabaseOptions options;
546546
DatabaseStatus status;
547+
ReadDatabaseArgs(*m_context.args, options);
547548
options.require_create = true;
548549
options.create_flags = wallet_creation_flags;
549550
options.create_passphrase = passphrase;
@@ -553,6 +554,7 @@ class WalletLoaderImpl : public WalletLoader
553554
{
554555
DatabaseOptions options;
555556
DatabaseStatus status;
557+
ReadDatabaseArgs(*m_context.args, options);
556558
options.require_existing = true;
557559
return MakeWallet(m_context, LoadWallet(m_context, name, true /* load_on_start */, options, status, error, warnings));
558560
}

src/wallet/load.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ bool VerifyWallets(WalletContext& context)
5757
if (!args.IsArgSet("wallet")) {
5858
DatabaseOptions options;
5959
DatabaseStatus status;
60+
ReadDatabaseArgs(args, options);
6061
bilingual_str error_string;
6162
options.require_existing = true;
6263
options.verify = false;
@@ -84,6 +85,7 @@ bool VerifyWallets(WalletContext& context)
8485

8586
DatabaseOptions options;
8687
DatabaseStatus status;
88+
ReadDatabaseArgs(args, options);
8789
options.require_existing = true;
8890
options.verify = true;
8991
bilingual_str error_string;
@@ -112,6 +114,7 @@ bool LoadWallets(WalletContext& context)
112114
}
113115
DatabaseOptions options;
114116
DatabaseStatus status;
117+
ReadDatabaseArgs(*context.args, options);
115118
options.require_existing = true;
116119
options.verify = false; // No need to verify, assuming verified earlier in VerifyWallets()
117120
bilingual_str error;

src/wallet/rpc/wallet.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <rpc/server.h>
99
#include <rpc/util.h>
1010
#include <util/translation.h>
11+
#include <wallet/context.h>
1112
#include <wallet/receive.h>
1213
#include <wallet/rpc/wallet.h>
1314
#include <wallet/rpc/util.h>
@@ -218,6 +219,7 @@ static RPCHelpMan loadwallet()
218219

219220
DatabaseOptions options;
220221
DatabaseStatus status;
222+
ReadDatabaseArgs(*context.args, options);
221223
options.require_existing = true;
222224
bilingual_str error;
223225
std::vector<bilingual_str> warnings;
@@ -377,6 +379,7 @@ static RPCHelpMan createwallet()
377379

378380
DatabaseOptions options;
379381
DatabaseStatus status;
382+
ReadDatabaseArgs(*context.args, options);
380383
options.require_create = true;
381384
options.create_flags = flags;
382385
options.create_passphrase = passphrase;

src/wallet/salvage.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ static bool KeyFilter(const std::string& type)
2323
return WalletBatch::IsKeyType(type) || type == DBKeys::HDCHAIN;
2424
}
2525

26-
bool RecoverDatabaseFile(const fs::path& file_path, bilingual_str& error, std::vector<bilingual_str>& warnings)
26+
bool RecoverDatabaseFile(const ArgsManager& args, const fs::path& file_path, bilingual_str& error, std::vector<bilingual_str>& warnings)
2727
{
2828
DatabaseOptions options;
2929
DatabaseStatus status;
30+
ReadDatabaseArgs(args, options);
3031
options.require_existing = true;
3132
options.verify = false;
3233
options.require_format = DatabaseFormat::BERKELEY;

src/wallet/salvage.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
#include <fs.h>
1010
#include <streams.h>
1111

12+
class ArgsManager;
1213
struct bilingual_str;
1314

1415
namespace wallet {
15-
bool RecoverDatabaseFile(const fs::path& file_path, bilingual_str& error, std::vector<bilingual_str>& warnings);
16+
bool RecoverDatabaseFile(const ArgsManager& args, const fs::path& file_path, bilingual_str& error, std::vector<bilingual_str>& warnings);
1617
} // namespace wallet
1718

1819
#endif // BITCOIN_WALLET_SALVAGE_H

src/wallet/sqlite.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ static void SetPragma(sqlite3* db, const std::string& key, const std::string& va
6767
}
6868
}
6969

70-
SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, bool mock)
71-
: WalletDatabase(), m_mock(mock), m_dir_path(fs::PathToString(dir_path)), m_file_path(fs::PathToString(file_path))
70+
SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, const DatabaseOptions& options, bool mock)
71+
: 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)
7272
{
7373
{
7474
LOCK(g_sqlite_mutex);
@@ -239,7 +239,7 @@ void SQLiteDatabase::Open()
239239
// Enable fullfsync for the platforms that use it
240240
SetPragma(m_db, "fullfsync", "true", "Failed to enable fullfsync");
241241

242-
if (gArgs.GetBoolArg("-unsafesqlitesync", false)) {
242+
if (m_use_unsafe_sync) {
243243
// Use normal synchronous mode for the journal
244244
LogPrintf("WARNING SQLite is configured to not wait for data to be flushed to disk. Data loss and corruption may occur.\n");
245245
SetPragma(m_db, "synchronous", "OFF", "Failed to set synchronous mode to OFF");
@@ -561,7 +561,7 @@ std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const D
561561
{
562562
try {
563563
fs::path data_file = SQLiteDataFile(path);
564-
auto db = std::make_unique<SQLiteDatabase>(data_file.parent_path(), data_file);
564+
auto db = std::make_unique<SQLiteDatabase>(data_file.parent_path(), data_file, options);
565565
if (options.verify && !db->Verify(error)) {
566566
status = DatabaseStatus::FAILED_VERIFY;
567567
return nullptr;

src/wallet/sqlite.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class SQLiteDatabase : public WalletDatabase
6969
SQLiteDatabase() = delete;
7070

7171
/** Create DB handle to real database */
72-
SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, bool mock = false);
72+
SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, const DatabaseOptions& options, bool mock = false);
7373

7474
~SQLiteDatabase();
7575

@@ -113,6 +113,7 @@ class SQLiteDatabase : public WalletDatabase
113113
std::unique_ptr<DatabaseBatch> MakeBatch(bool flush_on_close = true) override;
114114

115115
sqlite3* m_db{nullptr};
116+
bool m_use_unsafe_sync;
116117
};
117118

118119
std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);

0 commit comments

Comments
 (0)