Skip to content

Commit 480d806

Browse files
committed
Merge bitcoin#24924: bench: Make WalletLoading benchmark run faster
e673d8b bench: Enable loading benchmarks depending on what's compiled (Andrew Chow) 4af3547 bench: Use mock wallet database for wallet loading benchmark (Andrew Chow) 49910f2 sqlite: Use in-memory db instead of temp for mockdb (Andrew Chow) a108080 walletdb: Create a mock database of specific type (Andrew Chow) 7c0d344 bench: reduce the number of txs in wallet for wallet loading bench (Andrew Chow) f85b54e bench: Add transactions directly instead of mining blocks (Andrew Chow) d94244c bench: reduce number of epochs for wallet loading benchmark (Andrew Chow) 817c051 bench: use unsafesqlitesync in wallet loading benchmark (Andrew Chow) 9e404a9 bench: Remove minEpochIterations from wallet loading benchmark (Andrew Chow) Pull request description: `minEpochIterations` is probably unnecessary to set, so removing it makes the runtime much faster. ACKs for top commit: Rspigler: tACK e673d8b furszy: Code review ACK e673d8b, nice PR. glozow: Concept ACK e673d8b. For each commit, verified that there was a performance improvement without negating the purpose of the bench, and made some effort to verify that the code is correct. Tree-SHA512: 9337352ef846cf18642d5c14546c5abc1674b4975adb5dc961a1a276ca91f046b83b7a5e27ea6cd26264b96ae71151e14055579baf36afae7692ef4029800877
2 parents 2364d17 + e673d8b commit 480d806

File tree

3 files changed

+91
-17
lines changed

3 files changed

+91
-17
lines changed

src/bench/wallet_loading.cpp

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,19 @@
1717
#include <optional>
1818

1919
using wallet::CWallet;
20+
using wallet::DatabaseFormat;
2021
using wallet::DatabaseOptions;
21-
using wallet::DatabaseStatus;
2222
using wallet::ISMINE_SPENDABLE;
2323
using wallet::MakeWalletDatabase;
24+
using wallet::TxStateInactive;
2425
using wallet::WALLET_FLAG_DESCRIPTORS;
2526
using wallet::WalletContext;
27+
using wallet::WalletDatabase;
2628

27-
static const std::shared_ptr<CWallet> BenchLoadWallet(WalletContext& context, DatabaseOptions& options)
29+
static const std::shared_ptr<CWallet> BenchLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, DatabaseOptions& options)
2830
{
29-
DatabaseStatus status;
3031
bilingual_str error;
3132
std::vector<bilingual_str> warnings;
32-
auto database = MakeWalletDatabase("", options, status, error);
33-
assert(database);
3433
auto wallet = CWallet::Create(context, "", std::move(database), options.create_flags, error, warnings);
3534
NotifyWalletLoaded(context, wallet);
3635
if (context.chain) {
@@ -46,9 +45,47 @@ static void BenchUnloadWallet(std::shared_ptr<CWallet>&& wallet)
4645
UnloadWallet(std::move(wallet));
4746
}
4847

48+
static void AddTx(CWallet& wallet)
49+
{
50+
bilingual_str error;
51+
CTxDestination dest;
52+
wallet.GetNewDestination(OutputType::BECH32, "", dest, error);
53+
54+
CMutableTransaction mtx;
55+
mtx.vout.push_back({COIN, GetScriptForDestination(dest)});
56+
mtx.vin.push_back(CTxIn());
57+
58+
wallet.AddToWallet(MakeTransactionRef(mtx), TxStateInactive{});
59+
}
60+
61+
static std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database, DatabaseOptions& options)
62+
{
63+
auto new_database = CreateMockWalletDatabase(options);
64+
65+
// Get a cursor to the original database
66+
auto batch = database.MakeBatch();
67+
batch->StartCursor();
68+
69+
// Get a batch for the new database
70+
auto new_batch = new_database->MakeBatch();
71+
72+
// Read all records from the original database and write them to the new one
73+
while (true) {
74+
CDataStream key(SER_DISK, CLIENT_VERSION);
75+
CDataStream value(SER_DISK, CLIENT_VERSION);
76+
bool complete;
77+
batch->ReadAtCursor(key, value, complete);
78+
if (complete) break;
79+
new_batch->Write(key, value);
80+
}
81+
82+
return new_database;
83+
}
84+
4985
static void WalletLoading(benchmark::Bench& bench, bool legacy_wallet)
5086
{
5187
const auto test_setup = MakeNoLogFileContext<TestingSetup>();
88+
test_setup->m_args.ForceSetArg("-unsafesqlitesync", "1");
5289

5390
WalletContext context;
5491
context.args = &test_setup->m_args;
@@ -57,27 +94,40 @@ static void WalletLoading(benchmark::Bench& bench, bool legacy_wallet)
5794
// Setup the wallet
5895
// Loading the wallet will also create it
5996
DatabaseOptions options;
60-
if (!legacy_wallet) options.create_flags = WALLET_FLAG_DESCRIPTORS;
61-
auto wallet = BenchLoadWallet(context, options);
97+
if (legacy_wallet) {
98+
options.require_format = DatabaseFormat::BERKELEY;
99+
} else {
100+
options.create_flags = WALLET_FLAG_DESCRIPTORS;
101+
options.require_format = DatabaseFormat::SQLITE;
102+
}
103+
auto database = CreateMockWalletDatabase(options);
104+
auto wallet = BenchLoadWallet(std::move(database), context, options);
62105

63106
// Generate a bunch of transactions and addresses to put into the wallet
64-
for (int i = 0; i < 5000; ++i) {
65-
generatetoaddress(test_setup->m_node, getnewaddress(*wallet));
107+
for (int i = 0; i < 1000; ++i) {
108+
AddTx(*wallet);
66109
}
67110

111+
database = DuplicateMockDatabase(wallet->GetDatabase(), options);
112+
68113
// reload the wallet for the actual benchmark
69114
BenchUnloadWallet(std::move(wallet));
70115

71-
bench.minEpochIterations(10).run([&] {
72-
wallet = BenchLoadWallet(context, options);
116+
bench.epochs(5).run([&] {
117+
wallet = BenchLoadWallet(std::move(database), context, options);
73118

74119
// Cleanup
120+
database = DuplicateMockDatabase(wallet->GetDatabase(), options);
75121
BenchUnloadWallet(std::move(wallet));
76122
});
77123
}
78124

125+
#ifdef USE_BDB
79126
static void WalletLoadingLegacy(benchmark::Bench& bench) { WalletLoading(bench, /*legacy_wallet=*/true); }
80-
static void WalletLoadingDescriptors(benchmark::Bench& bench) { WalletLoading(bench, /*legacy_wallet=*/false); }
81-
82127
BENCHMARK(WalletLoadingLegacy);
128+
#endif
129+
130+
#ifdef USE_SQLITE
131+
static void WalletLoadingDescriptors(benchmark::Bench& bench) { WalletLoading(bench, /*legacy_wallet=*/false); }
83132
BENCHMARK(WalletLoadingDescriptors);
133+
#endif

src/wallet/walletdb.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,13 +1186,36 @@ std::unique_ptr<WalletDatabase> CreateDummyWalletDatabase()
11861186
}
11871187

11881188
/** Return object for accessing temporary in-memory database. */
1189-
std::unique_ptr<WalletDatabase> CreateMockWalletDatabase()
1189+
std::unique_ptr<WalletDatabase> CreateMockWalletDatabase(DatabaseOptions& options)
11901190
{
1191-
DatabaseOptions options;
1191+
1192+
std::optional<DatabaseFormat> format;
1193+
if (options.require_format) format = options.require_format;
1194+
if (!format) {
1195+
#ifdef USE_BDB
1196+
format = DatabaseFormat::BERKELEY;
1197+
#endif
11921198
#ifdef USE_SQLITE
1193-
return std::make_unique<SQLiteDatabase>("", "", options, true);
1194-
#elif USE_BDB
1199+
format = DatabaseFormat::SQLITE;
1200+
#endif
1201+
}
1202+
1203+
if (format == DatabaseFormat::SQLITE) {
1204+
#ifdef USE_SQLITE
1205+
return std::make_unique<SQLiteDatabase>(":memory:", "", options, true);
1206+
#endif
1207+
assert(false);
1208+
}
1209+
1210+
#ifdef USE_BDB
11951211
return std::make_unique<BerkeleyDatabase>(std::make_shared<BerkeleyEnvironment>(), "", options);
11961212
#endif
1213+
assert(false);
1214+
}
1215+
1216+
std::unique_ptr<WalletDatabase> CreateMockWalletDatabase()
1217+
{
1218+
DatabaseOptions options;
1219+
return CreateMockWalletDatabase(options);
11971220
}
11981221
} // namespace wallet

src/wallet/walletdb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, st
301301
std::unique_ptr<WalletDatabase> CreateDummyWalletDatabase();
302302

303303
/** Return object for accessing temporary in-memory database. */
304+
std::unique_ptr<WalletDatabase> CreateMockWalletDatabase(DatabaseOptions& options);
304305
std::unique_ptr<WalletDatabase> CreateMockWalletDatabase();
305306
} // namespace wallet
306307

0 commit comments

Comments
 (0)