@@ -355,6 +355,9 @@ BOOST_AUTO_TEST_CASE(noncontextual_package_tests)
355355
356356BOOST_AUTO_TEST_CASE (package_submission_tests)
357357{
358+ // Mine blocks to mature coinbases.
359+ mineBlocks (3 );
360+ MockMempoolMinFee (CFeeRate (5000 ));
358361 LOCK (cs_main);
359362 unsigned int expected_pool_size = m_node.mempool ->size ();
360363 CKey parent_key = GenerateRandomKey ();
@@ -478,6 +481,60 @@ BOOST_AUTO_TEST_CASE(package_submission_tests)
478481
479482 BOOST_CHECK_EQUAL (m_node.mempool ->size (), expected_pool_size);
480483 }
484+
485+ // In-mempool parent and child with missing parent.
486+ {
487+ auto tx_parent_1 = MakeTransactionRef (CreateValidMempoolTransaction (/* input_transaction=*/ m_coinbase_txns[1 ], /* input_vout=*/ 0 ,
488+ /* input_height=*/ 0 , /* input_signing_key=*/ coinbaseKey,
489+ /* output_destination=*/ parent_locking_script,
490+ /* output_amount=*/ CAmount (50 * COIN - low_fee_amt), /* submit=*/ false ));
491+ auto tx_parent_2 = MakeTransactionRef (CreateValidMempoolTransaction (/* input_transaction=*/ m_coinbase_txns[2 ], /* input_vout=*/ 0 ,
492+ /* input_height=*/ 0 , /* input_signing_key=*/ coinbaseKey,
493+ /* output_destination=*/ parent_locking_script,
494+ /* output_amount=*/ CAmount (50 * COIN - 800 ), /* submit=*/ false ));
495+
496+ auto tx_child_missing_parent = MakeTransactionRef (CreateValidMempoolTransaction ({tx_parent_1, tx_parent_2},
497+ {{tx_parent_1->GetHash (), 0 }, {tx_parent_2->GetHash (), 0 }},
498+ /* input_height=*/ 0 , {parent_key},
499+ {{49 * COIN, child_locking_script}}, /* submit=*/ false ));
500+
501+ Package package_missing_parent{tx_parent_1, tx_child_missing_parent};
502+
503+ const auto result_missing_parent = ProcessNewPackage (m_node.chainman ->ActiveChainstate (), *m_node.mempool ,
504+ package_missing_parent, /* test_accept=*/ false , /* client_maxfeerate=*/ {});
505+ if (auto err_missing_parent{CheckPackageMempoolAcceptResult (package_missing_parent, result_missing_parent, /* expect_valid=*/ false , m_node.mempool .get ())}) {
506+ BOOST_ERROR (err_missing_parent.value ());
507+ } else {
508+ auto it_parent = result_missing_parent.m_tx_results .find (tx_parent_1->GetWitnessHash ());
509+ auto it_child = result_missing_parent.m_tx_results .find (tx_child_missing_parent->GetWitnessHash ());
510+
511+ BOOST_CHECK_EQUAL (result_missing_parent.m_state .GetResult (), PackageValidationResult::PCKG_TX);
512+ BOOST_CHECK_EQUAL (result_missing_parent.m_state .GetRejectReason (), " transaction failed" );
513+
514+ BOOST_CHECK_EQUAL (it_parent->second .m_state .GetResult (), TxValidationResult::TX_RECONSIDERABLE);
515+ BOOST_CHECK_EQUAL (it_child->second .m_state .GetResult (), TxValidationResult::TX_MISSING_INPUTS);
516+ BOOST_CHECK_EQUAL (it_child->second .m_state .GetRejectReason (), " bad-txns-inputs-missingorspent" );
517+ BOOST_CHECK_EQUAL (m_node.mempool ->size (), expected_pool_size);
518+ }
519+
520+ // Submit parent2 ahead of time, should become ok.
521+ Package package_just_parent2{tx_parent_2};
522+ expected_pool_size += 1 ;
523+ const auto result_just_parent2 = ProcessNewPackage (m_node.chainman ->ActiveChainstate (), *m_node.mempool ,
524+ package_just_parent2, /* test_accept=*/ false , /* client_maxfeerate=*/ {});
525+ if (auto err_parent2{CheckPackageMempoolAcceptResult (package_just_parent2, result_just_parent2, /* expect_valid=*/ true , m_node.mempool .get ())}) {
526+ BOOST_ERROR (err_parent2.value ());
527+ }
528+ BOOST_CHECK_EQUAL (m_node.mempool ->size (), expected_pool_size);
529+
530+ const auto result_parent_already_in = ProcessNewPackage (m_node.chainman ->ActiveChainstate (), *m_node.mempool ,
531+ package_missing_parent, /* test_accept=*/ false , /* client_maxfeerate=*/ {});
532+ expected_pool_size += 2 ;
533+ if (auto err_parent_already_in{CheckPackageMempoolAcceptResult (package_missing_parent, result_parent_already_in, /* expect_valid=*/ true , m_node.mempool .get ())}) {
534+ BOOST_ERROR (err_parent_already_in.value ());
535+ }
536+ BOOST_CHECK_EQUAL (m_node.mempool ->size (), expected_pool_size);
537+ }
481538}
482539
483540// Tests for packages containing a single transaction
0 commit comments