Line data Source code
1 : // Copyright (c) 2015-2021 The Bitcoin Core developers
2 : // Copyright (c) 2014-2025 The Dash Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #ifndef BITCOIN_TEST_UTIL_SETUP_COMMON_H
7 : #define BITCOIN_TEST_UTIL_SETUP_COMMON_H
8 :
9 : #include <chainparamsbase.h>
10 : #include <fs.h>
11 : #include <key.h>
12 : #include <node/caches.h>
13 : #include <node/context.h> // IWYU pragma: export
14 : #include <primitives/transaction.h>
15 : #include <pubkey.h>
16 : #include <random.h>
17 : #include <util/check.h>
18 : #include <util/string.h>
19 : #include <util/system.h>
20 : #include <util/time.h>
21 : #include <util/vector.h>
22 :
23 : #include <functional>
24 : #include <stdexcept>
25 : #include <type_traits>
26 : #include <vector>
27 :
28 : class CChainParams;
29 : class CFeeRate;
30 : namespace Consensus {
31 : struct Params;
32 : };
33 :
34 : class CChainState;
35 :
36 : /** This is connected to the logger. Can be used to redirect logs to any other log */
37 : extern const std::function<void(const std::string&)> G_TEST_LOG_FUN;
38 :
39 : /** Retrieve the command line arguments. */
40 : extern const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS;
41 :
42 : // Enable BOOST_CHECK_EQUAL for enum class types
43 : namespace std {
44 : template <typename T>
45 2 : std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
46 : {
47 2 : return stream << static_cast<typename std::underlying_type<T>::type>(e);
48 : }
49 : } // namespace std
50 :
51 : /**
52 : * This global and the helpers that use it are not thread-safe.
53 : *
54 : * If thread-safety is needed, a per-thread instance could be
55 : * used in the multi-threaded test.
56 : */
57 : extern FastRandomContext g_insecure_rand_ctx;
58 :
59 : /**
60 : * Flag to make GetRand in random.h return the same number
61 : */
62 : extern bool g_mock_deterministic_tests;
63 :
64 : enum class SeedRand {
65 : ZEROS, //!< Seed with a compile time constant of zeros
66 : SEED, //!< Call the Seed() helper
67 : };
68 :
69 : /** Seed the given random ctx or use the seed passed in via an environment var */
70 : void Seed(FastRandomContext& ctx);
71 :
72 705 : static inline void SeedInsecureRand(SeedRand seed = SeedRand::SEED)
73 : {
74 705 : if (seed == SeedRand::ZEROS) {
75 14 : g_insecure_rand_ctx = FastRandomContext(/*fDeterministic=*/true);
76 14 : } else {
77 691 : Seed(g_insecure_rand_ctx);
78 : }
79 705 : }
80 :
81 : static constexpr CAmount CENT{1000000};
82 :
83 : /** Initialize components during initialization (NodeContext-friendly aliases) */
84 : std::unique_ptr<PeerManager> MakePeerManager(CConnman& connman,
85 : node::NodeContext& node,
86 : BanMan* banman,
87 : const CChainParams& chainparams,
88 : bool ignore_incoming_txs);
89 : void DashChainstateSetup(ChainstateManager& chainman,
90 : node::NodeContext& node,
91 : bool llmq_dbs_in_memory,
92 : bool llmq_dbs_wipe,
93 : const Consensus::Params& consensus_params);
94 : void DashChainstateSetupClose(node::NodeContext& node);
95 :
96 : /** Basic testing setup.
97 : * This just configures logging, data dir and chain parameters.
98 : */
99 : struct BasicTestingSetup {
100 : node::NodeContext m_node;
101 :
102 : explicit BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN, const std::vector<const char*>& extra_args = {});
103 : ~BasicTestingSetup();
104 :
105 : const fs::path m_path_root;
106 : ArgsManager m_args;
107 : };
108 :
109 : /** Testing setup that performs all steps up until right before
110 : * ChainstateManager gets initialized. Meant for testing ChainstateManager
111 : * initialization behaviour.
112 : */
113 : struct ChainTestingSetup : public BasicTestingSetup {
114 : node::CacheSizes m_cache_sizes{};
115 : bool m_coins_db_in_memory{true};
116 : bool m_block_tree_db_in_memory{true};
117 :
118 : explicit ChainTestingSetup(const std::string& chainName = CBaseChainParams::MAIN, const std::vector<const char*>& extra_args = {});
119 : ~ChainTestingSetup();
120 :
121 : // Supplies a chainstate, if one is needed
122 : void LoadVerifyActivateChainstate();
123 : };
124 :
125 : /** Testing setup that configures a complete environment.
126 : */
127 : struct TestingSetup : public ChainTestingSetup {
128 : explicit TestingSetup(
129 : const std::string& chainName = CBaseChainParams::MAIN,
130 : const std::vector<const char*>& extra_args = {},
131 : const bool coins_db_in_memory = true,
132 : const bool block_tree_db_in_memory = true);
133 : ~TestingSetup();
134 : };
135 :
136 : /** Identical to TestingSetup, but chain set to regtest */
137 : struct RegTestingSetup : public TestingSetup {
138 32 : RegTestingSetup(const std::vector<const char*>& extra_args = {})
139 32 : : TestingSetup{CBaseChainParams::REGTEST, extra_args} {}
140 : };
141 :
142 : class CBlock;
143 : struct CMutableTransaction;
144 : class CScript;
145 :
146 : struct TestChainSetup : public TestingSetup
147 : {
148 : TestChainSetup(int num_blocks,
149 : const std::string& chain_name = CBaseChainParams::REGTEST,
150 : const std::vector<const char*>& extra_args = {});
151 : ~TestChainSetup();
152 :
153 : /**
154 : * Create a new block with just given transactions, coinbase paying to
155 : * scriptPubKey, and try to add it to the current chain.
156 : * If no chainstate is specified, default to the active.
157 : */
158 : CBlock CreateAndProcessBlock(const std::vector<CMutableTransaction>& txns,
159 : const CScript& scriptPubKey,
160 : CChainState* chainstate = nullptr);
161 :
162 : /**
163 : * Create a new block with just given transactions, coinbase paying to
164 : * scriptPubKey.
165 : */
166 : CBlock CreateBlock(const std::vector<CMutableTransaction>& txns,
167 : const CScript& scriptPubKey,
168 : CChainState& chainstate);
169 :
170 : //! Mine a series of new blocks on the active chain.
171 : void mineBlocks(int num_blocks);
172 :
173 : /**
174 : * Create a transaction and submit to the mempool.
175 : *
176 : * @param input_transaction The transaction to spend
177 : * @param input_vout The vout to spend from the input_transaction
178 : * @param input_height The height of the block that included the input_transaction
179 : * @param input_signing_key The key to spend the input_transaction
180 : * @param output_destination Where to send the output
181 : * @param output_amount How much to send
182 : * @param submit Whether or not to submit to mempool
183 : */
184 : CMutableTransaction CreateValidMempoolTransaction(CTransactionRef input_transaction,
185 : int input_vout,
186 : int input_height,
187 : CKey input_signing_key,
188 : CScript output_destination,
189 : CAmount output_amount = CAmount(1 * COIN),
190 : bool submit = true);
191 :
192 : /** Create transactions spending from m_coinbase_txns. These transactions will only spend coins
193 : * that exist in the current chain, but may be premature coinbase spends, have missing
194 : * signatures, or violate some other consensus rules. They should only be used for testing
195 : * mempool consistency. All transactions will have some random number of inputs and outputs
196 : * (between 1 and 24). Transactions may or may not be dependent upon each other; if dependencies
197 : * exit, every parent will always be somewhere in the list before the child so each transaction
198 : * can be submitted in the same order they appear in the list.
199 : * @param[in] submit When true, submit transactions to the mempool.
200 : * When false, return them but don't submit them.
201 : * @returns A vector of transactions that can be submitted to the mempool.
202 : */
203 : std::vector<CTransactionRef> PopulateMempool(FastRandomContext& det_rand, size_t num_transactions, bool submit);
204 :
205 : /** Mock the mempool minimum feerate by adding a transaction and calling TrimToSize(0),
206 : * simulating the mempool "reaching capacity" and evicting by descendant feerate. Note that
207 : * this clears the mempool, and the new minimum feerate will depend on the maximum feerate of
208 : * transactions removed, so this must be called while the mempool is empty.
209 : *
210 : * @param target_feerate The new mempool minimum feerate after this function returns.
211 : * Must be above max(incremental feerate, min relay feerate),
212 : * or 1sat/vB with default settings.
213 : */
214 : void MockMempoolMinFee(const CFeeRate& target_feerate);
215 :
216 : std::vector<CTransactionRef> m_coinbase_txns; // For convenience, coinbase transactions
217 : CKey coinbaseKey; // private/public key needed to spend coinbase transactions
218 : };
219 :
220 : /**
221 : * Testing fixture that pre-creates a 100-block REGTEST-mode block chain
222 : */
223 : struct TestChain100Setup : public TestChainSetup {
224 : TestChain100Setup(const std::string& chain_name = CBaseChainParams::REGTEST,
225 : const std::vector<const char*>& extra_args = {});
226 : };
227 :
228 : /**
229 : * Make a test setup that has disk access to the debug.log file disabled. Can
230 : * be used in "hot loops", for example fuzzing or benchmarking.
231 : */
232 : template <class T = const BasicTestingSetup>
233 : std::unique_ptr<T> MakeNoLogFileContext(const std::string& chain_name = CBaseChainParams::REGTEST, const std::vector<const char*>& extra_args = {})
234 : {
235 : const std::vector<const char*> arguments = Cat(
236 : {
237 : "-nodebuglogfile",
238 : "-nodebug",
239 : },
240 : extra_args);
241 :
242 : return std::make_unique<T>(chain_name, arguments);
243 : }
244 :
245 : CBlock getBlock13b8a();
246 :
247 : /**
248 : * BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
249 : * Use as
250 : * BOOST_CHECK_EXCEPTION(code that throws, exception type, HasReason("foo"));
251 : */
252 : class HasReason
253 : {
254 : public:
255 40 : explicit HasReason(const std::string& reason) : m_reason(reason) {}
256 20 : bool operator()(const std::exception& e) const
257 : {
258 20 : return std::string(e.what()).find(m_reason) != std::string::npos;
259 : };
260 :
261 : private:
262 : const std::string m_reason;
263 : };
264 :
265 : // define an implicit conversion here so that uint256 may be used directly in BOOST_CHECK_*
266 : std::ostream& operator<<(std::ostream& os, const uint256& num);
267 :
268 : #endif // BITCOIN_TEST_UTIL_SETUP_COMMON_H
|