mempool_ephemeral_spends.cpp raw
1 // Copyright (c) 2011-2022 The Limenka 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>
6 #include <consensus/amount.h>
7 #include <kernel/cs_main.h>
8 #include <policy/ephemeral_policy.h>
9 #include <policy/policy.h>
10 #include <primitives/transaction.h>
11 #include <script/script.h>
12 #include <sync.h>
13 #include <test/util/setup_common.h>
14 #include <test/util/txmempool.h>
15 #include <txmempool.h>
16 #include <util/check.h>
17
18 #include <cstdint>
19 #include <memory>
20 #include <vector>
21
22
23 static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
24 {
25 int64_t nTime{0};
26 unsigned int nHeight{1};
27 uint64_t sequence{0};
28 bool spendsCoinbase{false};
29 unsigned int sigOpCost{4};
30 uint64_t fee{0};
31 LockPoints lp;
32 AddToMempool(pool, CTxMemPoolEntry(
33 tx, fee, nTime, nHeight, sequence,
34 COIN_AGE_CACHE_ZERO,
35 spendsCoinbase, /*extra_weight=*/0, sigOpCost, lp));
36 }
37
38 static void MempoolCheckEphemeralSpends(benchmark::Bench& bench)
39 {
40 const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
41
42 int number_outputs{1000};
43 if (bench.complexityN() > 1) {
44 number_outputs = static_cast<int>(bench.complexityN());
45 }
46
47 // Tx with many outputs
48 CMutableTransaction tx1;
49 tx1.vin.resize(1);
50 tx1.vout.resize(number_outputs);
51 for (size_t i = 0; i < tx1.vout.size(); i++) {
52 tx1.vout[i].scriptPubKey = CScript();
53 // Each output progressively larger
54 tx1.vout[i].nValue = i * CENT;
55 }
56
57 const auto& parent_txid = tx1.GetHash();
58
59 // Spends all outputs of tx1, other details don't matter
60 CMutableTransaction tx2;
61 tx2.vin.resize(tx1.vout.size());
62 for (size_t i = 0; i < tx2.vin.size(); i++) {
63 tx2.vin[0].prevout.hash = parent_txid;
64 tx2.vin[0].prevout.n = i;
65 }
66 tx2.vout.resize(1);
67
68 CTxMemPool& pool = *Assert(testing_setup->m_node.mempool);
69 LOCK2(cs_main, pool.cs);
70 // Create transaction references outside the "hot loop"
71 const CTransactionRef tx1_r{MakeTransactionRef(tx1)};
72 const CTransactionRef tx2_r{MakeTransactionRef(tx2)};
73
74 AddTx(tx1_r, pool);
75
76 uint32_t iteration{0};
77
78 TxValidationState dummy_state;
79 Wtxid dummy_wtxid;
80
81 bench.run([&]() NO_THREAD_SAFETY_ANALYSIS {
82
83 CheckEphemeralSpends({tx2_r}, /*dust_relay_rate=*/CFeeRate(iteration * COIN / 10), pool, dummy_state, dummy_wtxid);
84 iteration++;
85 });
86 }
87
88 BENCHMARK(MempoolCheckEphemeralSpends, benchmark::PriorityLevel::HIGH);
89