aboutsummaryrefslogtreecommitdiff
path: root/src/bench
diff options
context:
space:
mode:
Diffstat (limited to 'src/bench')
-rw-r--r--src/bench/base58.cpp2
-rw-r--r--src/bench/coin_selection.cpp29
-rw-r--r--src/bench/duplicate_inputs.cpp100
-rw-r--r--src/bench/prevector.cpp10
4 files changed, 125 insertions, 16 deletions
diff --git a/src/bench/base58.cpp b/src/bench/base58.cpp
index a555376e40..e7702ec461 100644
--- a/src/bench/base58.cpp
+++ b/src/bench/base58.cpp
@@ -49,7 +49,7 @@ static void Base58Decode(benchmark::State& state)
const char* addr = "17VZNX1SN5NtKa8UQFxwQbFeFc3iqRYhem";
std::vector<unsigned char> vch;
while (state.KeepRunning()) {
- DecodeBase58(addr, vch);
+ (void) DecodeBase58(addr, vch);
}
}
diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp
index 8552ed34fd..74641191a1 100644
--- a/src/bench/coin_selection.cpp
+++ b/src/bench/coin_selection.cpp
@@ -4,25 +4,19 @@
#include <bench/bench.h>
#include <interfaces/chain.h>
-#include <wallet/wallet.h>
#include <wallet/coinselection.h>
+#include <wallet/wallet.h>
#include <set>
-static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector<OutputGroup>& groups)
+static void addCoin(const CAmount& nValue, const CWallet& wallet, std::vector<std::unique_ptr<CWalletTx>>& wtxs)
{
- int nInput = 0;
-
static int nextLockTime = 0;
CMutableTransaction tx;
tx.nLockTime = nextLockTime++; // so all transactions get different hashes
- tx.vout.resize(nInput + 1);
- tx.vout[nInput].nValue = nValue;
- CWalletTx* wtx = new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)));
-
- int nAge = 6 * 24;
- COutput output(wtx, nInput, nAge, true /* spendable */, true /* solvable */, true /* safe */);
- groups.emplace_back(output.GetInputCoin(), 6, false, 0, 0);
+ tx.vout.resize(1);
+ tx.vout[0].nValue = nValue;
+ wtxs.push_back(MakeUnique<CWalletTx>(&wallet, MakeTransactionRef(std::move(tx))));
}
// Simple benchmark for wallet coin selection. Note that it maybe be necessary
@@ -36,14 +30,21 @@ static void CoinSelection(benchmark::State& state)
{
auto chain = interfaces::MakeChain();
const CWallet wallet(*chain, WalletLocation(), WalletDatabase::CreateDummy());
+ std::vector<std::unique_ptr<CWalletTx>> wtxs;
LOCK(wallet.cs_wallet);
// Add coins.
- std::vector<OutputGroup> groups;
for (int i = 0; i < 1000; ++i) {
- addCoin(1000 * COIN, wallet, groups);
+ addCoin(1000 * COIN, wallet, wtxs);
+ }
+ addCoin(3 * COIN, wallet, wtxs);
+
+ // Create groups
+ std::vector<OutputGroup> groups;
+ for (const auto& wtx : wtxs) {
+ COutput output(wtx.get(), 0 /* iIn */, 6 * 24 /* nDepthIn */, true /* spendable */, true /* solvable */, true /* safe */);
+ groups.emplace_back(output.GetInputCoin(), 6, false, 0, 0);
}
- addCoin(3 * COIN, wallet, groups);
const CoinEligibilityFilter filter_standard(1, 6, 0);
const CoinSelectionParams coin_selection_params(true, 34, 148, CFeeRate(0), 0);
diff --git a/src/bench/duplicate_inputs.cpp b/src/bench/duplicate_inputs.cpp
new file mode 100644
index 0000000000..e0854e2c62
--- /dev/null
+++ b/src/bench/duplicate_inputs.cpp
@@ -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);
diff --git a/src/bench/prevector.cpp b/src/bench/prevector.cpp
index 8cc404b9e2..00e5d7e7a0 100644
--- a/src/bench/prevector.cpp
+++ b/src/bench/prevector.cpp
@@ -2,13 +2,21 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <compat.h>
#include <prevector.h>
#include <serialize.h>
#include <streams.h>
+#include <type_traits>
#include <bench/bench.h>
+// GCC 4.8 is missing some C++11 type_traits,
+// https://www.gnu.org/software/gcc/gcc-5/changes.html
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5
+#define IS_TRIVIALLY_CONSTRUCTIBLE std::has_trivial_default_constructor
+#else
+#define IS_TRIVIALLY_CONSTRUCTIBLE std::is_trivially_default_constructible
+#endif
+
struct nontrivial_t {
int x;
nontrivial_t() :x(-1) {}