45 static constexpr
int MAX_CLUSTER_COUNT = 64;
47 static constexpr
int NUM_TOP_CHAINS = 1000;
49 static constexpr
int NUM_TX_PER_TOP_CHAIN = MAX_CLUSTER_COUNT;
51 static constexpr
int NUM_DEPS_PER_BOTTOM_TX = 100;
53 static constexpr int32_t MAX_CLUSTER_SIZE = 100
'000 * 100; 56 static constexpr uint64_t HIGH_ACCEPTABLE_COST = 100'000
'000; 59 std::vector<TxGraph::Ref> top_refs; 61 std::vector<TxGraph::Ref> bottom_refs; 65 std::vector<size_t> top_components; 67 InsecureRandomContext rng(11); 68 auto graph = MakeTxGraph(MAX_CLUSTER_COUNT, MAX_CLUSTER_SIZE, HIGH_ACCEPTABLE_COST, PointerComparator); 70 // Construct the top chains. 71 for (int chain = 0; chain < NUM_TOP_CHAINS; ++chain) { 72 for (int chaintx = 0; chaintx < NUM_TX_PER_TOP_CHAIN; ++chaintx) { 73 int64_t fee = rng.randbits<27>() + 100; 74 FeePerWeight feerate{fee, 1}; 75 graph->AddTransaction(top_refs.emplace_back(), feerate); 76 // Add internal dependencies linking the chain transactions together. 78 graph->AddDependency(*(top_refs.rbegin()), *(top_refs.rbegin() + 1)); 81 // Remember the last transaction in each chain, to attach the bottom transactions to. 82 top_components.push_back(top_refs.size() - 1); 85 // Make the graph linearize all clusters acceptably. 86 graph->GetBlockBuilder(); 88 // Construct the bottom transactions, and dependencies to the top chains. 89 while (top_components.size() > 1) { 90 // Construct the transaction. 91 int64_t fee = rng.randbits<27>() + 100; 92 FeePerWeight feerate{fee, 1}; 93 TxGraph::Ref bottom_tx; 94 graph->AddTransaction(bottom_tx, feerate); 95 // Determine the number of dependencies this transaction will have. 96 int deps = std::min<int>(NUM_DEPS_PER_BOTTOM_TX, top_components.size()); 97 for (int dep = 0; dep < deps; ++dep) { 98 // Pick an transaction in top_components to attach to. 99 auto idx = rng.randrange(top_components.size()); 101 graph->AddDependency(/*parent=*/top_refs[top_components[idx]], /*child=*/bottom_tx); 102 // Unless this is the last dependency being added, remove from top_components, as 103 // the component will be merged with that one. 104 if (dep < deps - 1) { 105 // Move entry top the back. 106 if (idx != top_components.size() - 1) std::swap(top_components.back(), top_components[idx]); 108 top_components.pop_back(); 111 bottom_refs.push_back(std::move(bottom_tx)); 114 // Run the benchmark exactly once. Running it multiple times would require the setup to be 115 // redone, which takes a very non-negligible time compared to the trimming itself. 116 bench.epochIterations(1).epochs(1).run([&] { 117 // Call Trim() to remove transactions and bring the cluster back within limits. 119 // And relinearize everything that remains acceptably. 120 graph->GetBlockBuilder(); 123 assert(!graph->IsOversized(TxGraph::Level::TOP)); 124 // At least 99% of chains must survive. 125 assert(graph->GetTransactionCount(TxGraph::Level::TOP) >= (NUM_TOP_CHAINS * NUM_TX_PER_TOP_CHAIN * 99) / 100); 130 static void TxGraphTrim(benchmark::Bench& bench) { BenchTxGraphTrim(bench); } 132 BENCHMARK(TxGraphTrim);
Main entry point to nanobench's benchmarking facility.