aboutsummaryrefslogtreecommitdiff
path: root/src/test/util
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2019-11-07 08:01:59 -0500
committerMarcoFalke <falke.marco@gmail.com>2019-11-07 08:02:25 -0500
commit46fc4d1a24c88e797d6080336e3828e45e39c3fd (patch)
tree1df0e2070c7581fdbf56b2a295751b212ab44cd6 /src/test/util
parente65b4160e99fa86d6d840dce75cae29334afd1f2 (diff)
parentfa4c6fa9b1139791f45f1495d662c1c7cd2f7ed6 (diff)
downloadbitcoin-46fc4d1a24c88e797d6080336e3828e45e39c3fd.tar.xz
Merge #17384: test: Create new test library
fa4c6fa9b1139791f45f1495d662c1c7cd2f7ed6 doc: Add documentation for new test/lib (MarcoFalke) faec28252cf4f8e754c689a7a44fd421f631db50 scripted-diff: test: Move setup_common to test library (MarcoFalke) Pull request description: Sorry for clickbait, this is only a move-only scripted-diff commit and one documentation commit. Longer term, someone who knows something about build systems can make this an actual library. Motivation for this is that each module gets compiled for each target that includes it. For example, setup_common is compiled 27 times (for the fuzz suite) and another 3 times for the other tests (bench, unit test, gui) ACKs for top commit: practicalswift: ACK fa4c6fa9b1139791f45f1495d662c1c7cd2f7ed6 -- diff looks correct and Travis is happy jonatack: ACK fa4c6fa9b1139791f45f1495d662c1c7cd2f7ed6 with the reserve that the commit messages (and PR description) contain the motivation for this change. Built, ran tests, light code review. ryanofsky: Code review ACK fa4c6fa9b1139791f45f1495d662c1c7cd2f7ed6. I didn't realize `lib` was actually name of existing directory, not a new name. But in any case this looks good and nice to have one scripted diff instead of two. Tree-SHA512: 2e176df90c60578276e4a6dc83ff57ff59d8e666ecf30c5ceacb8c326725da91baa4cac3dfa7a2e1605f58122a3e3e27e4938ff33e3a0ce7ea53afffebbf57a4
Diffstat (limited to 'src/test/util')
-rw-r--r--src/test/util/README.md11
-rw-r--r--src/test/util/blockfilter.cpp26
-rw-r--r--src/test/util/blockfilter.h13
-rw-r--r--src/test/util/logging.cpp32
-rw-r--r--src/test/util/logging.h29
-rw-r--r--src/test/util/setup_common.cpp200
-rw-r--r--src/test/util/setup_common.h139
-rw-r--r--src/test/util/transaction_utils.cpp39
-rw-r--r--src/test/util/transaction_utils.h19
9 files changed, 508 insertions, 0 deletions
diff --git a/src/test/util/README.md b/src/test/util/README.md
new file mode 100644
index 0000000000..36ad645201
--- /dev/null
+++ b/src/test/util/README.md
@@ -0,0 +1,11 @@
+# Test library
+
+This contains files for the test library, which is used by the test binaries (unit tests, benchmarks, fuzzers, gui
+tests).
+
+Generally, the files in this folder should be well-separated modules. New code should be added to existing modules or
+(when in doubt) a new module should be created.
+
+The utilities in here are compiled into a library, which does not hold any state. However, the main file `setup_common`
+defines the common test setup for all test binaries. The test binaries will handle the global state when they
+instantiate the `BasicTestingSetup` (or one of its derived classes).
diff --git a/src/test/util/blockfilter.cpp b/src/test/util/blockfilter.cpp
new file mode 100644
index 0000000000..bccff5e5a6
--- /dev/null
+++ b/src/test/util/blockfilter.cpp
@@ -0,0 +1,26 @@
+// Copyright (c) 2019 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 <test/util/blockfilter.h>
+
+#include <chainparams.h>
+#include <validation.h>
+
+
+bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex* block_index, BlockFilter& filter)
+{
+ CBlock block;
+ if (!ReadBlockFromDisk(block, block_index->GetBlockPos(), Params().GetConsensus())) {
+ return false;
+ }
+
+ CBlockUndo block_undo;
+ if (block_index->nHeight > 0 && !UndoReadFromDisk(block_undo, block_index)) {
+ return false;
+ }
+
+ filter = BlockFilter(filter_type, block, block_undo);
+ return true;
+}
+
diff --git a/src/test/util/blockfilter.h b/src/test/util/blockfilter.h
new file mode 100644
index 0000000000..79d11dcad8
--- /dev/null
+++ b/src/test/util/blockfilter.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TEST_UTIL_BLOCKFILTER_H
+#define BITCOIN_TEST_UTIL_BLOCKFILTER_H
+
+#include <blockfilter.h>
+class CBlockIndex;
+
+bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex* block_index, BlockFilter& filter);
+
+#endif // BITCOIN_TEST_UTIL_BLOCKFILTER_H
diff --git a/src/test/util/logging.cpp b/src/test/util/logging.cpp
new file mode 100644
index 0000000000..fe2e69104b
--- /dev/null
+++ b/src/test/util/logging.cpp
@@ -0,0 +1,32 @@
+// Copyright (c) 2019 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 <test/util/logging.h>
+
+#include <logging.h>
+#include <noui.h>
+#include <tinyformat.h>
+#include <util/memory.h>
+
+#include <stdexcept>
+
+DebugLogHelper::DebugLogHelper(std::string message)
+ : m_message{std::move(message)}
+{
+ m_print_connection = LogInstance().PushBackCallback(
+ [this](const std::string& s) {
+ if (m_found) return;
+ m_found = s.find(m_message) != std::string::npos;
+ });
+ noui_test_redirect();
+}
+
+void DebugLogHelper::check_found()
+{
+ noui_reconnect();
+ LogInstance().DeleteCallback(m_print_connection);
+ if (!m_found) {
+ throw std::runtime_error(strprintf("'%s' not found in debug log\n", m_message));
+ }
+}
diff --git a/src/test/util/logging.h b/src/test/util/logging.h
new file mode 100644
index 0000000000..45ec44173c
--- /dev/null
+++ b/src/test/util/logging.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TEST_UTIL_LOGGING_H
+#define BITCOIN_TEST_UTIL_LOGGING_H
+
+#include <util/macros.h>
+
+#include <functional>
+#include <list>
+#include <string>
+
+class DebugLogHelper
+{
+ const std::string m_message;
+ bool m_found{false};
+ std::list<std::function<void(const std::string&)>>::iterator m_print_connection;
+
+ void check_found();
+
+public:
+ DebugLogHelper(std::string message);
+ ~DebugLogHelper() { check_found(); }
+};
+
+#define ASSERT_DEBUG_LOG(message) DebugLogHelper PASTE2(debugloghelper, __COUNTER__)(message)
+
+#endif // BITCOIN_TEST_UTIL_LOGGING_H
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
new file mode 100644
index 0000000000..b85f643bf5
--- /dev/null
+++ b/src/test/util/setup_common.cpp
@@ -0,0 +1,200 @@
+// Copyright (c) 2011-2019 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 <test/util/setup_common.h>
+
+#include <banman.h>
+#include <chainparams.h>
+#include <consensus/consensus.h>
+#include <consensus/params.h>
+#include <consensus/validation.h>
+#include <crypto/sha256.h>
+#include <init.h>
+#include <miner.h>
+#include <net.h>
+#include <noui.h>
+#include <pow.h>
+#include <rpc/blockchain.h>
+#include <rpc/register.h>
+#include <rpc/server.h>
+#include <script/sigcache.h>
+#include <streams.h>
+#include <txdb.h>
+#include <util/memory.h>
+#include <util/strencodings.h>
+#include <util/time.h>
+#include <util/translation.h>
+#include <util/validation.h>
+#include <validation.h>
+#include <validationinterface.h>
+
+#include <functional>
+
+const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
+
+FastRandomContext g_insecure_rand_ctx;
+
+std::ostream& operator<<(std::ostream& os, const uint256& num)
+{
+ os << num.ToString();
+ return os;
+}
+
+BasicTestingSetup::BasicTestingSetup(const std::string& chainName)
+ : m_path_root(fs::temp_directory_path() / "test_common_" PACKAGE_NAME / strprintf("%lu_%i", (unsigned long)GetTime(), (int)(InsecureRandRange(1 << 30))))
+{
+ fs::create_directories(m_path_root);
+ gArgs.ForceSetArg("-datadir", m_path_root.string());
+ ClearDatadirCache();
+ SelectParams(chainName);
+ gArgs.ForceSetArg("-printtoconsole", "0");
+ InitLogging();
+ LogInstance().StartLogging();
+ SHA256AutoDetect();
+ ECC_Start();
+ SetupEnvironment();
+ SetupNetworking();
+ InitSignatureCache();
+ InitScriptExecutionCache();
+ fCheckBlockIndex = true;
+ static bool noui_connected = false;
+ if (!noui_connected) {
+ noui_connect();
+ noui_connected = true;
+ }
+}
+
+BasicTestingSetup::~BasicTestingSetup()
+{
+ LogInstance().DisconnectTestLogger();
+ fs::remove_all(m_path_root);
+ ECC_Stop();
+}
+
+TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
+{
+ const CChainParams& chainparams = Params();
+ // Ideally we'd move all the RPC tests to the functional testing framework
+ // instead of unit tests, but for now we need these here.
+ g_rpc_node = &m_node;
+ RegisterAllCoreRPCCommands(tableRPC);
+
+ // We have to run a scheduler thread to prevent ActivateBestChain
+ // from blocking due to queue overrun.
+ threadGroup.create_thread(std::bind(&CScheduler::serviceQueue, &scheduler));
+ GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
+
+ mempool.setSanityCheck(1.0);
+ pblocktree.reset(new CBlockTreeDB(1 << 20, true));
+ g_chainstate = MakeUnique<CChainState>();
+ ::ChainstateActive().InitCoinsDB(
+ /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
+ assert(!::ChainstateActive().CanFlushToDisk());
+ ::ChainstateActive().InitCoinsCache();
+ assert(::ChainstateActive().CanFlushToDisk());
+ if (!LoadGenesisBlock(chainparams)) {
+ throw std::runtime_error("LoadGenesisBlock failed.");
+ }
+
+ BlockValidationState state;
+ if (!ActivateBestChain(state, chainparams)) {
+ throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", FormatStateMessage(state)));
+ }
+
+ nScriptCheckThreads = 3;
+ for (int i = 0; i < nScriptCheckThreads - 1; i++)
+ threadGroup.create_thread([i]() { return ThreadScriptCheck(i); });
+
+ m_node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", nullptr, DEFAULT_MISBEHAVING_BANTIME);
+ m_node.connman = MakeUnique<CConnman>(0x1337, 0x1337); // Deterministic randomness for tests.
+}
+
+TestingSetup::~TestingSetup()
+{
+ threadGroup.interrupt_all();
+ threadGroup.join_all();
+ GetMainSignals().FlushBackgroundCallbacks();
+ GetMainSignals().UnregisterBackgroundSignalScheduler();
+ g_rpc_node = nullptr;
+ m_node.connman.reset();
+ m_node.banman.reset();
+ UnloadBlockIndex();
+ g_chainstate.reset();
+ pblocktree.reset();
+}
+
+TestChain100Setup::TestChain100Setup()
+{
+ // CreateAndProcessBlock() does not support building SegWit blocks, so don't activate in these tests.
+ // TODO: fix the code to support SegWit blocks.
+ gArgs.ForceSetArg("-segwitheight", "432");
+ // Need to recreate chainparams
+ SelectParams(CBaseChainParams::REGTEST);
+
+ // Generate a 100-block chain:
+ coinbaseKey.MakeNewKey(true);
+ CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
+ for (int i = 0; i < COINBASE_MATURITY; i++)
+ {
+ std::vector<CMutableTransaction> noTxns;
+ CBlock b = CreateAndProcessBlock(noTxns, scriptPubKey);
+ m_coinbase_txns.push_back(b.vtx[0]);
+ }
+}
+
+// Create a new block with just given transactions, coinbase paying to
+// scriptPubKey, and try to add it to the current chain.
+CBlock TestChain100Setup::CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns, const CScript& scriptPubKey)
+{
+ const CChainParams& chainparams = Params();
+ std::unique_ptr<CBlockTemplate> pblocktemplate = BlockAssembler(chainparams).CreateNewBlock(scriptPubKey);
+ CBlock& block = pblocktemplate->block;
+
+ // Replace mempool-selected txns with just coinbase plus passed-in txns:
+ block.vtx.resize(1);
+ for (const CMutableTransaction& tx : txns)
+ block.vtx.push_back(MakeTransactionRef(tx));
+ // IncrementExtraNonce creates a valid coinbase and merkleRoot
+ {
+ LOCK(cs_main);
+ unsigned int extraNonce = 0;
+ IncrementExtraNonce(&block, ::ChainActive().Tip(), extraNonce);
+ }
+
+ while (!CheckProofOfWork(block.GetHash(), block.nBits, chainparams.GetConsensus())) ++block.nNonce;
+
+ std::shared_ptr<const CBlock> shared_pblock = std::make_shared<const CBlock>(block);
+ ProcessNewBlock(chainparams, shared_pblock, true, nullptr);
+
+ CBlock result = block;
+ return result;
+}
+
+TestChain100Setup::~TestChain100Setup()
+{
+ gArgs.ForceSetArg("-segwitheight", "0");
+}
+
+
+CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction &tx) {
+ return FromTx(MakeTransactionRef(tx));
+}
+
+CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransactionRef& tx)
+{
+ return CTxMemPoolEntry(tx, nFee, nTime, nHeight,
+ spendsCoinbase, sigOpCost, lp);
+}
+
+/**
+ * @returns a real block (0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af)
+ * with 9 txs.
+ */
+CBlock getBlock13b8a()
+{
+ CBlock block;
+ CDataStream stream(ParseHex("0100000090f0a9f110702f808219ebea1173056042a714bad51b916cb6800000000000005275289558f51c9966699404ae2294730c3c9f9bda53523ce50e9b95e558da2fdb261b4d4c86041b1ab1bf930901000000010000000000000000000000000000000000000000000000000000000000000000ffffffff07044c86041b0146ffffffff0100f2052a01000000434104e18f7afbe4721580e81e8414fc8c24d7cfacf254bb5c7b949450c3e997c2dc1242487a8169507b631eb3771f2b425483fb13102c4eb5d858eef260fe70fbfae0ac00000000010000000196608ccbafa16abada902780da4dc35dafd7af05fa0da08cf833575f8cf9e836000000004a493046022100dab24889213caf43ae6adc41cf1c9396c08240c199f5225acf45416330fd7dbd022100fe37900e0644bf574493a07fc5edba06dbc07c311b947520c2d514bc5725dcb401ffffffff0100f2052a010000001976a914f15d1921f52e4007b146dfa60f369ed2fc393ce288ac000000000100000001fb766c1288458c2bafcfec81e48b24d98ec706de6b8af7c4e3c29419bfacb56d000000008c493046022100f268ba165ce0ad2e6d93f089cfcd3785de5c963bb5ea6b8c1b23f1ce3e517b9f022100da7c0f21adc6c401887f2bfd1922f11d76159cbc597fbd756a23dcbb00f4d7290141042b4e8625a96127826915a5b109852636ad0da753c9e1d5606a50480cd0c40f1f8b8d898235e571fe9357d9ec842bc4bba1827daaf4de06d71844d0057707966affffffff0280969800000000001976a9146963907531db72d0ed1a0cfb471ccb63923446f388ac80d6e34c000000001976a914f0688ba1c0d1ce182c7af6741e02658c7d4dfcd388ac000000000100000002c40297f730dd7b5a99567eb8d27b78758f607507c52292d02d4031895b52f2ff010000008b483045022100f7edfd4b0aac404e5bab4fd3889e0c6c41aa8d0e6fa122316f68eddd0a65013902205b09cc8b2d56e1cd1f7f2fafd60a129ed94504c4ac7bdc67b56fe67512658b3e014104732012cb962afa90d31b25d8fb0e32c94e513ab7a17805c14ca4c3423e18b4fb5d0e676841733cb83abaf975845c9f6f2a8097b7d04f4908b18368d6fc2d68ecffffffffca5065ff9617cbcba45eb23726df6498a9b9cafed4f54cbab9d227b0035ddefb000000008a473044022068010362a13c7f9919fa832b2dee4e788f61f6f5d344a7c2a0da6ae740605658022006d1af525b9a14a35c003b78b72bd59738cd676f845d1ff3fc25049e01003614014104732012cb962afa90d31b25d8fb0e32c94e513ab7a17805c14ca4c3423e18b4fb5d0e676841733cb83abaf975845c9f6f2a8097b7d04f4908b18368d6fc2d68ecffffffff01001ec4110200000043410469ab4181eceb28985b9b4e895c13fa5e68d85761b7eee311db5addef76fa8621865134a221bd01f28ec9999ee3e021e60766e9d1f3458c115fb28650605f11c9ac000000000100000001cdaf2f758e91c514655e2dc50633d1e4c84989f8aa90a0dbc883f0d23ed5c2fa010000008b48304502207ab51be6f12a1962ba0aaaf24a20e0b69b27a94fac5adf45aa7d2d18ffd9236102210086ae728b370e5329eead9accd880d0cb070aea0c96255fae6c4f1ddcce1fd56e014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff02404b4c00000000001976a9142b6ba7c9d796b75eef7942fc9288edd37c32f5c388ac002d3101000000001976a9141befba0cdc1ad56529371864d9f6cb042faa06b588ac000000000100000001b4a47603e71b61bc3326efd90111bf02d2f549b067f4c4a8fa183b57a0f800cb010000008a4730440220177c37f9a505c3f1a1f0ce2da777c339bd8339ffa02c7cb41f0a5804f473c9230220585b25a2ee80eb59292e52b987dad92acb0c64eced92ed9ee105ad153cdb12d001410443bd44f683467e549dae7d20d1d79cbdb6df985c6e9c029c8d0c6cb46cc1a4d3cf7923c5021b27f7a0b562ada113bc85d5fda5a1b41e87fe6e8802817cf69996ffffffff0280651406000000001976a9145505614859643ab7b547cd7f1f5e7e2a12322d3788ac00aa0271000000001976a914ea4720a7a52fc166c55ff2298e07baf70ae67e1b88ac00000000010000000586c62cd602d219bb60edb14a3e204de0705176f9022fe49a538054fb14abb49e010000008c493046022100f2bc2aba2534becbdf062eb993853a42bbbc282083d0daf9b4b585bd401aa8c9022100b1d7fd7ee0b95600db8535bbf331b19eed8d961f7a8e54159c53675d5f69df8c014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff03ad0e58ccdac3df9dc28a218bcf6f1997b0a93306faaa4b3a28ae83447b2179010000008b483045022100be12b2937179da88599e27bb31c3525097a07cdb52422d165b3ca2f2020ffcf702200971b51f853a53d644ebae9ec8f3512e442b1bcb6c315a5b491d119d10624c83014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff2acfcab629bbc8685792603762c921580030ba144af553d271716a95089e107b010000008b483045022100fa579a840ac258871365dd48cd7552f96c8eea69bd00d84f05b283a0dab311e102207e3c0ee9234814cfbb1b659b83671618f45abc1326b9edcc77d552a4f2a805c0014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffffdcdc6023bbc9944a658ddc588e61eacb737ddf0a3cd24f113b5a8634c517fcd2000000008b4830450221008d6df731df5d32267954bd7d2dda2302b74c6c2a6aa5c0ca64ecbabc1af03c75022010e55c571d65da7701ae2da1956c442df81bbf076cdbac25133f99d98a9ed34c014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffffe15557cd5ce258f479dfd6dc6514edf6d7ed5b21fcfa4a038fd69f06b83ac76e010000008b483045022023b3e0ab071eb11de2eb1cc3a67261b866f86bf6867d4558165f7c8c8aca2d86022100dc6e1f53a91de3efe8f63512850811f26284b62f850c70ca73ed5de8771fb451014104462e76fd4067b3a0aa42070082dcb0bf2f388b6495cf33d789904f07d0f55c40fbd4b82963c69b3dc31895d0c772c812b1d5fbcade15312ef1c0e8ebbb12dcd4ffffffff01404b4c00000000001976a9142b6ba7c9d796b75eef7942fc9288edd37c32f5c388ac00000000010000000166d7577163c932b4f9690ca6a80b6e4eb001f0a2fa9023df5595602aae96ed8d000000008a4730440220262b42546302dfb654a229cefc86432b89628ff259dc87edd1154535b16a67e102207b4634c020a97c3e7bbd0d4d19da6aa2269ad9dded4026e896b213d73ca4b63f014104979b82d02226b3a4597523845754d44f13639e3bf2df5e82c6aab2bdc79687368b01b1ab8b19875ae3c90d661a3d0a33161dab29934edeb36aa01976be3baf8affffffff02404b4c00000000001976a9144854e695a02af0aeacb823ccbc272134561e0a1688ac40420f00000000001976a914abee93376d6b37b5c2940655a6fcaf1c8e74237988ac0000000001000000014e3f8ef2e91349a9059cb4f01e54ab2597c1387161d3da89919f7ea6acdbb371010000008c49304602210081f3183471a5ca22307c0800226f3ef9c353069e0773ac76bb580654d56aa523022100d4c56465bdc069060846f4fbf2f6b20520b2a80b08b168b31e66ddb9c694e240014104976c79848e18251612f8940875b2b08d06e6dc73b9840e8860c066b7e87432c477e9a59a453e71e6d76d5fe34058b800a098fc1740ce3012e8fc8a00c96af966ffffffff02c0e1e400000000001976a9144134e75a6fcb6042034aab5e18570cf1f844f54788ac404b4c00000000001976a9142b6ba7c9d796b75eef7942fc9288edd37c32f5c388ac00000000"), SER_NETWORK, PROTOCOL_VERSION);
+ stream >> block;
+ return block;
+}
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
new file mode 100644
index 0000000000..5467cd6cce
--- /dev/null
+++ b/src/test/util/setup_common.h
@@ -0,0 +1,139 @@
+// Copyright (c) 2015-2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TEST_UTIL_SETUP_COMMON_H
+#define BITCOIN_TEST_UTIL_SETUP_COMMON_H
+
+#include <chainparamsbase.h>
+#include <fs.h>
+#include <key.h>
+#include <node/context.h>
+#include <pubkey.h>
+#include <random.h>
+#include <scheduler.h>
+#include <txmempool.h>
+
+#include <type_traits>
+
+#include <boost/thread.hpp>
+
+// Enable BOOST_CHECK_EQUAL for enum class types
+template <typename T>
+std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
+{
+ return stream << static_cast<typename std::underlying_type<T>::type>(e);
+}
+
+/**
+ * This global and the helpers that use it are not thread-safe.
+ *
+ * If thread-safety is needed, the global could be made thread_local (given
+ * that thread_local is supported on all architectures we support) or a
+ * per-thread instance could be used in the multi-threaded test.
+ */
+extern FastRandomContext g_insecure_rand_ctx;
+
+/**
+ * Flag to make GetRand in random.h return the same number
+ */
+extern bool g_mock_deterministic_tests;
+
+static inline void SeedInsecureRand(bool deterministic = false)
+{
+ g_insecure_rand_ctx = FastRandomContext(deterministic);
+}
+
+static inline uint32_t InsecureRand32() { return g_insecure_rand_ctx.rand32(); }
+static inline uint256 InsecureRand256() { return g_insecure_rand_ctx.rand256(); }
+static inline uint64_t InsecureRandBits(int bits) { return g_insecure_rand_ctx.randbits(bits); }
+static inline uint64_t InsecureRandRange(uint64_t range) { return g_insecure_rand_ctx.randrange(range); }
+static inline bool InsecureRandBool() { return g_insecure_rand_ctx.randbool(); }
+
+static constexpr CAmount CENT{1000000};
+
+/** Basic testing setup.
+ * This just configures logging, data dir and chain parameters.
+ */
+struct BasicTestingSetup {
+ ECCVerifyHandle globalVerifyHandle;
+
+ explicit BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN);
+ ~BasicTestingSetup();
+private:
+ const fs::path m_path_root;
+};
+
+/** Testing setup that configures a complete environment.
+ * Included are coins database, script check threads setup.
+ */
+struct TestingSetup : public BasicTestingSetup {
+ NodeContext m_node;
+ boost::thread_group threadGroup;
+ CScheduler scheduler;
+
+ explicit TestingSetup(const std::string& chainName = CBaseChainParams::MAIN);
+ ~TestingSetup();
+};
+
+/** Identical to TestingSetup, but chain set to regtest */
+struct RegTestingSetup : public TestingSetup {
+ RegTestingSetup()
+ : TestingSetup{CBaseChainParams::REGTEST} {}
+};
+
+class CBlock;
+struct CMutableTransaction;
+class CScript;
+
+//
+// Testing fixture that pre-creates a
+// 100-block REGTEST-mode block chain
+//
+struct TestChain100Setup : public RegTestingSetup {
+ TestChain100Setup();
+
+ // Create a new block with just given transactions, coinbase paying to
+ // scriptPubKey, and try to add it to the current chain.
+ CBlock CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns,
+ const CScript& scriptPubKey);
+
+ ~TestChain100Setup();
+
+ std::vector<CTransactionRef> m_coinbase_txns; // For convenience, coinbase transactions
+ CKey coinbaseKey; // private/public key needed to spend coinbase transactions
+};
+
+class CTxMemPoolEntry;
+
+struct TestMemPoolEntryHelper
+{
+ // Default values
+ CAmount nFee;
+ int64_t nTime;
+ unsigned int nHeight;
+ bool spendsCoinbase;
+ unsigned int sigOpCost;
+ LockPoints lp;
+
+ TestMemPoolEntryHelper() :
+ nFee(0), nTime(0), nHeight(1),
+ spendsCoinbase(false), sigOpCost(4) { }
+
+ CTxMemPoolEntry FromTx(const CMutableTransaction& tx);
+ CTxMemPoolEntry FromTx(const CTransactionRef& tx);
+
+ // Change the default value
+ TestMemPoolEntryHelper &Fee(CAmount _fee) { nFee = _fee; return *this; }
+ TestMemPoolEntryHelper &Time(int64_t _time) { nTime = _time; return *this; }
+ TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; }
+ TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; }
+ TestMemPoolEntryHelper &SigOpsCost(unsigned int _sigopsCost) { sigOpCost = _sigopsCost; return *this; }
+};
+
+CBlock getBlock13b8a();
+
+// define an implicit conversion here so that uint256 may be used directly in BOOST_CHECK_*
+std::ostream& operator<<(std::ostream& os, const uint256& num);
+
+#endif
diff --git a/src/test/util/transaction_utils.cpp b/src/test/util/transaction_utils.cpp
new file mode 100644
index 0000000000..90b78effb0
--- /dev/null
+++ b/src/test/util/transaction_utils.cpp
@@ -0,0 +1,39 @@
+// Copyright (c) 2019 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 <test/util/transaction_utils.h>
+
+CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey, int nValue)
+{
+ CMutableTransaction txCredit;
+ txCredit.nVersion = 1;
+ txCredit.nLockTime = 0;
+ txCredit.vin.resize(1);
+ txCredit.vout.resize(1);
+ txCredit.vin[0].prevout.SetNull();
+ txCredit.vin[0].scriptSig = CScript() << CScriptNum(0) << CScriptNum(0);
+ txCredit.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
+ txCredit.vout[0].scriptPubKey = scriptPubKey;
+ txCredit.vout[0].nValue = nValue;
+
+ return txCredit;
+}
+
+CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CTransaction& txCredit)
+{
+ CMutableTransaction txSpend;
+ txSpend.nVersion = 1;
+ txSpend.nLockTime = 0;
+ txSpend.vin.resize(1);
+ txSpend.vout.resize(1);
+ txSpend.vin[0].scriptWitness = scriptWitness;
+ txSpend.vin[0].prevout.hash = txCredit.GetHash();
+ txSpend.vin[0].prevout.n = 0;
+ txSpend.vin[0].scriptSig = scriptSig;
+ txSpend.vin[0].nSequence = CTxIn::SEQUENCE_FINAL;
+ txSpend.vout[0].scriptPubKey = CScript();
+ txSpend.vout[0].nValue = txCredit.vout[0].nValue;
+
+ return txSpend;
+}
diff --git a/src/test/util/transaction_utils.h b/src/test/util/transaction_utils.h
new file mode 100644
index 0000000000..57604646e7
--- /dev/null
+++ b/src/test/util/transaction_utils.h
@@ -0,0 +1,19 @@
+// Copyright (c) 2019 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_TEST_UTIL_TRANSACTION_UTILS_H
+#define BITCOIN_TEST_UTIL_TRANSACTION_UTILS_H
+
+#include <primitives/transaction.h>
+
+// create crediting transaction
+// [1 coinbase input => 1 output with given scriptPubkey and value]
+CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey, int nValue = 0);
+
+// create spending transaction
+// [1 input with referenced transaction outpoint, scriptSig, scriptWitness =>
+// 1 output with empty scriptPubKey, full value of referenced transaction]
+CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CTransaction& txCredit);
+
+#endif // BITCOIN_TEST_UTIL_TRANSACTION_UTILS_H