Skip to content

Commit fa0fc1b

Browse files
author
MarcoFalke
committed
bench: Add block assemble benchmark
1 parent 66cc47b commit fa0fc1b

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

src/Makefile.bench.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ bench_bench_bitcoin_SOURCES = \
1515
bench/bench_bitcoin.cpp \
1616
bench/bench.cpp \
1717
bench/bench.h \
18+
bench/block_assemble.cpp \
1819
bench/checkblock.cpp \
1920
bench/checkqueue.cpp \
2021
bench/Examples.cpp \

src/bench/block_assemble.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// Copyright (c) 2011-2017 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 <scheduler.h>
13+
#include <txdb.h>
14+
#include <txmempool.h>
15+
#include <utiltime.h>
16+
#include <validation.h>
17+
#include <validationinterface.h>
18+
19+
#include <boost/thread.hpp>
20+
21+
#include <list>
22+
#include <vector>
23+
24+
static std::shared_ptr<CBlock> PrepareBlock(const CScript& coinbase_scriptPubKey)
25+
{
26+
auto block = std::make_shared<CBlock>(
27+
BlockAssembler{Params()}
28+
.CreateNewBlock(coinbase_scriptPubKey, /* fMineWitnessTx */ true)
29+
->block);
30+
31+
block->nTime = ::chainActive.Tip()->GetMedianTimePast() + 1;
32+
block->hashMerkleRoot = BlockMerkleRoot(*block);
33+
34+
return block;
35+
}
36+
37+
38+
static CTxIn MineBlock(const CScript& coinbase_scriptPubKey)
39+
{
40+
auto block = PrepareBlock(coinbase_scriptPubKey);
41+
42+
while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
43+
assert(++block->nNonce);
44+
}
45+
46+
bool processed{ProcessNewBlock(Params(), block, true, nullptr)};
47+
assert(processed);
48+
49+
return CTxIn{block->vtx[0]->GetHash(), 0};
50+
}
51+
52+
53+
static void AssembleBlock(benchmark::State& state)
54+
{
55+
const std::vector<unsigned char> op_true{OP_TRUE};
56+
CScriptWitness witness;
57+
witness.stack.push_back(op_true);
58+
59+
uint256 witness_program;
60+
CSHA256().Write(&op_true[0], op_true.size()).Finalize(witness_program.begin());
61+
62+
const CScript SCRIPT_PUB{CScript(OP_0) << std::vector<unsigned char>{witness_program.begin(), witness_program.end()}};
63+
64+
// Switch to regtest so we can mine faster
65+
// Also segwit is active, so we can include witness transactions
66+
SelectParams(CBaseChainParams::REGTEST);
67+
68+
InitScriptExecutionCache();
69+
70+
boost::thread_group thread_group;
71+
CScheduler scheduler;
72+
{
73+
::pblocktree.reset(new CBlockTreeDB(1 << 20, true));
74+
::pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true));
75+
::pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get()));
76+
77+
const CChainParams& chainparams = Params();
78+
thread_group.create_thread(boost::bind(&CScheduler::serviceQueue, &scheduler));
79+
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
80+
LoadGenesisBlock(chainparams);
81+
CValidationState state;
82+
ActivateBestChain(state, chainparams);
83+
assert(::chainActive.Tip() != nullptr);
84+
const bool witness_enabled{IsWitnessEnabled(::chainActive.Tip(), chainparams.GetConsensus())};
85+
assert(witness_enabled);
86+
}
87+
88+
// Collect some loose transactions that spend the coinbases of our mined blocks
89+
constexpr size_t NUM_BLOCKS{200};
90+
std::array<CTransactionRef, NUM_BLOCKS - COINBASE_MATURITY + 1> txs;
91+
for (size_t b{0}; b < NUM_BLOCKS; ++b) {
92+
CMutableTransaction tx;
93+
tx.vin.push_back(MineBlock(SCRIPT_PUB));
94+
tx.vin.back().scriptWitness = witness;
95+
tx.vout.emplace_back(1337, SCRIPT_PUB);
96+
if (NUM_BLOCKS - b >= COINBASE_MATURITY)
97+
txs.at(b) = MakeTransactionRef(tx);
98+
}
99+
for (const auto& txr : txs) {
100+
CValidationState state;
101+
bool ret{::AcceptToMemoryPool(::mempool, state, txr, nullptr /* pfMissingInputs */, nullptr /* plTxnReplaced */, false /* bypass_limits */, /* nAbsurdFee */ 0)};
102+
assert(ret);
103+
}
104+
105+
while (state.KeepRunning()) {
106+
PrepareBlock(SCRIPT_PUB);
107+
}
108+
109+
thread_group.interrupt_all();
110+
thread_group.join_all();
111+
GetMainSignals().FlushBackgroundCallbacks();
112+
GetMainSignals().UnregisterBackgroundSignalScheduler();
113+
}
114+
115+
BENCHMARK(AssembleBlock, 700);

0 commit comments

Comments
 (0)