122 std::chrono::microseconds now{
GetTime()};
125 for (
const auto segwit_parent : {
true,
false}) {
126 for (
const auto segwit_child : {
true,
false}) {
129 const auto& parent_txid = ptx_parent->GetHash();
130 const auto& parent_wtxid = ptx_parent->GetWitnessHash();
131 const auto& child_txid = ptx_child->GetHash();
132 const auto& child_wtxid = ptx_child->GetWitnessHash();
139 const auto& [keep, unique_txids, package_to_validate] = txdownload_impl.
MempoolRejectedTx(ptx_parent, state, nodeid,
true);
152 BOOST_TEST_MESSAGE(
"Testing behavior for " << result << (segwit_parent ?
" segwit " :
" nonsegwit"));
153 actual_behavior.
CheckEqual(expected_behavior, segwit_parent);
160 const bool parent_txid_rejected{segwit_parent ? expected_behavior.m_txid_in_rejects : expected_behavior.m_wtxid_in_rejects};
187 CAmount amount_depth_2{amount_depth_1 - 1000};
190 int test_chain_height{100};
198 size_t coinbase_idx{0};
200 for (
int decisions = 0; decisions < (1 << 4); ++decisions) {
201 auto mtx_single_parent = CreateValidMempoolTransaction(m_coinbase_txns[coinbase_idx], 0, test_chain_height, coinbaseKey, destination, amount_depth_1,
false);
202 auto single_parent = MakeTransactionRef(mtx_single_parent);
204 auto mtx_orphan = CreateValidMempoolTransaction(single_parent, 0, test_chain_height, wallet_key, destination, amount_depth_2,
false);
205 auto orphan = MakeTransactionRef(mtx_orphan);
214 const bool parent_recent_rej(decisions & 1);
215 const bool parent_recent_rej_recon((decisions >> 1) & 1);
216 const bool parent_recent_conf((decisions >> 2) & 1);
217 const bool parent_in_mempool((decisions >> 3) & 1);
222 if (parent_in_mempool) {
223 const auto mempool_result =
WITH_LOCK(
::cs_main,
return m_node.chainman->ProcessTransaction(single_parent));
226 assert(coinbase_idx < m_coinbase_txns.size());
232 const bool expect_keep_orphan = !parent_recent_rej;
233 const unsigned int expected_parents = parent_recent_rej || parent_recent_conf || parent_in_mempool ? 0 : 1;
236 BOOST_CHECK(expect_keep_orphan || expected_parents == 0);
237 const auto ret_1p1c = txdownload_impl.
MempoolRejectedTx(orphan, state_orphan, nodeid,
true);
240 expect_keep_orphan,
true, expected_parents);
241 BOOST_CHECK_MESSAGE(ok, err_msg);
246 std::vector<CTransactionRef> parents;
247 std::vector<COutPoint> outpoints;
248 int32_t num_parents{24};
249 for (int32_t i = 0; i < num_parents; ++i) {
250 assert(coinbase_idx < m_coinbase_txns.size());
251 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[coinbase_idx++], 0, test_chain_height,
252 coinbaseKey, destination, amount_depth_1 + i,
false);
253 auto ptx_parent = MakeTransactionRef(mtx_parent);
254 parents.emplace_back(ptx_parent);
255 outpoints.emplace_back(ptx_parent->GetHash(), 0);
259 auto mtx_orphan = CreateValidMempoolTransaction(parents, outpoints, test_chain_height, {wallet_key}, {{amount_depth_2 * num_parents, destination}},
false);
260 auto orphan = MakeTransactionRef(mtx_orphan);
268 const auto ret_1p1c_parent_reconsiderable = txdownload_impl.
MempoolRejectedTx(orphan, state_orphan, nodeid,
true);
270 const bool ok =
CheckOrphanBehavior(txdownload_impl, orphan, ret_1p1c_parent_reconsiderable, err_msg,
271 true,
true, num_parents);
272 BOOST_CHECK_MESSAGE(ok, err_msg);
281 for (int32_t i = 1; i < num_parents; ++i) {
284 const unsigned int expected_parents = 1;
286 const auto ret_1recon_conf = txdownload_impl.
MempoolRejectedTx(orphan, state_orphan, nodeid,
true);
289 true,
true, expected_parents);
290 BOOST_CHECK_MESSAGE(ok, err_msg);
294 for (
int i = 0; i < 2; ++i) {
301 auto& alreadyhave_parent = parents[0];
308 const auto ret_2_problems = txdownload_impl.
MempoolRejectedTx(orphan, state_orphan, nodeid,
true);
312 BOOST_CHECK_MESSAGE(ok, err_msg);
318 assert(coinbase_idx < m_coinbase_txns.size());
319 auto parent_2outputs = MakeTransactionRef(CreateValidMempoolTransaction({m_coinbase_txns[coinbase_idx]}, {{m_coinbase_txns[coinbase_idx]->GetHash(), 0}}, test_chain_height, {coinbaseKey},
320 {{amount_split_half, destination}, {amount_split_half, destination}},
false));
322 auto orphan = MakeTransactionRef(CreateValidMempoolTransaction({parent_2outputs}, {{parent_2outputs->GetHash(), 0}, {parent_2outputs->GetHash(), 1}},
323 test_chain_height, {wallet_key}, {{amount_depth_2, destination}},
false));
331 const auto ret_1p1c_2reconsiderable = txdownload_impl.
MempoolRejectedTx(orphan, state_orphan, nodeid,
true);
333 const bool ok =
CheckOrphanBehavior(txdownload_impl, orphan, ret_1p1c_2reconsiderable, err_msg,
335 BOOST_CHECK_MESSAGE(ok, err_msg);
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.