diff options
Diffstat (limited to 'src/bench')
-rw-r--r-- | src/bench/addrman.cpp | 38 | ||||
-rw-r--r-- | src/bench/bench.cpp | 2 | ||||
-rw-r--r-- | src/bench/bench.h | 2 | ||||
-rw-r--r-- | src/bench/bench_bitcoin.cpp | 4 | ||||
-rw-r--r-- | src/bench/bip324_ecdh.cpp | 51 | ||||
-rw-r--r-- | src/bench/block_assemble.cpp | 2 | ||||
-rw-r--r-- | src/bench/checkblock.cpp | 5 | ||||
-rw-r--r-- | src/bench/checkqueue.cpp | 2 | ||||
-rw-r--r-- | src/bench/coin_selection.cpp | 8 | ||||
-rw-r--r-- | src/bench/ellswift.cpp | 31 | ||||
-rw-r--r-- | src/bench/load_external.cpp | 3 | ||||
-rw-r--r-- | src/bench/lockedpool.cpp | 4 | ||||
-rw-r--r-- | src/bench/logging.cpp | 3 | ||||
-rw-r--r-- | src/bench/mempool_stress.cpp | 5 | ||||
-rw-r--r-- | src/bench/pool.cpp | 50 | ||||
-rw-r--r-- | src/bench/rpc_blockchain.cpp | 3 | ||||
-rw-r--r-- | src/bench/rpc_mempool.cpp | 4 | ||||
-rw-r--r-- | src/bench/streams_findbyte.cpp | 31 | ||||
-rw-r--r-- | src/bench/util_time.cpp | 2 | ||||
-rw-r--r-- | src/bench/wallet_balance.cpp | 17 | ||||
-rw-r--r-- | src/bench/wallet_create_tx.cpp | 15 | ||||
-rw-r--r-- | src/bench/wallet_loading.cpp | 53 |
22 files changed, 257 insertions, 78 deletions
diff --git a/src/bench/addrman.cpp b/src/bench/addrman.cpp index d6b52eb587..f044feebba 100644 --- a/src/bench/addrman.cpp +++ b/src/bench/addrman.cpp @@ -4,6 +4,7 @@ #include <addrman.h> #include <bench/bench.h> +#include <netbase.h> #include <netgroup.h> #include <random.h> #include <util/check.h> @@ -95,6 +96,41 @@ static void AddrManSelect(benchmark::Bench& bench) }); } +// The worst case performance of the Select() function is when there is only +// one address on the table, because it linearly searches every position of +// several buckets before identifying the correct bucket +static void AddrManSelectFromAlmostEmpty(benchmark::Bench& bench) +{ + AddrMan addrman{EMPTY_NETGROUPMAN, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO}; + + // Add one address to the new table + CService addr = Lookup("250.3.1.1", 8333, false).value(); + addrman.Add({CAddress(addr, NODE_NONE)}, addr); + + bench.run([&] { + (void)addrman.Select(); + }); +} + +static void AddrManSelectByNetwork(benchmark::Bench& bench) +{ + AddrMan addrman{EMPTY_NETGROUPMAN, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO}; + + // add single I2P address to new table + CService i2p_service; + i2p_service.SetSpecial("udhdrtrcetjm5sxzskjyr5ztpeszydbh4dpl3pl4utgqqw2v4jna.b32.i2p"); + CAddress i2p_address(i2p_service, NODE_NONE); + i2p_address.nTime = Now<NodeSeconds>(); + const CNetAddr source{LookupHost("252.2.2.2", false).value()}; + addrman.Add({i2p_address}, source); + + FillAddrMan(addrman); + + bench.run([&] { + (void)addrman.Select(/*new_only=*/false, NET_I2P); + }); +} + static void AddrManGetAddr(benchmark::Bench& bench) { AddrMan addrman{EMPTY_NETGROUPMAN, /*deterministic=*/false, ADDRMAN_CONSISTENCY_CHECK_RATIO}; @@ -135,5 +171,7 @@ static void AddrManAddThenGood(benchmark::Bench& bench) BENCHMARK(AddrManAdd, benchmark::PriorityLevel::HIGH); BENCHMARK(AddrManSelect, benchmark::PriorityLevel::HIGH); +BENCHMARK(AddrManSelectFromAlmostEmpty, benchmark::PriorityLevel::HIGH); +BENCHMARK(AddrManSelectByNetwork, benchmark::PriorityLevel::HIGH); BENCHMARK(AddrManGetAddr, benchmark::PriorityLevel::HIGH); BENCHMARK(AddrManAddThenGood, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp index 4374a63250..84b66bc4b2 100644 --- a/src/bench/bench.cpp +++ b/src/bench/bench.cpp @@ -4,8 +4,8 @@ #include <bench/bench.h> -#include <fs.h> #include <test/util/setup_common.h> +#include <util/fs.h> #include <util/string.h> #include <chrono> diff --git a/src/bench/bench.h b/src/bench/bench.h index 22c63a797b..78196134e7 100644 --- a/src/bench/bench.h +++ b/src/bench/bench.h @@ -5,7 +5,7 @@ #ifndef BITCOIN_BENCH_BENCH_H #define BITCOIN_BENCH_BENCH_H -#include <fs.h> +#include <util/fs.h> #include <util/macros.h> #include <chrono> diff --git a/src/bench/bench_bitcoin.cpp b/src/bench/bench_bitcoin.cpp index 06e32f684f..8c421c3fec 100644 --- a/src/bench/bench_bitcoin.cpp +++ b/src/bench/bench_bitcoin.cpp @@ -5,10 +5,10 @@ #include <bench/bench.h> #include <clientversion.h> +#include <common/args.h> #include <crypto/sha256.h> -#include <fs.h> +#include <util/fs.h> #include <util/strencodings.h> -#include <util/system.h> #include <chrono> #include <cstdint> diff --git a/src/bench/bip324_ecdh.cpp b/src/bench/bip324_ecdh.cpp new file mode 100644 index 0000000000..659da0f08e --- /dev/null +++ b/src/bench/bip324_ecdh.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 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 <key.h> +#include <pubkey.h> +#include <random.h> +#include <span.h> + +#include <array> +#include <cstddef> + +static void BIP324_ECDH(benchmark::Bench& bench) +{ + ECC_Start(); + FastRandomContext rng; + + std::array<std::byte, 32> key_data; + std::array<std::byte, EllSwiftPubKey::size()> our_ellswift_data; + std::array<std::byte, EllSwiftPubKey::size()> their_ellswift_data; + + rng.fillrand(key_data); + rng.fillrand(our_ellswift_data); + rng.fillrand(their_ellswift_data); + + bench.batch(1).unit("ecdh").run([&] { + CKey key; + key.Set(UCharCast(key_data.data()), UCharCast(key_data.data()) + 32, true); + EllSwiftPubKey our_ellswift(our_ellswift_data); + EllSwiftPubKey their_ellswift(their_ellswift_data); + + auto ret = key.ComputeBIP324ECDHSecret(their_ellswift, our_ellswift, true); + + // To make sure that the computation is not the same on every iteration (ellswift decoding + // is variable-time), distribute bytes from the shared secret over the 3 inputs. The most + // important one is their_ellswift, because that one is actually decoded, so it's given most + // bytes. The data is copied into the middle, so that both halves are affected: + // - Copy 8 bytes from the resulting shared secret into middle of the private key. + std::copy(ret.begin(), ret.begin() + 8, key_data.begin() + 12); + // - Copy 8 bytes from the resulting shared secret into the middle of our ellswift key. + std::copy(ret.begin() + 8, ret.begin() + 16, our_ellswift_data.begin() + 28); + // - Copy 16 bytes from the resulting shared secret into the middle of their ellswift key. + std::copy(ret.begin() + 16, ret.end(), their_ellswift_data.begin() + 24); + }); + + ECC_Stop(); +} + +BENCHMARK(BIP324_ECDH, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/block_assemble.cpp b/src/bench/block_assemble.cpp index 8dd4117a3e..4d032cefc5 100644 --- a/src/bench/block_assemble.cpp +++ b/src/bench/block_assemble.cpp @@ -27,7 +27,7 @@ static void AssembleBlock(benchmark::Bench& bench) std::array<CTransactionRef, NUM_BLOCKS - COINBASE_MATURITY + 1> txs; for (size_t b{0}; b < NUM_BLOCKS; ++b) { CMutableTransaction tx; - tx.vin.push_back(MineBlock(test_setup->m_node, P2WSH_OP_TRUE)); + tx.vin.push_back(CTxIn{MineBlock(test_setup->m_node, P2WSH_OP_TRUE)}); tx.vin.back().scriptWitness = witness; tx.vout.emplace_back(1337, P2WSH_OP_TRUE); if (NUM_BLOCKS - b >= COINBASE_MATURITY) diff --git a/src/bench/checkblock.cpp b/src/bench/checkblock.cpp index ee76f7b767..269ac847a5 100644 --- a/src/bench/checkblock.cpp +++ b/src/bench/checkblock.cpp @@ -6,9 +6,10 @@ #include <bench/data.h> #include <chainparams.h> +#include <common/args.h> #include <consensus/validation.h> #include <streams.h> -#include <util/system.h> +#include <util/chaintype.h> #include <validation.h> // These are the two major time-sinks which happen after we have fully received @@ -36,7 +37,7 @@ static void DeserializeAndCheckBlockTest(benchmark::Bench& bench) stream.write({&a, 1}); // Prevent compaction ArgsManager bench_args; - const auto chainParams = CreateChainParams(bench_args, CBaseChainParams::MAIN); + const auto chainParams = CreateChainParams(bench_args, ChainType::MAIN); bench.unit("block").run([&] { CBlock block; // Note that CBlock caches its checked state, so we need to recreate it here diff --git a/src/bench/checkqueue.cpp b/src/bench/checkqueue.cpp index 8ad6fde6bf..70e0b86eba 100644 --- a/src/bench/checkqueue.cpp +++ b/src/bench/checkqueue.cpp @@ -4,11 +4,11 @@ #include <bench/bench.h> #include <checkqueue.h> +#include <common/system.h> #include <key.h> #include <prevector.h> #include <pubkey.h> #include <random.h> -#include <util/system.h> #include <vector> diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp index 265d4bf655..0e110a653a 100644 --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -5,9 +5,11 @@ #include <bench/bench.h> #include <interfaces/chain.h> #include <node/context.h> +#include <policy/policy.h> #include <wallet/coinselection.h> #include <wallet/spend.h> #include <wallet/wallet.h> +#include <wallet/test/util.h> #include <set> @@ -19,7 +21,7 @@ using wallet::CWallet; using wallet::CWalletTx; using wallet::CoinEligibilityFilter; using wallet::CoinSelectionParams; -using wallet::CreateDummyWalletDatabase; +using wallet::CreateMockableWalletDatabase; using wallet::OutputGroup; using wallet::SelectCoinsBnB; using wallet::TxStateInactive; @@ -45,7 +47,7 @@ static void CoinSelection(benchmark::Bench& bench) { NodeContext node; auto chain = interfaces::MakeChain(node); - CWallet wallet(chain.get(), "", CreateDummyWalletDatabase()); + CWallet wallet(chain.get(), "", CreateMockableWalletDatabase()); std::vector<std::unique_ptr<CWalletTx>> wtxs; LOCK(wallet.cs_wallet); @@ -115,7 +117,7 @@ static void BnBExhaustion(benchmark::Bench& bench) bench.run([&] { // Benchmark CAmount target = make_hard_case(17, utxo_pool); - SelectCoinsBnB(utxo_pool, target, 0); // Should exhaust + SelectCoinsBnB(utxo_pool, target, 0, MAX_STANDARD_TX_WEIGHT); // Should exhaust // Cleanup utxo_pool.clear(); diff --git a/src/bench/ellswift.cpp b/src/bench/ellswift.cpp new file mode 100644 index 0000000000..75729e170c --- /dev/null +++ b/src/bench/ellswift.cpp @@ -0,0 +1,31 @@ +// Copyright (c) 2022-2023 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 <key.h> +#include <random.h> + +static void EllSwiftCreate(benchmark::Bench& bench) +{ + ECC_Start(); + + CKey key; + key.MakeNewKey(true); + + uint256 entropy = GetRandHash(); + + bench.batch(1).unit("pubkey").run([&] { + auto ret = key.EllSwiftCreate(AsBytes(Span{entropy})); + /* Use the first 32 bytes of the ellswift encoded public key as next private key. */ + key.Set(UCharCast(ret.data()), UCharCast(ret.data()) + 32, true); + assert(key.IsValid()); + /* Use the last 32 bytes of the ellswift encoded public key as next entropy. */ + std::copy(ret.begin() + 32, ret.begin() + 64, AsBytePtr(entropy.data())); + }); + + ECC_Stop(); +} + +BENCHMARK(EllSwiftCreate, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/load_external.cpp b/src/bench/load_external.cpp index 0fd842c7c3..2ff72a3012 100644 --- a/src/bench/load_external.cpp +++ b/src/bench/load_external.cpp @@ -6,6 +6,7 @@ #include <bench/data.h> #include <chainparams.h> #include <test/util/setup_common.h> +#include <util/chaintype.h> #include <validation.h> /** @@ -22,7 +23,7 @@ */ static void LoadExternalBlockFile(benchmark::Bench& bench) { - const auto testing_setup{MakeNoLogFileContext<const TestingSetup>(CBaseChainParams::MAIN)}; + const auto testing_setup{MakeNoLogFileContext<const TestingSetup>(ChainType::MAIN)}; // Create a single block as in the blocks files (magic bytes, block size, // block data) as a stream object. diff --git a/src/bench/lockedpool.cpp b/src/bench/lockedpool.cpp index 161f9af621..6851ed0bd8 100644 --- a/src/bench/lockedpool.cpp +++ b/src/bench/lockedpool.cpp @@ -17,9 +17,7 @@ static void BenchLockedPool(benchmark::Bench& bench) const size_t synth_size = 1024*1024; Arena b(synth_base, synth_size, 16); - std::vector<void*> addr; - for (int x=0; x<ASIZE; ++x) - addr.push_back(nullptr); + std::vector<void*> addr{ASIZE, nullptr}; uint32_t s = 0x12345678; bench.run([&] { int idx = s & (addr.size() - 1); diff --git a/src/bench/logging.cpp b/src/bench/logging.cpp index 9aedb26236..c97c4e151b 100644 --- a/src/bench/logging.cpp +++ b/src/bench/logging.cpp @@ -5,6 +5,7 @@ #include <bench/bench.h> #include <logging.h> #include <test/util/setup_common.h> +#include <util/chaintype.h> // All but 2 of the benchmarks should have roughly similar performance: // @@ -18,7 +19,7 @@ static void Logging(benchmark::Bench& bench, const std::vector<const char*>& ext LogInstance().DisableCategory(BCLog::LogFlags::ALL); TestingSetup test_setup{ - CBaseChainParams::REGTEST, + ChainType::REGTEST, extra_args, }; diff --git a/src/bench/mempool_stress.cpp b/src/bench/mempool_stress.cpp index 80c959cdfb..826da73800 100644 --- a/src/bench/mempool_stress.cpp +++ b/src/bench/mempool_stress.cpp @@ -7,6 +7,7 @@ #include <policy/policy.h> #include <test/util/setup_common.h> #include <txmempool.h> +#include <util/chaintype.h> #include <validation.h> #include <vector> @@ -88,7 +89,7 @@ static void ComplexMemPool(benchmark::Bench& bench) childTxs = static_cast<int>(bench.complexityN()); } std::vector<CTransactionRef> ordered_coins = CreateOrderedCoins(det_rand, childTxs, /*min_ancestors=*/1); - const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(CBaseChainParams::MAIN); + const auto testing_setup = MakeNoLogFileContext<const TestingSetup>(ChainType::MAIN); CTxMemPool& pool = *testing_setup.get()->m_node.mempool; LOCK2(cs_main, pool.cs); bench.run([&]() NO_THREAD_SAFETY_ANALYSIS { @@ -103,7 +104,7 @@ static void ComplexMemPool(benchmark::Bench& bench) static void MempoolCheck(benchmark::Bench& bench) { FastRandomContext det_rand{true}; - auto testing_setup = MakeNoLogFileContext<TestChain100Setup>(CBaseChainParams::REGTEST, {"-checkmempool=1"}); + auto testing_setup = MakeNoLogFileContext<TestChain100Setup>(ChainType::REGTEST, {"-checkmempool=1"}); CTxMemPool& pool = *testing_setup.get()->m_node.mempool; LOCK2(cs_main, pool.cs); testing_setup->PopulateMempool(det_rand, 400, true); diff --git a/src/bench/pool.cpp b/src/bench/pool.cpp new file mode 100644 index 0000000000..b3e54d85a2 --- /dev/null +++ b/src/bench/pool.cpp @@ -0,0 +1,50 @@ +// Copyright (c) 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 <support/allocators/pool.h> + +#include <unordered_map> + +template <typename Map> +void BenchFillClearMap(benchmark::Bench& bench, Map& map) +{ + size_t batch_size = 5000; + + // make sure each iteration of the benchmark contains exactly 5000 inserts and one clear. + // do this at least 10 times so we get reasonable accurate results + + bench.batch(batch_size).minEpochIterations(10).run([&] { + auto rng = ankerl::nanobench::Rng(1234); + for (size_t i = 0; i < batch_size; ++i) { + map[rng()]; + } + map.clear(); + }); +} + +static void PoolAllocator_StdUnorderedMap(benchmark::Bench& bench) +{ + auto map = std::unordered_map<uint64_t, uint64_t>(); + BenchFillClearMap(bench, map); +} + +static void PoolAllocator_StdUnorderedMapWithPoolResource(benchmark::Bench& bench) +{ + using Map = std::unordered_map<uint64_t, + uint64_t, + std::hash<uint64_t>, + std::equal_to<uint64_t>, + PoolAllocator<std::pair<const uint64_t, uint64_t>, + sizeof(std::pair<const uint64_t, uint64_t>) + 4 * sizeof(void*), + alignof(void*)>>; + + // make sure the resource supports large enough pools to hold the node. We do this by adding the size of a few pointers to it. + auto pool_resource = Map::allocator_type::ResourceType(); + auto map = Map{0, std::hash<uint64_t>{}, std::equal_to<uint64_t>{}, &pool_resource}; + BenchFillClearMap(bench, map); +} + +BENCHMARK(PoolAllocator_StdUnorderedMap, benchmark::PriorityLevel::HIGH); +BENCHMARK(PoolAllocator_StdUnorderedMapWithPoolResource, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/rpc_blockchain.cpp b/src/bench/rpc_blockchain.cpp index f68b6acb5b..a9b197b190 100644 --- a/src/bench/rpc_blockchain.cpp +++ b/src/bench/rpc_blockchain.cpp @@ -8,6 +8,7 @@ #include <rpc/blockchain.h> #include <streams.h> #include <test/util/setup_common.h> +#include <util/chaintype.h> #include <validation.h> #include <univalue.h> @@ -15,7 +16,7 @@ namespace { struct TestBlockAndIndex { - const std::unique_ptr<const TestingSetup> testing_setup{MakeNoLogFileContext<const TestingSetup>(CBaseChainParams::MAIN)}; + const std::unique_ptr<const TestingSetup> testing_setup{MakeNoLogFileContext<const TestingSetup>(ChainType::MAIN)}; CBlock block{}; uint256 blockHash{}; CBlockIndex blockindex{}; diff --git a/src/bench/rpc_mempool.cpp b/src/bench/rpc_mempool.cpp index e3e1a07c83..7e274370e0 100644 --- a/src/bench/rpc_mempool.cpp +++ b/src/bench/rpc_mempool.cpp @@ -3,12 +3,12 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <bench/bench.h> -#include <chainparamsbase.h> #include <kernel/cs_main.h> #include <kernel/mempool_entry.h> #include <rpc/mempool.h> #include <test/util/setup_common.h> #include <txmempool.h> +#include <util/chaintype.h> #include <univalue.h> @@ -21,7 +21,7 @@ static void AddTx(const CTransactionRef& tx, const CAmount& fee, CTxMemPool& poo static void RpcMempool(benchmark::Bench& bench) { - const auto testing_setup = MakeNoLogFileContext<const ChainTestingSetup>(CBaseChainParams::MAIN); + const auto testing_setup = MakeNoLogFileContext<const ChainTestingSetup>(ChainType::MAIN); CTxMemPool& pool = *Assert(testing_setup->m_node.mempool); LOCK2(cs_main, pool.cs); diff --git a/src/bench/streams_findbyte.cpp b/src/bench/streams_findbyte.cpp new file mode 100644 index 0000000000..77f5940926 --- /dev/null +++ b/src/bench/streams_findbyte.cpp @@ -0,0 +1,31 @@ +// Copyright (c) 2023 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 <util/fs.h> +#include <streams.h> + +static void FindByte(benchmark::Bench& bench) +{ + // Setup + FILE* file = fsbridge::fopen("streams_tmp", "w+b"); + const size_t file_size = 200; + uint8_t data[file_size] = {0}; + data[file_size-1] = 1; + fwrite(&data, sizeof(uint8_t), file_size, file); + rewind(file); + CBufferedFile bf(file, /*nBufSize=*/file_size + 1, /*nRewindIn=*/file_size, 0, 0); + + bench.run([&] { + bf.SetPos(0); + bf.FindByte(std::byte(1)); + }); + + // Cleanup + bf.fclose(); + fs::remove("streams_tmp"); +} + +BENCHMARK(FindByte, benchmark::PriorityLevel::HIGH); diff --git a/src/bench/util_time.cpp b/src/bench/util_time.cpp index 8dbbdec28c..4cbc0dfbbd 100644 --- a/src/bench/util_time.cpp +++ b/src/bench/util_time.cpp @@ -32,7 +32,7 @@ static void BenchTimeMillis(benchmark::Bench& bench) static void BenchTimeMillisSys(benchmark::Bench& bench) { bench.run([&] { - (void)GetTimeMillis(); + (void)TicksSinceEpoch<std::chrono::milliseconds>(SystemClock::now()); }); } diff --git a/src/bench/wallet_balance.cpp b/src/bench/wallet_balance.cpp index d5d057e96d..bf2195293e 100644 --- a/src/bench/wallet_balance.cpp +++ b/src/bench/wallet_balance.cpp @@ -4,6 +4,7 @@ #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> @@ -14,26 +15,21 @@ #include <optional> -using wallet::CWallet; -using wallet::CreateMockWalletDatabase; -using wallet::DBErrors; -using wallet::GetBalance; -using wallet::WALLET_FLAG_DESCRIPTORS; - -const std::string ADDRESS_BCRT1_UNSPENDABLE = "bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj"; - +namespace wallet { 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; - CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockWalletDatabase()}; + // 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*) {}}); @@ -63,3 +59,4 @@ BENCHMARK(WalletBalanceDirty, benchmark::PriorityLevel::HIGH); BENCHMARK(WalletBalanceClean, benchmark::PriorityLevel::HIGH); BENCHMARK(WalletBalanceMine, benchmark::PriorityLevel::HIGH); BENCHMARK(WalletBalanceWatch, benchmark::PriorityLevel::HIGH); +} // namespace wallet diff --git a/src/bench/wallet_create_tx.cpp b/src/bench/wallet_create_tx.cpp index bd32a5abdc..5e5bc76fd2 100644 --- a/src/bench/wallet_create_tx.cpp +++ b/src/bench/wallet_create_tx.cpp @@ -15,7 +15,7 @@ #include <wallet/wallet.h> using wallet::CWallet; -using wallet::CreateMockWalletDatabase; +using wallet::CreateMockableWalletDatabase; using wallet::DBErrors; using wallet::WALLET_FLAG_DESCRIPTORS; @@ -83,7 +83,9 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type { const auto test_setup = MakeNoLogFileContext<const TestingSetup>(); - CWallet wallet{test_setup->m_node.chain.get(), "", CreateMockWalletDatabase()}; + // Set clock to genesis block, so the descriptors/keys creation time don't interfere with the blocks scanning process. + 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); @@ -102,7 +104,7 @@ static void WalletCreateTx(benchmark::Bench& bench, const OutputType output_type } // Check available balance - auto bal = wallet::GetAvailableBalance(wallet); // Cache + auto bal = WITH_LOCK(wallet.cs_wallet, return wallet::AvailableCoins(wallet).GetTotalAmount()); // Cache assert(bal == 50 * COIN * (chain_size - COINBASE_MATURITY)); wallet::CCoinControl coin_control; @@ -136,7 +138,9 @@ 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(), "", CreateMockWalletDatabase()}; + // Set clock to genesis block, so the descriptors/keys creation time don't interfere with the blocks scanning process. + 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); @@ -146,6 +150,7 @@ static void AvailableCoins(benchmark::Bench& bench, const std::vector<OutputType // Generate destinations std::vector<CScript> dest_wallet; + dest_wallet.reserve(output_type.size()); for (auto type : output_type) { dest_wallet.emplace_back(GetScriptForDestination(getNewDestination(wallet, type))); } @@ -160,7 +165,7 @@ static void AvailableCoins(benchmark::Bench& bench, const std::vector<OutputType } // Check available balance - auto bal = wallet::GetAvailableBalance(wallet); // Cache + auto bal = WITH_LOCK(wallet.cs_wallet, return wallet::AvailableCoins(wallet).GetTotalAmount()); // Cache assert(bal == 50 * COIN * (chain_size - COINBASE_MATURITY)); bench.epochIterations(2).run([&] { diff --git a/src/bench/wallet_loading.cpp b/src/bench/wallet_loading.cpp index 6b09adcc9d..5453238728 100644 --- a/src/bench/wallet_loading.cpp +++ b/src/bench/wallet_loading.cpp @@ -16,33 +16,7 @@ #include <optional> -using wallet::CWallet; -using wallet::DatabaseFormat; -using wallet::DatabaseOptions; -using wallet::TxStateInactive; -using wallet::WALLET_FLAG_DESCRIPTORS; -using wallet::WalletContext; -using wallet::WalletDatabase; - -static std::shared_ptr<CWallet> BenchLoadWallet(std::unique_ptr<WalletDatabase> database, WalletContext& context, DatabaseOptions& options) -{ - bilingual_str error; - std::vector<bilingual_str> warnings; - auto wallet = CWallet::Create(context, "", std::move(database), options.create_flags, error, warnings); - NotifyWalletLoaded(context, wallet); - if (context.chain) { - wallet->postInitProcess(); - } - return wallet; -} - -static void BenchUnloadWallet(std::shared_ptr<CWallet>&& wallet) -{ - SyncWithValidationInterfaceQueue(); - wallet->m_chain_notifications_handler.reset(); - UnloadWallet(std::move(wallet)); -} - +namespace wallet{ static void AddTx(CWallet& wallet) { CMutableTransaction mtx; @@ -55,7 +29,6 @@ static void AddTx(CWallet& wallet) static void WalletLoading(benchmark::Bench& bench, bool legacy_wallet) { const auto test_setup = MakeNoLogFileContext<TestingSetup>(); - test_setup->m_args.ForceSetArg("-unsafesqlitesync", "1"); WalletContext context; context.args = &test_setup->m_args; @@ -63,32 +36,29 @@ static void WalletLoading(benchmark::Bench& bench, bool legacy_wallet) // Setup the wallet // Loading the wallet will also create it - DatabaseOptions options; - if (legacy_wallet) { - options.require_format = DatabaseFormat::BERKELEY; - } else { - options.create_flags = WALLET_FLAG_DESCRIPTORS; - options.require_format = DatabaseFormat::SQLITE; + uint64_t create_flags = 0; + if (!legacy_wallet) { + create_flags = WALLET_FLAG_DESCRIPTORS; } - auto database = CreateMockWalletDatabase(options); - auto wallet = BenchLoadWallet(std::move(database), context, options); + auto database = CreateMockableWalletDatabase(); + auto wallet = TestLoadWallet(std::move(database), context, create_flags); // Generate a bunch of transactions and addresses to put into the wallet for (int i = 0; i < 1000; ++i) { AddTx(*wallet); } - database = DuplicateMockDatabase(wallet->GetDatabase(), options); + database = DuplicateMockDatabase(wallet->GetDatabase()); // reload the wallet for the actual benchmark - BenchUnloadWallet(std::move(wallet)); + TestUnloadWallet(std::move(wallet)); bench.epochs(5).run([&] { - wallet = BenchLoadWallet(std::move(database), context, options); + wallet = TestLoadWallet(std::move(database), context, create_flags); // Cleanup - database = DuplicateMockDatabase(wallet->GetDatabase(), options); - BenchUnloadWallet(std::move(wallet)); + database = DuplicateMockDatabase(wallet->GetDatabase()); + TestUnloadWallet(std::move(wallet)); }); } @@ -101,3 +71,4 @@ BENCHMARK(WalletLoadingLegacy, benchmark::PriorityLevel::HIGH); static void WalletLoadingDescriptors(benchmark::Bench& bench) { WalletLoading(bench, /*legacy_wallet=*/false); } BENCHMARK(WalletLoadingDescriptors, benchmark::PriorityLevel::HIGH); #endif +} // namespace wallet |