Merge bitcoin/bitcoin#25234: bench: add benchmark for wallet 'AvailableCoins' function.

3a4f8bc24271d05765e9bf1e26558a28ab2e6b81 bench: add benchmark for wallet 'AvailableCoins' function. (furszy)

Pull request description:

  #### Rationale

  `AvailableCoins` is part of several important flows for the wallet; from RPC commands that create transactions like `fundrawtransaction`, `send`, `walletcreatefundedpsbt`, get the available balance, list the available coins with `listunspent` etc. to GUI connected processes that perform the same or similar actions: tx creation, available balance calculation, present the spendable coins in the coin control dialog.

  As we are improving this process in #24699, #25005 and there are more structural changes coming on the way. This benchmark aims to ensure us that, at least, there are no regressions (obviously performance improvements are great but, at least for me, this heads into the direction of having a base metric to compare future structural changes).

  #### Implementation Notes

  There are 5 new benchmarks, one per wallet supported output type (LEGACY, P2SH_SEGWIT, BECH32, BECH32M), plus a multi-output-type wallet benchmark which contains outputs from all the descriptor types.

  The test, by default, fills-up the wallet with 1k transactions, 2k outputs. Mainly to not consume much time if the user just want to verify that no substantial regressions were introduced. But, my expectation for those who are focused on this process is to use a much higher number locally to really note the differences across commits.

ACKs for top commit:
  achow101:
    ACK 3a4f8bc24271d05765e9bf1e26558a28ab2e6b81
  hernanmarino:
    ACK 3a4f8bc24271d05765e9bf1e26558a28ab2e6b81
  aureleoules:
    ACK 3a4f8bc24271d05765e9bf1e26558a28ab2e6b81

Tree-SHA512: d0bb4c165f1efa181b47cb31561e6217eff9135bcd1b6761a7292f9018e456d13d18a1b886c2e2268d35c52f9e1fd8e0f252972424e5c5f00c280620b79c5a1b
This commit is contained in:
Andrew Chow 2023-01-04 12:00:40 -05:00
commit 139ba2bf12
No known key found for this signature in database
GPG Key ID: 17565732E08E5E41

View File

@ -133,11 +133,51 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type
});
}
static void AvailableCoins(benchmark::Bench& bench, const std::vector<OutputType>& output_type)
{
const auto test_setup = MakeNoLogFileContext<const TestingSetup>();
CWallet wallet{test_setup->m_node.chain.get(), "", gArgs, CreateMockWalletDatabase()};
{
LOCK(wallet.cs_wallet);
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
wallet.SetupDescriptorScriptPubKeyMans();
if (wallet.LoadWallet() != DBErrors::LOAD_OK) assert(false);
}
// Generate destinations
std::vector<CScript> dest_wallet;
for (auto type : output_type) {
dest_wallet.emplace_back(GetScriptForDestination(getNewDestination(wallet, type)));
}
// Generate chain; each coinbase will have two outputs to fill-up the wallet
const auto& params = Params();
unsigned int chain_size = 1000;
for (unsigned int i = 0; i < chain_size / dest_wallet.size(); ++i) {
for (const auto& dest : dest_wallet) {
generateFakeBlock(params, test_setup->m_node, wallet, dest);
}
}
// Check available balance
auto bal = wallet::GetAvailableBalance(wallet); // Cache
assert(bal == 50 * COIN * (chain_size - COINBASE_MATURITY));
bench.epochIterations(2).run([&] {
LOCK(wallet.cs_wallet);
const auto& res = wallet::AvailableCoins(wallet);
assert(res.All().size() == (chain_size - COINBASE_MATURITY) * 2);
});
}
static void WalletCreateTxUseOnlyPresetInputs(benchmark::Bench& bench) { WalletCreateTx(bench, OutputType::BECH32, /*allow_other_inputs=*/false,
{{/*num_of_internal_inputs=*/4}}); }
static void WalletCreateTxUsePresetInputsAndCoinSelection(benchmark::Bench& bench) { WalletCreateTx(bench, OutputType::BECH32, /*allow_other_inputs=*/true,
{{/*num_of_internal_inputs=*/4}}); }
static void WalletAvailableCoins(benchmark::Bench& bench) { AvailableCoins(bench, {OutputType::BECH32M}); }
BENCHMARK(WalletCreateTxUseOnlyPresetInputs, benchmark::PriorityLevel::LOW)
BENCHMARK(WalletCreateTxUsePresetInputsAndCoinSelection, benchmark::PriorityLevel::LOW)
BENCHMARK(WalletAvailableCoins, benchmark::PriorityLevel::LOW);