Bitcoin Core 28.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
disconnected_transactions.cpp
Go to the documentation of this file.
1// Copyright (c) 2023 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>
7#include <primitives/block.h>
8#include <test/util/random.h>
10
11constexpr size_t BLOCK_VTX_COUNT{4000};
12constexpr size_t BLOCK_VTX_COUNT_10PERCENT{400};
13
14using BlockTxns = decltype(CBlock::vtx);
15
27
28static BlockTxns CreateRandomTransactions(size_t num_txns)
29{
30 // Ensure every transaction has a different txid by having each one spend the previous one.
31 static Txid prevout_hash{};
32
33 BlockTxns txns;
34 txns.reserve(num_txns);
35 // Simplest spk for every tx
36 CScript spk = CScript() << OP_TRUE;
37 for (uint32_t i = 0; i < num_txns; ++i) {
39 tx.vin.emplace_back(COutPoint{prevout_hash, 0});
40 tx.vout.emplace_back(CENT, spk);
41 auto ptx{MakeTransactionRef(tx)};
42 txns.emplace_back(ptx);
43 prevout_hash = ptx->GetHash();
44 }
45 return txns;
46}
47
53static ReorgTxns CreateBlocks(size_t num_not_shared)
54{
55 auto num_shared{BLOCK_VTX_COUNT - num_not_shared};
56 const auto shared_txns{CreateRandomTransactions(/*num_txns=*/num_shared)};
57
58 // Create different sets of transactions...
59 auto disconnected_block_txns{CreateRandomTransactions(/*num_txns=*/num_not_shared)};
60 std::copy(shared_txns.begin(), shared_txns.end(), std::back_inserter(disconnected_block_txns));
61
62 auto connected_block_txns{CreateRandomTransactions(/*num_txns=*/num_not_shared)};
63 std::copy(shared_txns.begin(), shared_txns.end(), std::back_inserter(connected_block_txns));
64
65 assert(disconnected_block_txns.size() == BLOCK_VTX_COUNT);
66 assert(connected_block_txns.size() == BLOCK_VTX_COUNT);
67
68 return ReorgTxns{/*disconnected_txns=*/disconnected_block_txns,
69 /*connected_txns_1=*/connected_block_txns,
70 /*connected_txns_2=*/CreateRandomTransactions(BLOCK_VTX_COUNT),
71 /*num_shared=*/num_shared};
72}
73
74static void Reorg(const ReorgTxns& reorg)
75{
77 // Disconnect block
78 const auto evicted = disconnectpool.AddTransactionsFromBlock(reorg.disconnected_txns);
79 assert(evicted.empty());
80
81 // Connect first block
82 disconnectpool.removeForBlock(reorg.connected_txns_1);
83 // Connect new tip
84 disconnectpool.removeForBlock(reorg.connected_txns_2);
85
86 // Sanity Check
87 assert(disconnectpool.size() == BLOCK_VTX_COUNT - reorg.num_shared);
88
89 disconnectpool.clear();
90}
91
97{
98 const auto chains{CreateBlocks(/*num_not_shared=*/1)};
99 assert(chains.num_shared == BLOCK_VTX_COUNT - 1);
100
101 bench.minEpochIterations(10).run([&]() {
102 Reorg(chains);
103 });
104}
105
108{
109 const auto chains{CreateBlocks(/*num_not_shared=*/BLOCK_VTX_COUNT_10PERCENT)};
110 assert(chains.num_shared == BLOCK_VTX_COUNT - BLOCK_VTX_COUNT_10PERCENT);
111
112 bench.minEpochIterations(10).run([&]() {
113 Reorg(chains);
114 });
115}
116
119{
120 const auto chains{CreateBlocks(/*num_not_shared=*/BLOCK_VTX_COUNT - BLOCK_VTX_COUNT_10PERCENT)};
121 assert(chains.num_shared == BLOCK_VTX_COUNT_10PERCENT);
122
123 bench.minEpochIterations(10).run([&]() {
124 Reorg(chains);
125 });
126}
127
#define BENCHMARK(n, priority_level)
Definition bench.h:79
constexpr size_t BLOCK_VTX_COUNT_10PERCENT
static ReorgTxns CreateBlocks(size_t num_not_shared)
Creates blocks for a Reorg, each with BLOCK_VTX_COUNT transactions.
static void AddAndRemoveDisconnectedBlockTransactions90(benchmark::Bench &bench)
Add transactions from DisconnectedBlockTransactions, remove 90% of them, and then pop from the front ...
static void AddAndRemoveDisconnectedBlockTransactionsAll(benchmark::Bench &bench)
Add transactions from DisconnectedBlockTransactions, remove all but one (the disconnected block's coi...
constexpr size_t BLOCK_VTX_COUNT
static void AddAndRemoveDisconnectedBlockTransactions10(benchmark::Bench &bench)
Add transactions from DisconnectedBlockTransactions, remove 10% of them, and then pop from the front ...
static void Reorg(const ReorgTxns &reorg)
decltype(CBlock::vtx) BlockTxns
static BlockTxns CreateRandomTransactions(size_t num_txns)
std::vector< CTransactionRef > vtx
Definition block.h:72
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition transaction.h:29
Serialized script, used inside transaction inputs and outputs.
Definition script.h:414
DisconnectedBlockTransactions.
std::vector< CTransactionRef > AddTransactionsFromBlock(const std::vector< CTransactionRef > &vtx)
Add transactions from the block, iterating through vtx in reverse order.
Main entry point to nanobench's benchmarking facility.
Definition nanobench.h:627
Bench & run(char const *benchmarkName, Op &&op)
Repeatedly calls op() based on the configuration, and performs measurements.
Definition nanobench.h:1234
ANKERL_NANOBENCH(NODISCARD) std Bench & minEpochIterations(uint64_t numIters) noexcept
Sets the minimum number of iterations each epoch should take.
static const unsigned int MAX_DISCONNECTED_TX_POOL_BYTES
Maximum bytes for transactions to store for processing during reorg.
@ HIGH
Definition bench.h:47
static CTransactionRef MakeTransactionRef(Tx &&txIn)
@ OP_TRUE
Definition script.h:83
static constexpr CAmount CENT
A mutable version of CTransaction.
std::vector< CTxOut > vout
std::vector< CTxIn > vin
Reorg where 1 block is disconnected and 2 blocks are connected.
BlockTxns connected_txns_1
First connected block.
BlockTxns disconnected_txns
Disconnected block.
BlockTxns connected_txns_2
Second connected block, new chain tip.
size_t num_shared
Transactions shared between disconnected_txns and connected_txns_1.
assert(!tx.IsCoinBase())