bench: Utilize setup() in WalletEncrypt to create the encryption wallet
What changed, and why it matters
This is a benchmark-only code cleanup. It changes how a performance test creates a fresh wallet before each encryption run, replacing a database-copy approach with a setup() function that creates a new wallet each time. There is no change to production wallet encryption behavior and no security issue.
No security action needed. Review as normal code-quality/benchmark maintenance change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors src/bench/wallet_encrypt.cpp to use the benchmark framework’s setup() hook. Previously the benchmark duplicated the loaded wallet’s mock database and reloaded it for each iteration. Now it unloads any prior wallet and creates a new WalletDatabase + CWallet in setup(), then adds pre-generated descriptors. The actual EncryptWallet() call remains unchanged. This affects only test/benchmark code.
Changed components
src/bench/wallet_encrypt.cppInspect captured patch +34 / −35
diff --git a/src/bench/wallet_encrypt.cpp b/src/bench/wallet_encrypt.cpp
index 3d73081c..1f4db614 100644
--- a/src/bench/wallet_encrypt.cpp
+++ b/src/bench/wallet_encrypt.cpp
@@ -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);
-
- // Save a copy of the db before encrypting
- database = DuplicateMockDatabase(wallet->GetDatabase());
-
- wallet->EncryptWallet(secure_pass);
-
- for (const auto& [_, key] : wallet->mapMasterKeys){
- assert(key.nDeriveIterations == CMasterKey::DEFAULT_DERIVE_ITERATIONS);
- }
-
- TestUnloadWallet(std::move(wallet));
- });
+ std::unique_ptr<WalletDatabase> database;
+ std::shared_ptr<CWallet> wallet;
+ bench.batch(key_count).unit("key").setup([&] {
+ if (wallet) {
+ TestUnloadWallet(std::move(wallet));
+ }
+
+ std::unique_ptr<WalletDatabase> database = CreateMockableWalletDatabase();
+ wallet = TestCreateWallet(std::move(database), context, create_flags);
+
+ {
+ 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));
}
constexpr unsigned int KEY_COUNT = 2000;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.