Skip to content

Commit 327129f

Browse files
author
MarcoFalke
committed
Merge #14400: Add Benchmark to test input de-duplication worst case
e4eee7d Add Benchmark to test input de-duplication worst case (Jeremy Rubin) Pull request description: Because there are now 2PRs referencing this benchmark commit, we may as well add it independently as it is worth landing the benchmark even if neither patch is accepted. bitcoin/bitcoin#14397 bitcoin/bitcoin#14387 Tree-SHA512: 4d947323c02297b0d8f5871f9e7cc42488c0e1792a8b10dc174a25f4dd53da8146fd276949a5dbacf4083f0c6a7235cb6f21a8bc35caa499bc2508f8a048b987
2 parents a7dc032 + e4eee7d commit 327129f

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

src/Makefile.bench.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ bench_bench_bitcoin_SOURCES = \
1818
bench/block_assemble.cpp \
1919
bench/checkblock.cpp \
2020
bench/checkqueue.cpp \
21+
bench/duplicate_inputs.cpp \
2122
bench/examples.cpp \
2223
bench/rollingbloom.cpp \
2324
bench/crypto_hash.cpp \

src/bench/duplicate_inputs.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright (c) 2011-2018 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 <chainparams.h>
7+
#include <coins.h>
8+
#include <consensus/merkle.h>
9+
#include <consensus/validation.h>
10+
#include <miner.h>
11+
#include <policy/policy.h>
12+
#include <pow.h>
13+
#include <scheduler.h>
14+
#include <txdb.h>
15+
#include <txmempool.h>
16+
#include <util/time.h>
17+
#include <validation.h>
18+
#include <validationinterface.h>
19+
20+
#include <boost/thread.hpp>
21+
22+
#include <list>
23+
#include <vector>
24+
25+
26+
static void DuplicateInputs(benchmark::State& state)
27+
{
28+
const CScript SCRIPT_PUB{CScript(OP_TRUE)};
29+
30+
// Switch to regtest so we can mine faster
31+
// Also segwit is active, so we can include witness transactions
32+
SelectParams(CBaseChainParams::REGTEST);
33+
34+
InitScriptExecutionCache();
35+
36+
boost::thread_group thread_group;
37+
CScheduler scheduler;
38+
const CChainParams& chainparams = Params();
39+
{
40+
::pblocktree.reset(new CBlockTreeDB(1 << 20, true));
41+
::pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true));
42+
::pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get()));
43+
44+
thread_group.create_thread(std::bind(&CScheduler::serviceQueue, &scheduler));
45+
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
46+
LoadGenesisBlock(chainparams);
47+
CValidationState cvstate;
48+
ActivateBestChain(cvstate, chainparams);
49+
assert(::chainActive.Tip() != nullptr);
50+
const bool witness_enabled{IsWitnessEnabled(::chainActive.Tip(), chainparams.GetConsensus())};
51+
assert(witness_enabled);
52+
}
53+
54+
CBlock block{};
55+
CMutableTransaction coinbaseTx{};
56+
CMutableTransaction naughtyTx{};
57+
58+
CBlockIndex* pindexPrev = ::chainActive.Tip();
59+
assert(pindexPrev != nullptr);
60+
block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus());
61+
block.nNonce = 0;
62+
auto nHeight = pindexPrev->nHeight + 1;
63+
64+
// Make a coinbase TX
65+
coinbaseTx.vin.resize(1);
66+
coinbaseTx.vin[0].prevout.SetNull();
67+
coinbaseTx.vout.resize(1);
68+
coinbaseTx.vout[0].scriptPubKey = SCRIPT_PUB;
69+
coinbaseTx.vout[0].nValue = GetBlockSubsidy(nHeight, chainparams.GetConsensus());
70+
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
71+
72+
73+
naughtyTx.vout.resize(1);
74+
naughtyTx.vout[0].nValue = 0;
75+
naughtyTx.vout[0].scriptPubKey = SCRIPT_PUB;
76+
77+
uint64_t n_inputs = (((MAX_BLOCK_SERIALIZED_SIZE / WITNESS_SCALE_FACTOR) - (CTransaction(coinbaseTx).GetTotalSize() + CTransaction(naughtyTx).GetTotalSize())) / 41) - 100;
78+
for (uint64_t x = 0; x < (n_inputs - 1); ++x) {
79+
naughtyTx.vin.emplace_back(GetRandHash(), 0, CScript(), 0);
80+
}
81+
naughtyTx.vin.emplace_back(naughtyTx.vin.back());
82+
83+
block.vtx.push_back(MakeTransactionRef(std::move(coinbaseTx)));
84+
block.vtx.push_back(MakeTransactionRef(std::move(naughtyTx)));
85+
86+
block.hashMerkleRoot = BlockMerkleRoot(block);
87+
88+
while (state.KeepRunning()) {
89+
CValidationState cvstate{};
90+
assert(!CheckBlock(block, cvstate, chainparams.GetConsensus(), false, false));
91+
assert(cvstate.GetRejectReason() == "bad-txns-inputs-duplicate");
92+
}
93+
94+
thread_group.interrupt_all();
95+
thread_group.join_all();
96+
GetMainSignals().FlushBackgroundCallbacks();
97+
GetMainSignals().UnregisterBackgroundSignalScheduler();
98+
}
99+
100+
BENCHMARK(DuplicateInputs, 10);

0 commit comments

Comments
 (0)