123 std::chrono::microseconds now{
GetTime()};
126 for (
const auto segwit_parent : {
true,
false}) {
127 for (
const auto segwit_child : {
true,
false}) {
130 const auto& parent_txid = ptx_parent->GetHash();
131 const auto& parent_wtxid = ptx_parent->GetWitnessHash();
132 const auto& child_txid = ptx_child->GetHash();
133 const auto& child_wtxid = ptx_child->GetWitnessHash();
140 const auto& [keep, unique_txids, package_to_validate] = txdownload_impl.
MempoolRejectedTx(ptx_parent, state, nodeid,
true);
153 BOOST_TEST_MESSAGE(
"Testing behavior for " << result << (segwit_parent ?
" segwit " :
" nonsegwit"));
154 actual_behavior.
CheckEqual(expected_behavior, segwit_parent);
161 const bool parent_txid_rejected{segwit_parent ? expected_behavior.m_txid_in_rejects : expected_behavior.m_wtxid_in_rejects};
189 CAmount amount_depth_2{amount_depth_1 - 1000};
192 int test_chain_height{100};
200 size_t coinbase_idx{0};
202 for (
int decisions = 0; decisions < (1 << 4); ++decisions) {
203 auto mtx_single_parent = CreateValidMempoolTransaction(m_coinbase_txns[coinbase_idx], 0, test_chain_height, coinbaseKey, destination, amount_depth_1,
false);
206 auto mtx_orphan = CreateValidMempoolTransaction(single_parent, 0, test_chain_height, wallet_key, destination, amount_depth_2,
false);
216 const bool parent_recent_rej(decisions & 1);
217 const bool parent_recent_rej_recon((decisions >> 1) & 1);
218 const bool parent_recent_conf((decisions >> 2) & 1);
219 const bool parent_in_mempool((decisions >> 3) & 1);
224 if (parent_in_mempool) {
225 const auto mempool_result =
WITH_LOCK(
::cs_main,
return m_node.chainman->ProcessTransaction(single_parent));
228 assert(coinbase_idx < m_coinbase_txns.size());
234 const bool expect_keep_orphan = !parent_recent_rej;
235 const unsigned int expected_parents = parent_recent_rej || parent_recent_conf || parent_in_mempool ? 0 : 1;
238 BOOST_CHECK(expect_keep_orphan || expected_parents == 0);
239 const auto ret_1p1c = txdownload_impl.
MempoolRejectedTx(orphan, state_orphan, nodeid,
true);
242 expect_keep_orphan,
true, expected_parents);
243 BOOST_CHECK_MESSAGE(ok, err_msg);
248 std::vector<CTransactionRef> parents;
249 std::vector<COutPoint> outpoints;
250 int32_t num_parents{24};
251 for (int32_t i = 0; i < num_parents; ++i) {
252 assert(coinbase_idx < m_coinbase_txns.size());
253 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[coinbase_idx++], 0, test_chain_height,
254 coinbaseKey, destination, amount_depth_1 + i,
false);
256 parents.emplace_back(ptx_parent);
257 outpoints.emplace_back(ptx_parent->GetHash(), 0);
261 auto mtx_orphan = CreateValidMempoolTransaction(parents, outpoints, test_chain_height, {wallet_key}, {{amount_depth_2 * num_parents, destination}},
false);
270 const auto ret_1p1c_parent_reconsiderable = txdownload_impl.
MempoolRejectedTx(orphan, state_orphan, nodeid,
true);
272 const bool ok =
CheckOrphanBehavior(txdownload_impl, orphan, ret_1p1c_parent_reconsiderable, err_msg,
273 true,
true, num_parents);
274 BOOST_CHECK_MESSAGE(ok, err_msg);
283 for (int32_t i = 1; i < num_parents; ++i) {
286 const unsigned int expected_parents = 1;
288 const auto ret_1recon_conf = txdownload_impl.
MempoolRejectedTx(orphan, state_orphan, nodeid,
true);
291 true,
true, expected_parents);
292 BOOST_CHECK_MESSAGE(ok, err_msg);
296 for (
int i = 0; i < 2; ++i) {
303 auto& alreadyhave_parent = parents[0];
310 const auto ret_2_problems = txdownload_impl.
MempoolRejectedTx(orphan, state_orphan, nodeid,
true);
314 BOOST_CHECK_MESSAGE(ok, err_msg);
320 assert(coinbase_idx < m_coinbase_txns.size());
321 auto parent_2outputs =
MakeTransactionRef(CreateValidMempoolTransaction({m_coinbase_txns[coinbase_idx]}, {{m_coinbase_txns[coinbase_idx]->GetHash(), 0}}, test_chain_height, {coinbaseKey},
322 {{amount_split_half, destination}, {amount_split_half, destination}},
false));
324 auto orphan =
MakeTransactionRef(CreateValidMempoolTransaction({parent_2outputs}, {{parent_2outputs->GetHash(), 0}, {parent_2outputs->GetHash(), 1}},
325 test_chain_height, {wallet_key}, {{amount_depth_2, destination}},
false));
333 const auto ret_1p1c_2reconsiderable = txdownload_impl.
MempoolRejectedTx(orphan, state_orphan, nodeid,
true);
335 const bool ok =
CheckOrphanBehavior(txdownload_impl, orphan, ret_1p1c_2reconsiderable, err_msg,
337 BOOST_CHECK_MESSAGE(ok, err_msg);
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.