Skip to content

Commit 5c2e291

Browse files
committed
bench: Add basic CheckEphemeralSpends benchmark
1 parent 3f6559f commit 5c2e291

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

src/bench/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ add_executable(bench_bitcoin
3434
load_external.cpp
3535
lockedpool.cpp
3636
logging.cpp
37+
mempool_ephemeral_spends.cpp
3738
mempool_eviction.cpp
3839
mempool_stress.cpp
3940
merkle_root.cpp
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright (c) 2011-2022 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>
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 <txmempool.h>
15+
#include <util/check.h>
16+
17+
#include <cstdint>
18+
#include <memory>
19+
#include <vector>
20+
21+
22+
static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
23+
{
24+
int64_t nTime{0};
25+
unsigned int nHeight{1};
26+
uint64_t sequence{0};
27+
bool spendsCoinbase{false};
28+
unsigned int sigOpCost{4};
29+
uint64_t fee{0};
30+
LockPoints lp;
31+
pool.addUnchecked(CTxMemPoolEntry(
32+
tx, fee, nTime, nHeight, sequence,
33+
spendsCoinbase, sigOpCost, lp));
34+
}
35+
36+
static void MempoolCheckEphemeralSpends(benchmark::Bench& bench)
37+
{
38+
const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
39+
40+
int number_outputs{1000};
41+
if (bench.complexityN() > 1) {
42+
number_outputs = static_cast<int>(bench.complexityN());
43+
}
44+
45+
// Tx with many outputs
46+
CMutableTransaction tx1 = CMutableTransaction();
47+
tx1.vin.resize(1);
48+
tx1.vout.resize(number_outputs);
49+
for (size_t i = 0; i < tx1.vout.size(); i++) {
50+
tx1.vout[i].scriptPubKey = CScript();
51+
// Each output progressively larger
52+
tx1.vout[i].nValue = i * CENT;
53+
}
54+
55+
const auto& parent_txid = tx1.GetHash();
56+
57+
// Spends all outputs of tx1, other details don't matter
58+
CMutableTransaction tx2 = CMutableTransaction();
59+
tx2.vin.resize(tx1.vout.size());
60+
for (size_t i = 0; i < tx2.vin.size(); i++) {
61+
tx2.vin[0].prevout.hash = parent_txid;
62+
tx2.vin[0].prevout.n = i;
63+
}
64+
tx2.vout.resize(1);
65+
66+
CTxMemPool& pool = *Assert(testing_setup->m_node.mempool);
67+
LOCK2(cs_main, pool.cs);
68+
// Create transaction references outside the "hot loop"
69+
const CTransactionRef tx1_r{MakeTransactionRef(tx1)};
70+
const CTransactionRef tx2_r{MakeTransactionRef(tx2)};
71+
72+
AddTx(tx1_r, pool);
73+
74+
uint32_t iteration{0};
75+
76+
bench.run([&]() NO_THREAD_SAFETY_ANALYSIS {
77+
78+
CheckEphemeralSpends({tx2_r}, /*dust_relay_rate=*/CFeeRate(iteration * COIN / 10), pool);
79+
iteration++;
80+
});
81+
}
82+
83+
BENCHMARK(MempoolCheckEphemeralSpends, benchmark::PriorityLevel::HIGH);

0 commit comments

Comments
 (0)