Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <bench/bench.h>6#include <random.h>7#include <txgraph.h>8#include <util/check.h>9#include <util/feefrac.h>11#include <algorithm>12#include <cstddef>13#include <cstdint>14#include <memory>15#include <utility>16#include <vector>18namespace {20std::strong_ordering PointerComparator(const TxGraph::Ref& a, const TxGraph::Ref& b) noexcept21{22return (&a) <=> (&b);23}25void BenchTxGraphTrim(benchmark::Bench& bench)26{27// The from-block transactions consist of 1000 fully linear clusters, each with 6428// transactions. The mempool contains 11 transactions that together merge all of these into29// a single cluster.30//31// (1000 chains of 64 transactions, 64000 T's total)32//33// T T T T T T T T34// | | | | | | | |35// T T T T T T T T36// | | | | | | | |37// T T T T T T T T38// | | | | | | | |39// T T T T T T T T40// (64 long) (64 long) (64 long) (64 long) (64 long) (64 long) (64 long) (64 long)41// | | | | | | | |42// | | / \ | / \ | | /43// \----------+--------/ \--------+--------/ \--------+-----+----+--------/44// | | |45// B B B46//47// (11 B's, each attaching to up to 100 chains of 64 T's)48//49/** The maximum cluster count used in this test. */50static constexpr int MAX_CLUSTER_COUNT = 64;51/** The number of "top" (from-block) chains of transactions. */52static constexpr int NUM_TOP_CHAINS = 1000;53/** The number of transactions per top chain. */54static constexpr int NUM_TX_PER_TOP_CHAIN = MAX_CLUSTER_COUNT;55/** The (maximum) number of dependencies per bottom transaction. */56static constexpr int NUM_DEPS_PER_BOTTOM_TX = 100;57/** Set a very large cluster size limit so that only the count limit is triggered. */58static constexpr int32_t MAX_CLUSTER_SIZE = 100'000 * 100;59/** Set a very high number for acceptable cost, so that we certainly benchmark optimal60* linearization. */61static constexpr uint64_t HIGH_ACCEPTABLE_COST = 100'000'000;63/** Refs to all top transactions. */64std::vector<TxGraph::Ref> top_refs;65/** Refs to all bottom transactions. */66std::vector<TxGraph::Ref> bottom_refs;67/** Indexes into top_refs for some transaction of each component, in arbitrary order.68* Initially these are the last transactions in each chains, but as bottom transactions are69* added, entries will be removed when they get merged, and randomized. */70std::vector<size_t> top_components;72InsecureRandomContext rng(11);73auto graph = MakeTxGraph(MAX_CLUSTER_COUNT, MAX_CLUSTER_SIZE, HIGH_ACCEPTABLE_COST, PointerComparator);75// Construct the top chains.76for (int chain = 0; chain < NUM_TOP_CHAINS; ++chain) {77for (int chaintx = 0; chaintx < NUM_TX_PER_TOP_CHAIN; ++chaintx) {78int64_t fee = rng.randbits<27>() + 100;79FeePerWeight feerate{fee, 1};80graph->AddTransaction(top_refs.emplace_back(), feerate);81// Add internal dependencies linking the chain transactions together.82if (chaintx > 0) {83graph->AddDependency(*(top_refs.rbegin()), *(top_refs.rbegin() + 1));84}85}86// Remember the last transaction in each chain, to attach the bottom transactions to.87top_components.push_back(top_refs.size() - 1);88}90// Make the graph linearize all clusters acceptably.91graph->GetBlockBuilder();93// Construct the bottom transactions, and dependencies to the top chains.94while (top_components.size() > 1) {95// Construct the transaction.96int64_t fee = rng.randbits<27>() + 100;97FeePerWeight feerate{fee, 1};98TxGraph::Ref bottom_tx;99graph->AddTransaction(bottom_tx, feerate);100// Determine the number of dependencies this transaction will have.101int deps = std::min<int>(NUM_DEPS_PER_BOTTOM_TX, top_components.size());102for (int dep = 0; dep < deps; ++dep) {103// Pick an transaction in top_components to attach to.104auto idx = rng.randrange(top_components.size());105// Add dependency.106graph->AddDependency(/*parent=*/top_refs[top_components[idx]], /*child=*/bottom_tx);107// Unless this is the last dependency being added, remove from top_components, as108// the component will be merged with that one.109if (dep < deps - 1) {110// Move entry top the back.111if (idx != top_components.size() - 1) std::swap(top_components.back(), top_components[idx]);112// And pop it.113top_components.pop_back();114}115}116bottom_refs.push_back(std::move(bottom_tx));117}119// Run the benchmark exactly once. Running it multiple times would require the setup to be120// redone, which takes a very non-negligible time compared to the trimming itself.121bench.epochIterations(1).epochs(1).run([&] {122// Call Trim() to remove transactions and bring the cluster back within limits.123graph->Trim();124// And relinearize everything that remains acceptably.125graph->GetBlockBuilder();126});128assert(!graph->IsOversized(TxGraph::Level::TOP));129// At least 99% of chains must survive.130assert(graph->GetTransactionCount(TxGraph::Level::TOP) >= (NUM_TOP_CHAINS * NUM_TX_PER_TOP_CHAIN * 99) / 100);131}133} // namespace135static void TxGraphTrim(benchmark::Bench& bench) { BenchTxGraphTrim(bench); }137BENCHMARK(TxGraphTrim);
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.