bench: Utilize setup() in WalletEncrypt to create the encryption wallet

WalletEncrypt needs an unencrypted wallet in order for the benchmark to
encrypt a wallet. This was previously achieved by duplicating the
contents of an initial wallet for each run of the benchmark. We can
instead use setup() to unload the previously loaded wallet and then
create a new wallet with unencrypted keys.
This commit is contained in:
Ava Chow
2026-04-29 14:32:35 -07:00
parent d672455d20
commit 426a94e7bd

View File

@@ -30,48 +30,47 @@ static void WalletEncrypt(benchmark::Bench& bench, unsigned int key_count)
context.chain = test_setup->m_node.chain.get();
uint64_t create_flags = WALLET_FLAG_DESCRIPTORS;
auto database = CreateMockableWalletDatabase();
auto wallet = TestCreateWallet(std::move(database), context, create_flags);
{
LOCK(wallet->cs_wallet);
for (unsigned int i = 0; i < key_count; i++) {
CKey key = GenerateRandomKey();
FlatSigningProvider keys;
std::string error;
std::vector<std::unique_ptr<Descriptor>> desc = Parse("combo(" + EncodeSecret(key) + ")", keys, error, /*require_checksum=*/false);
WalletDescriptor w_desc(std::move(desc.at(0)), /*creation_time=*/0, /*range_start=*/0, /*range_end=*/0, /*next_index=*/0);
Assert(wallet->AddWalletDescriptor(w_desc, keys, /*label=*/"", /*internal=*/false));
}
std::vector<std::pair<WalletDescriptor, FlatSigningProvider>> descs;
descs.reserve(key_count);
for (unsigned int i = 0; i < key_count; i++) {
CKey key = GenerateRandomKey();
FlatSigningProvider keys;
std::string error;
std::vector<std::unique_ptr<Descriptor>> desc = Parse("combo(" + EncodeSecret(key) + ")", keys, error, /*require_checksum=*/false);
WalletDescriptor w_desc(std::move(desc.at(0)), /*creation_time=*/0, /*range_start=*/0, /*range_end=*/0, /*next_index=*/0);
descs.emplace_back(w_desc, keys);
}
database = DuplicateMockDatabase(wallet->GetDatabase());
// reload the wallet for the actual benchmark
TestUnloadWallet(std::move(wallet));
// Setting a mock time is necessary to force default derive iteration count during
// wallet encryption.
SetMockTime(1);
// This benchmark has a lot of overhead, this should be good enough to catch
// any regressions, but for an accurate measurement of how long wallet
// encryption takes, this should be reworked after something like
// https://github.com/bitcoin/bitcoin/pull/34208 is merged.
bench.batch(key_count).unit("key").run([&] {
wallet = TestLoadWallet(std::move(database), context);
std::unique_ptr<WalletDatabase> database;
std::shared_ptr<CWallet> wallet;
bench.batch(key_count).unit("key").setup([&] {
if (wallet) {
TestUnloadWallet(std::move(wallet));
}
// Save a copy of the db before encrypting
database = DuplicateMockDatabase(wallet->GetDatabase());
std::unique_ptr<WalletDatabase> database = CreateMockableWalletDatabase();
wallet = TestCreateWallet(std::move(database), context, create_flags);
wallet->EncryptWallet(secure_pass);
{
LOCK(wallet->cs_wallet);
for (auto& [desc, keys] : descs) {
Assert(wallet->AddWalletDescriptor(desc, keys, /*label=*/"", /*internal=*/false));
}
}
})
.run([&] {
wallet->EncryptWallet(secure_pass);
for (const auto& [_, key] : wallet->mapMasterKeys){
assert(key.nDeriveIterations == CMasterKey::DEFAULT_DERIVE_ITERATIONS);
}
TestUnloadWallet(std::move(wallet));
});
for (const auto& [_, key] : wallet->mapMasterKeys){
assert(key.nDeriveIterations == CMasterKey::DEFAULT_DERIVE_ITERATIONS);
}
});
TestUnloadWallet(std::move(wallet));
}
constexpr unsigned int KEY_COUNT = 2000;