mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-03-20 20:49:50 +01:00
To avoid wasting processing power, we can skip blocks that occurred before the wallet's creation time, since these blocks are guaranteed not to contain any relevant wallet data. This has direct implications (an speed improvement) on the underlying blockchain synchronization process as well. The reason is that the validation interface queue is limited to 10 tasks per time. This means that no more than 10 blocks can be waiting for the wallet(s) to be processed while we are synchronizing the chain (activating the best chain to be more precise). Which can be a bottleneck if blocks arrive and are processed faster from the network than what they are processed by the wallet(s).
70 lines
3.0 KiB
C++
70 lines
3.0 KiB
C++
// Copyright (c) 2012-2022 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include <bench/bench.h>
|
|
#include <interfaces/chain.h>
|
|
#include <node/chainstate.h>
|
|
#include <node/context.h>
|
|
#include <test/util/mining.h>
|
|
#include <test/util/setup_common.h>
|
|
#include <wallet/test/util.h>
|
|
#include <validationinterface.h>
|
|
#include <wallet/receive.h>
|
|
#include <wallet/wallet.h>
|
|
|
|
#include <optional>
|
|
|
|
using wallet::CWallet;
|
|
using wallet::CreateMockableWalletDatabase;
|
|
using wallet::DBErrors;
|
|
using wallet::GetBalance;
|
|
using wallet::WALLET_FLAG_DESCRIPTORS;
|
|
|
|
const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj";
|
|
|
|
static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const bool add_mine)
|
|
{
|
|
const auto test_setup = MakeNoLogFileContext<const TestingSetup>();
|
|
|
|
const auto& ADDRESS_WATCHONLY = ADDRESS_BCRT1_UNSPENDABLE;
|
|
|
|
// Set clock to genesis block, so the descriptors/keys creation time don't interfere with the blocks scanning process.
|
|
// The reason is 'generatetoaddress', which creates a chain with deterministic timestamps in the past.
|
|
SetMockTime(test_setup->m_node.chainman->GetParams().GenesisBlock().nTime);
|
|
CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockableWalletDatabase()};
|
|
{
|
|
LOCK(wallet.cs_wallet);
|
|
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
|
|
wallet.SetupDescriptorScriptPubKeyMans();
|
|
if (wallet.LoadWallet() != DBErrors::LOAD_OK) assert(false);
|
|
}
|
|
auto handler = test_setup->m_node.chain->handleNotifications({&wallet, [](CWallet*) {}});
|
|
|
|
const std::optional<std::string> address_mine{add_mine ? std::optional<std::string>{getnewaddress(wallet)} : std::nullopt};
|
|
|
|
for (int i = 0; i < 100; ++i) {
|
|
generatetoaddress(test_setup->m_node, address_mine.value_or(ADDRESS_WATCHONLY));
|
|
generatetoaddress(test_setup->m_node, ADDRESS_WATCHONLY);
|
|
}
|
|
SyncWithValidationInterfaceQueue();
|
|
|
|
auto bal = GetBalance(wallet); // Cache
|
|
|
|
bench.run([&] {
|
|
if (set_dirty) wallet.MarkDirty();
|
|
bal = GetBalance(wallet);
|
|
if (add_mine) assert(bal.m_mine_trusted > 0);
|
|
});
|
|
}
|
|
|
|
static void WalletBalanceDirty(benchmark::Bench& bench) { WalletBalance(bench, /*set_dirty=*/true, /*add_mine=*/true); }
|
|
static void WalletBalanceClean(benchmark::Bench& bench) { WalletBalance(bench, /*set_dirty=*/false, /*add_mine=*/true); }
|
|
static void WalletBalanceMine(benchmark::Bench& bench) { WalletBalance(bench, /*set_dirty=*/false, /*add_mine=*/true); }
|
|
static void WalletBalanceWatch(benchmark::Bench& bench) { WalletBalance(bench, /*set_dirty=*/false, /*add_mine=*/false); }
|
|
|
|
BENCHMARK(WalletBalanceDirty, benchmark::PriorityLevel::HIGH);
|
|
BENCHMARK(WalletBalanceClean, benchmark::PriorityLevel::HIGH);
|
|
BENCHMARK(WalletBalanceMine, benchmark::PriorityLevel::HIGH);
|
|
BENCHMARK(WalletBalanceWatch, benchmark::PriorityLevel::HIGH);
|