Bitcoin Core  24.1.0
P2P Digital Currency
wallet_loading.cpp
Go to the documentation of this file.
1 // Copyright (c) 2022 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <bench/bench.h>
6 #include <interfaces/chain.h>
7 #include <node/context.h>
8 #include <test/util/mining.h>
10 #include <test/util/wallet.h>
11 #include <util/translation.h>
12 #include <validationinterface.h>
13 #include <wallet/context.h>
14 #include <wallet/receive.h>
15 #include <wallet/wallet.h>
16 
17 #include <optional>
18 
19 using wallet::CWallet;
26 
27 static const std::shared_ptr<CWallet> BenchLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, DatabaseOptions& options)
28 {
30  std::vector<bilingual_str> warnings;
31  auto wallet = CWallet::Create(context, "", std::move(database), options.create_flags, error, warnings);
33  if (context.chain) {
34  wallet->postInitProcess();
35  }
36  return wallet;
37 }
38 
39 static void BenchUnloadWallet(std::shared_ptr<CWallet>&& wallet)
40 {
42  wallet->m_chain_notifications_handler.reset();
43  UnloadWallet(std::move(wallet));
44 }
45 
46 static void AddTx(CWallet& wallet)
47 {
49  mtx.vout.push_back({COIN, GetScriptForDestination(*Assert(wallet.GetNewDestination(OutputType::BECH32, "")))});
50  mtx.vin.push_back(CTxIn());
51 
52  wallet.AddToWallet(MakeTransactionRef(mtx), TxStateInactive{});
53 }
54 
55 static std::unique_ptr<WalletDatabase> DuplicateMockDatabase(WalletDatabase& database, DatabaseOptions& options)
56 {
57  auto new_database = CreateMockWalletDatabase(options);
58 
59  // Get a cursor to the original database
60  auto batch = database.MakeBatch();
61  batch->StartCursor();
62 
63  // Get a batch for the new database
64  auto new_batch = new_database->MakeBatch();
65 
66  // Read all records from the original database and write them to the new one
67  while (true) {
70  bool complete;
71  batch->ReadAtCursor(key, value, complete);
72  if (complete) break;
73  new_batch->Write(key, value);
74  }
75 
76  return new_database;
77 }
78 
79 static void WalletLoading(benchmark::Bench& bench, bool legacy_wallet)
80 {
81  const auto test_setup = MakeNoLogFileContext<TestingSetup>();
82  test_setup->m_args.ForceSetArg("-unsafesqlitesync", "1");
83 
85  context.args = &test_setup->m_args;
86  context.chain = test_setup->m_node.chain.get();
87 
88  // Setup the wallet
89  // Loading the wallet will also create it
90  DatabaseOptions options;
91  if (legacy_wallet) {
92  options.require_format = DatabaseFormat::BERKELEY;
93  } else {
95  options.require_format = DatabaseFormat::SQLITE;
96  }
97  auto database = CreateMockWalletDatabase(options);
98  auto wallet = BenchLoadWallet(std::move(database), context, options);
99 
100  // Generate a bunch of transactions and addresses to put into the wallet
101  for (int i = 0; i < 1000; ++i) {
102  AddTx(*wallet);
103  }
104 
105  database = DuplicateMockDatabase(wallet->GetDatabase(), options);
106 
107  // reload the wallet for the actual benchmark
108  BenchUnloadWallet(std::move(wallet));
109 
110  bench.epochs(5).run([&] {
111  wallet = BenchLoadWallet(std::move(database), context, options);
112 
113  // Cleanup
114  database = DuplicateMockDatabase(wallet->GetDatabase(), options);
115  BenchUnloadWallet(std::move(wallet));
116  });
117 }
118 
119 #ifdef USE_BDB
120 static void WalletLoadingLegacy(benchmark::Bench& bench) { WalletLoading(bench, /*legacy_wallet=*/true); }
121 BENCHMARK(WalletLoadingLegacy);
122 #endif
123 
124 #ifdef USE_SQLITE
125 static void WalletLoadingDescriptors(benchmark::Bench& bench) { WalletLoading(bench, /*legacy_wallet=*/false); }
126 BENCHMARK(WalletLoadingDescriptors);
127 #endif
std::optional< DatabaseFormat > require_format
Definition: db.h:208
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
#define BENCHMARK(n)
Definition: bench.h:67
Bilingual messages:
Definition: translation.h:18
std::vector< CTxIn > vin
Definition: transaction.h:374
State of transaction not confirmed or conflicting with a known block and not in the mempool...
Definition: transaction.h:48
static void BenchUnloadWallet(std::shared_ptr< CWallet > &&wallet)
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:185
static const std::shared_ptr< CWallet > BenchLoadWallet(std::unique_ptr< WalletDatabase > database, WalletContext &context, DatabaseOptions &options)
Bench & run(char const *benchmarkName, Op &&op)
Repeatedly calls op() based on the configuration, and performs measurements.
Definition: nanobench.h:1183
std::unique_ptr< WalletDatabase > CreateMockWalletDatabase(DatabaseOptions &options)
Return object for accessing temporary in-memory database.
Definition: walletdb.cpp:1242
uint64_t create_flags
Definition: db.h:209
An input of a transaction.
Definition: transaction.h:73
void NotifyWalletLoaded(WalletContext &context, const std::shared_ptr< CWallet > &wallet)
Definition: wallet.cpp:177
Indicate that this wallet supports DescriptorScriptPubKeyMan.
Definition: walletutil.h:66
WalletContext context
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:235
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:334
static void WalletLoading(benchmark::Bench &bench, bool legacy_wallet)
std::vector< CTxOut > vout
Definition: transaction.h:375
Definition: node.h:39
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
Definition: wallet.cpp:209
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:415
static std::unique_ptr< WalletDatabase > DuplicateMockDatabase(WalletDatabase &database, DatabaseOptions &options)
DatabaseFormat
Definition: db.h:200
Bench & epochs(size_t numEpochs) noexcept
Controls number of epochs, the number of measurements to perform.
WalletContext struct containing references to state shared between CWallet instances, like the reference to the chain interface, and the list of opened wallets.
Definition: context.h:35
static void AddTx(CWallet &wallet)
interfaces::Chain * chain
Definition: context.h:36
virtual std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true)=0
Make a DatabaseBatch connected to this database.
A mutable version of CTransaction.
Definition: transaction.h:372
Main entry point to nanobench&#39;s benchmarking facility.
Definition: nanobench.h:616
std::shared_ptr< CWallet > wallet
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
ArgsManager * args
Definition: context.h:37
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
An instance of this class represents one database.
Definition: db.h:105
#define Assert(val)
Identity function.
Definition: check.h:74
static constexpr CAmount COIN
The amount of satoshis in one BTC.
Definition: amount.h:15