Skip to content

Commit 8775731

Browse files
committed
Merge bitcoin#31241: wallet: remove BDB dependency from wallet migration benchmark
18619b4 wallet: remove BDB dependency from wallet migration benchmark (furszy) Pull request description: Part of the legacy wallet removal working path bitcoin#20160. Stops creating a bdb database in the wallet migration benchmark. Instead, the benchmark now creates the db in memory and re-uses it for the migration process. ACKs for top commit: achow101: ACK 18619b4 brunoerg: code review ACK 18619b4 theStack: Code-review ACK 18619b4 Tree-SHA512: a107deee3d2c00b980e3606be07d038ca524b98251442956d702a7996e2ac5e2901f656482018cacbac8ef6a628ac1fb03f677d1658aeaded4036d834a95d7e0
2 parents 9ecc7af + 18619b4 commit 8775731

File tree

3 files changed

+38
-25
lines changed

3 files changed

+38
-25
lines changed

src/bench/wallet_migration.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <bitcoin-build-config.h> // IWYU pragma: keep
66

77
#include <bench/bench.h>
8+
#include <kernel/chain.h>
89
#include <interfaces/chain.h>
910
#include <node/context.h>
1011
#include <test/util/mining.h>
@@ -16,7 +17,7 @@
1617

1718
#include <optional>
1819

19-
#if defined(USE_BDB) && defined(USE_SQLITE) // only enable benchmark when bdb and sqlite are enabled
20+
#if defined(USE_SQLITE) // only enable benchmark when sqlite is enabled
2021

2122
namespace wallet{
2223

@@ -32,41 +33,39 @@ static void WalletMigration(benchmark::Bench& bench)
3233
int NUM_WATCH_ONLY_ADDR = 20;
3334

3435
// Setup legacy wallet
35-
DatabaseOptions options;
36-
options.use_unsafe_sync = true;
37-
options.verify = false;
38-
DatabaseStatus status;
39-
bilingual_str error;
40-
auto database = MakeWalletDatabase(fs::PathToString(test_setup->m_path_root / "legacy"), options, status, error);
41-
uint64_t create_flags = 0;
42-
auto wallet = TestLoadWallet(std::move(database), context, create_flags);
36+
std::unique_ptr<CWallet> wallet = std::make_unique<CWallet>(test_setup->m_node.chain.get(), "", CreateMockableWalletDatabase());
37+
wallet->chainStateFlushed(ChainstateRole::NORMAL, CBlockLocator{});
38+
LegacyDataSPKM* legacy_spkm = wallet->GetOrCreateLegacyDataSPKM();
4339

4440
// Add watch-only addresses
4541
std::vector<CScript> scripts_watch_only;
4642
for (int w = 0; w < NUM_WATCH_ONLY_ADDR; ++w) {
4743
CKey key = GenerateRandomKey();
4844
LOCK(wallet->cs_wallet);
49-
const CScript& script = scripts_watch_only.emplace_back(GetScriptForDestination(GetDestinationForKey(key.GetPubKey(), OutputType::LEGACY)));
50-
bool res = wallet->ImportScriptPubKeys(strprintf("watch_%d", w), {script},
51-
/*have_solving_data=*/false, /*apply_label=*/true, /*timestamp=*/1);
52-
assert(res);
45+
const auto& dest = GetDestinationForKey(key.GetPubKey(), OutputType::LEGACY);
46+
const CScript& script = scripts_watch_only.emplace_back(GetScriptForDestination(dest));
47+
assert(legacy_spkm->LoadWatchOnly(script));
48+
assert(wallet->SetAddressBook(dest, strprintf("watch_%d", w), /*purpose=*/std::nullopt));
5349
}
5450

5551
// Generate transactions and local addresses
56-
for (int j = 0; j < 400; ++j) {
52+
for (int j = 0; j < 500; ++j) {
53+
CKey key = GenerateRandomKey();
54+
CPubKey pubkey = key.GetPubKey();
55+
// Load key, scripts and create address book record
56+
Assert(legacy_spkm->LoadKey(key, pubkey));
57+
CTxDestination dest{PKHash(pubkey)};
58+
Assert(wallet->SetAddressBook(dest, strprintf("legacy_%d", j), /*purpose=*/std::nullopt));
59+
5760
CMutableTransaction mtx;
58-
mtx.vout.emplace_back(COIN, GetScriptForDestination(*Assert(wallet->GetNewDestination(OutputType::BECH32, strprintf("bench_%d", j)))));
59-
mtx.vout.emplace_back(COIN, GetScriptForDestination(*Assert(wallet->GetNewDestination(OutputType::LEGACY, strprintf("legacy_%d", j)))));
61+
mtx.vout.emplace_back(COIN, GetScriptForDestination(dest));
6062
mtx.vout.emplace_back(COIN, scripts_watch_only.at(j % NUM_WATCH_ONLY_ADDR));
6163
mtx.vin.resize(2);
6264
wallet->AddToWallet(MakeTransactionRef(mtx), TxStateInactive{}, /*update_wtx=*/nullptr, /*fFlushOnClose=*/false, /*rescanning_old_block=*/true);
6365
}
6466

65-
// Unload so the migration process loads it
66-
TestUnloadWallet(std::move(wallet));
67-
68-
bench.epochs(/*numEpochs=*/1).run([&] {
69-
util::Result<MigrationResult> res = MigrateLegacyToDescriptor(fs::PathToString(test_setup->m_path_root / "legacy"), "", context);
67+
bench.epochs(/*numEpochs=*/1).run([&context, &wallet] {
68+
util::Result<MigrationResult> res = MigrateLegacyToDescriptor(std::move(wallet), /*passphrase=*/"", context, /*was_loaded=*/false);
7069
assert(res);
7170
assert(res->wallet);
7271
assert(res->watchonly_wallet);

src/wallet/wallet.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4398,9 +4398,8 @@ bool DoMigration(CWallet& wallet, WalletContext& context, bilingual_str& error,
43984398

43994399
util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& wallet_name, const SecureString& passphrase, WalletContext& context)
44004400
{
4401-
MigrationResult res;
4402-
bilingual_str error;
44034401
std::vector<bilingual_str> warnings;
4402+
bilingual_str error;
44044403

44054404
// If the wallet is still loaded, unload it so that nothing else tries to use it while we're changing it
44064405
bool was_loaded = false;
@@ -4452,10 +4451,23 @@ util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& walle
44524451
return util::Error{Untranslated("Wallet loading failed.") + Untranslated(" ") + error};
44534452
}
44544453

4454+
return MigrateLegacyToDescriptor(std::move(local_wallet), passphrase, context, was_loaded);
4455+
}
4456+
4457+
util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet> local_wallet, const SecureString& passphrase, WalletContext& context, bool was_loaded)
4458+
{
4459+
MigrationResult res;
4460+
bilingual_str error;
4461+
std::vector<bilingual_str> warnings;
4462+
4463+
DatabaseOptions options;
4464+
options.require_existing = true;
4465+
DatabaseStatus status;
4466+
4467+
const std::string wallet_name = local_wallet->GetName();
4468+
44554469
// Helper to reload as normal for some of our exit scenarios
44564470
const auto& reload_wallet = [&](std::shared_ptr<CWallet>& to_reload) {
4457-
// Reset options.require_format as wallets of any format may be reloaded.
4458-
options.require_format = std::nullopt;
44594471
assert(to_reload.use_count() == 1);
44604472
std::string name = to_reload->GetName();
44614473
to_reload.reset();

src/wallet/wallet.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,8 @@ struct MigrationResult {
11351135

11361136
//! Do all steps to migrate a legacy wallet to a descriptor wallet
11371137
[[nodiscard]] util::Result<MigrationResult> MigrateLegacyToDescriptor(const std::string& wallet_name, const SecureString& passphrase, WalletContext& context);
1138+
//! Requirement: The wallet provided to this function must be isolated, with no attachment to the node's context.
1139+
[[nodiscard]] util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet> local_wallet, const SecureString& passphrase, WalletContext& context, bool was_loaded);
11381140
} // namespace wallet
11391141

11401142
#endif // BITCOIN_WALLET_WALLET_H

0 commit comments

Comments
 (0)