Merge #14400: Add Benchmark to test input de-duplication worst case
e4eee7d09d
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.
https://github.com/bitcoin/bitcoin/pull/14397
https://github.com/bitcoin/bitcoin/pull/14387
Tree-SHA512: 4d947323c02297b0d8f5871f9e7cc42488c0e1792a8b10dc174a25f4dd53da8146fd276949a5dbacf4083f0c6a7235cb6f21a8bc35caa499bc2508f8a048b987
This commit is contained in:
commit
327129f7a6
2 changed files with 101 additions and 0 deletions
|
@ -18,6 +18,7 @@ bench_bench_bitcoin_SOURCES = \
|
|||
bench/block_assemble.cpp \
|
||||
bench/checkblock.cpp \
|
||||
bench/checkqueue.cpp \
|
||||
bench/duplicate_inputs.cpp \
|
||||
bench/examples.cpp \
|
||||
bench/rollingbloom.cpp \
|
||||
bench/crypto_hash.cpp \
|
||||
|
|
100
src/bench/duplicate_inputs.cpp
Normal file
100
src/bench/duplicate_inputs.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
// Copyright (c) 2011-2018 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <bench/bench.h>
|
||||
#include <chainparams.h>
|
||||
#include <coins.h>
|
||||
#include <consensus/merkle.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <miner.h>
|
||||
#include <policy/policy.h>
|
||||
#include <pow.h>
|
||||
#include <scheduler.h>
|
||||
#include <txdb.h>
|
||||
#include <txmempool.h>
|
||||
#include <util/time.h>
|
||||
#include <validation.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
|
||||
static void DuplicateInputs(benchmark::State& state)
|
||||
{
|
||||
const CScript SCRIPT_PUB{CScript(OP_TRUE)};
|
||||
|
||||
// Switch to regtest so we can mine faster
|
||||
// Also segwit is active, so we can include witness transactions
|
||||
SelectParams(CBaseChainParams::REGTEST);
|
||||
|
||||
InitScriptExecutionCache();
|
||||
|
||||
boost::thread_group thread_group;
|
||||
CScheduler scheduler;
|
||||
const CChainParams& chainparams = Params();
|
||||
{
|
||||
::pblocktree.reset(new CBlockTreeDB(1 << 20, true));
|
||||
::pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true));
|
||||
::pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get()));
|
||||
|
||||
thread_group.create_thread(std::bind(&CScheduler::serviceQueue, &scheduler));
|
||||
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
|
||||
LoadGenesisBlock(chainparams);
|
||||
CValidationState cvstate;
|
||||
ActivateBestChain(cvstate, chainparams);
|
||||
assert(::chainActive.Tip() != nullptr);
|
||||
const bool witness_enabled{IsWitnessEnabled(::chainActive.Tip(), chainparams.GetConsensus())};
|
||||
assert(witness_enabled);
|
||||
}
|
||||
|
||||
CBlock block{};
|
||||
CMutableTransaction coinbaseTx{};
|
||||
CMutableTransaction naughtyTx{};
|
||||
|
||||
CBlockIndex* pindexPrev = ::chainActive.Tip();
|
||||
assert(pindexPrev != nullptr);
|
||||
block.nBits = GetNextWorkRequired(pindexPrev, &block, chainparams.GetConsensus());
|
||||
block.nNonce = 0;
|
||||
auto nHeight = pindexPrev->nHeight + 1;
|
||||
|
||||
// Make a coinbase TX
|
||||
coinbaseTx.vin.resize(1);
|
||||
coinbaseTx.vin[0].prevout.SetNull();
|
||||
coinbaseTx.vout.resize(1);
|
||||
coinbaseTx.vout[0].scriptPubKey = SCRIPT_PUB;
|
||||
coinbaseTx.vout[0].nValue = GetBlockSubsidy(nHeight, chainparams.GetConsensus());
|
||||
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;
|
||||
|
||||
|
||||
naughtyTx.vout.resize(1);
|
||||
naughtyTx.vout[0].nValue = 0;
|
||||
naughtyTx.vout[0].scriptPubKey = SCRIPT_PUB;
|
||||
|
||||
uint64_t n_inputs = (((MAX_BLOCK_SERIALIZED_SIZE / WITNESS_SCALE_FACTOR) - (CTransaction(coinbaseTx).GetTotalSize() + CTransaction(naughtyTx).GetTotalSize())) / 41) - 100;
|
||||
for (uint64_t x = 0; x < (n_inputs - 1); ++x) {
|
||||
naughtyTx.vin.emplace_back(GetRandHash(), 0, CScript(), 0);
|
||||
}
|
||||
naughtyTx.vin.emplace_back(naughtyTx.vin.back());
|
||||
|
||||
block.vtx.push_back(MakeTransactionRef(std::move(coinbaseTx)));
|
||||
block.vtx.push_back(MakeTransactionRef(std::move(naughtyTx)));
|
||||
|
||||
block.hashMerkleRoot = BlockMerkleRoot(block);
|
||||
|
||||
while (state.KeepRunning()) {
|
||||
CValidationState cvstate{};
|
||||
assert(!CheckBlock(block, cvstate, chainparams.GetConsensus(), false, false));
|
||||
assert(cvstate.GetRejectReason() == "bad-txns-inputs-duplicate");
|
||||
}
|
||||
|
||||
thread_group.interrupt_all();
|
||||
thread_group.join_all();
|
||||
GetMainSignals().FlushBackgroundCallbacks();
|
||||
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
||||
}
|
||||
|
||||
BENCHMARK(DuplicateInputs, 10);
|
Loading…
Reference in a new issue