207 unsigned int initialPoolSize = m_node.mempool->size();
212 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
214 parent_locking_script,
220 auto mtx_child = CreateValidMempoolTransaction(tx_parent, 0,
222 child_locking_script,
225 Package package_parent_child{tx_parent, tx_child};
226 const auto result_parent_child =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_parent_child,
true, {});
228 BOOST_ERROR(err_parent_child.value());
230 auto it_parent = result_parent_child.m_tx_results.find(tx_parent->GetWitnessHash());
231 auto it_child = result_parent_child.m_tx_results.find(tx_child->GetWitnessHash());
234 BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().size(), 1);
235 BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().front(), tx_parent->GetWitnessHash());
239 BOOST_CHECK_EQUAL(it_child->second.m_wtxids_fee_calculations.value().front(), tx_child->GetWitnessHash());
244 Package package_single_giant{giant_ptx};
245 auto result_single_large =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_single_giant,
true, {});
247 BOOST_ERROR(err_single_large.value());
250 BOOST_CHECK_EQUAL(result_single_large.m_state.GetRejectReason(),
"transaction failed");
251 auto it_giant_tx = result_single_large.m_tx_results.find(giant_ptx->GetWitnessHash());
269 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0, 0, coinbaseKey, spk,
273 auto mtx_child = CreateValidMempoolTransaction(tx_parent, 0, 101, placeholder_key, spk2,
295 for (
int i{0}; i < 24; ++i) {
296 auto parent =
MakeTransactionRef(CreateValidMempoolTransaction(m_coinbase_txns[i + 1],
297 0, 0, coinbaseKey, spk,
CAmount(48 *
COIN),
false));
298 package.emplace_back(parent);
299 child.
vin.emplace_back(
COutPoint(parent->GetHash(), 0));
301 child.
vout.emplace_back(47 *
COIN, spk2);
308 std::shuffle(package.begin(), package.end(), rng);
316 package.erase(package.begin());
320 package.insert(package.begin(), m_coinbase_txns[0]);
327 mtx_parent.
vin.emplace_back(
COutPoint(m_coinbase_txns[0]->GetHash(), 0));
328 mtx_parent.
vout.emplace_back(20 *
COIN, spk);
329 mtx_parent.
vout.emplace_back(20 *
COIN, spk2);
333 mtx_parent_also_child.
vin.emplace_back(
COutPoint(tx_parent->GetHash(), 0));
334 mtx_parent_also_child.
vout.emplace_back(20 *
COIN, spk);
338 mtx_child.
vin.emplace_back(
COutPoint(tx_parent->GetHash(), 1));
339 mtx_child.
vin.emplace_back(
COutPoint(tx_parent_also_child->GetHash(), 0));
340 mtx_child.
vout.emplace_back(39 *
COIN, spk);
363 unsigned int expected_pool_size = m_node.mempool->size();
369 for (
size_t i{0}; i < 10; ++i) {
370 auto mtx = CreateValidMempoolTransaction(m_coinbase_txns[i + 25], 0,
372 parent_locking_script,
376 auto result_unrelated_submit =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
377 package_unrelated,
false, {});
379 BOOST_CHECK(result_unrelated_submit.m_state.IsInvalid());
381 BOOST_CHECK_EQUAL(result_unrelated_submit.m_state.GetRejectReason(),
"package-not-child-with-parents");
387 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
389 parent_locking_script,
392 package_parent_child.push_back(tx_parent);
393 package_3gen.push_back(tx_parent);
397 auto mtx_child = CreateValidMempoolTransaction(tx_parent, 0,
399 child_locking_script,
402 package_parent_child.push_back(tx_child);
403 package_3gen.push_back(tx_child);
407 auto mtx_grandchild = CreateValidMempoolTransaction(tx_child, 0,
409 grandchild_locking_script,
412 package_3gen.push_back(tx_grandchild);
416 auto result_3gen_submit =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
417 package_3gen,
false, {});
418 BOOST_CHECK(result_3gen_submit.m_state.IsInvalid());
420 BOOST_CHECK_EQUAL(result_3gen_submit.m_state.GetRejectReason(),
"package-not-child-with-parents");
428 bad_witness.
stack.emplace_back(1);
430 mtx_parent_invalid.
vin[0].scriptWitness = bad_witness;
432 Package package_invalid_parent{tx_parent_invalid, tx_child};
433 auto result_quit_early =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
434 package_invalid_parent,
false, {});
436 BOOST_ERROR(err_parent_invalid.value());
438 auto it_parent = result_quit_early.m_tx_results.find(tx_parent_invalid->GetWitnessHash());
439 auto it_child = result_quit_early.m_tx_results.find(tx_child->GetWitnessHash());
441 BOOST_CHECK_EQUAL(it_parent->second.m_state.GetRejectReason(),
"bad-witness-nonstandard");
443 BOOST_CHECK_EQUAL(it_child->second.m_state.GetRejectReason(),
"bad-txns-inputs-missingorspent");
450 const auto submit_parent_child =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
451 package_parent_child,
false, {});
452 expected_pool_size += 2;
453 BOOST_CHECK_MESSAGE(submit_parent_child.m_state.IsValid(),
454 "Package validation unexpectedly failed: " << submit_parent_child.m_state.GetRejectReason());
455 BOOST_CHECK_EQUAL(submit_parent_child.m_tx_results.size(), package_parent_child.size());
456 auto it_parent = submit_parent_child.m_tx_results.find(tx_parent->GetWitnessHash());
457 auto it_child = submit_parent_child.m_tx_results.find(tx_child->GetWitnessHash());
458 BOOST_CHECK(it_parent != submit_parent_child.m_tx_results.end());
461 BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().size(), 1);
462 BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().front(), tx_parent->GetWitnessHash());
465 BOOST_CHECK_EQUAL(it_child->second.m_wtxids_fee_calculations.value().front(), tx_child->GetWitnessHash());
472 const auto submit_deduped =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
473 package_parent_child,
false, {});
475 BOOST_ERROR(err_deduped.value());
477 auto it_parent_deduped = submit_deduped.m_tx_results.find(tx_parent->GetWitnessHash());
478 auto it_child_deduped = submit_deduped.m_tx_results.find(tx_child->GetWitnessHash());
488 auto tx_parent_1 =
MakeTransactionRef(CreateValidMempoolTransaction(m_coinbase_txns[1], 0,
490 parent_locking_script,
492 auto tx_parent_2 =
MakeTransactionRef(CreateValidMempoolTransaction(m_coinbase_txns[2], 0,
494 parent_locking_script,
497 auto tx_child_missing_parent =
MakeTransactionRef(CreateValidMempoolTransaction({tx_parent_1, tx_parent_2},
498 {{tx_parent_1->GetHash(), 0}, {tx_parent_2->GetHash(), 0}},
500 {{49 *
COIN, child_locking_script}},
false));
502 Package package_missing_parent{tx_parent_1, tx_child_missing_parent};
504 const auto result_missing_parent =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
505 package_missing_parent,
false, {});
507 BOOST_ERROR(err_missing_parent.value());
509 auto it_parent = result_missing_parent.m_tx_results.find(tx_parent_1->GetWitnessHash());
510 auto it_child = result_missing_parent.m_tx_results.find(tx_child_missing_parent->GetWitnessHash());
513 BOOST_CHECK_EQUAL(result_missing_parent.m_state.GetRejectReason(),
"transaction failed");
517 BOOST_CHECK_EQUAL(it_child->second.m_state.GetRejectReason(),
"bad-txns-inputs-missingorspent");
522 Package package_just_parent2{tx_parent_2};
523 expected_pool_size += 1;
524 const auto result_just_parent2 =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
525 package_just_parent2,
false, {});
527 BOOST_ERROR(err_parent2.value());
531 const auto result_parent_already_in =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
532 package_missing_parent,
false, {});
533 expected_pool_size += 2;
535 BOOST_ERROR(err_parent_already_in.value());
547 auto expected_pool_size{m_node.mempool->size()};
554 auto mtx_single = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
556 single_locking_script,
559 Package package_tx_single{tx_single};
560 const auto result_single_tx =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
561 package_tx_single,
false, {});
562 expected_pool_size += 1;
563 BOOST_CHECK_MESSAGE(result_single_tx.m_state.IsValid(),
564 "Package validation unexpectedly failed: " << result_single_tx.m_state.ToString());
570 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[1], 0,
572 parent_locking_script,
575 Package package_just_parent{tx_parent};
576 const auto result_just_parent =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_just_parent,
false, {});
578 BOOST_ERROR(err_parent_child.value());
580 auto it_parent = result_just_parent.m_tx_results.find(tx_parent->GetWitnessHash());
581 BOOST_CHECK_MESSAGE(it_parent->second.m_state.IsValid(), it_parent->second.m_state.ToString());
583 BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().size(), 1);
584 BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().front(), tx_parent->GetWitnessHash());
586 expected_pool_size += 1;
591 auto mtx_child = CreateValidMempoolTransaction(tx_parent, 0,
593 child_locking_script,
596 Package package_just_child{tx_child};
597 const auto result_just_child =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_just_child,
false, {});
599 BOOST_ERROR(err_parent_child.value());
601 auto it_child = result_just_child.m_tx_results.find(tx_child->GetWitnessHash());
602 BOOST_CHECK_MESSAGE(it_child->second.m_state.IsValid(), it_child->second.m_state.ToString());
605 BOOST_CHECK_EQUAL(it_child->second.m_wtxids_fee_calculations.value().front(), tx_child->GetWitnessHash());
607 expected_pool_size += 1;
611 auto mtx_single_low_fee = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
613 single_locking_script,
616 Package package_tx_single_low_fee{tx_single_low_fee};
617 const auto result_single_tx_low_fee =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
618 package_tx_single_low_fee,
false, {});
622 BOOST_CHECK(!result_single_tx_low_fee.m_state.IsValid());
624 auto it_low_fee = result_single_tx_low_fee.m_tx_results.find(tx_single_low_fee->GetWitnessHash());
627 BOOST_ERROR(err_single.value());
645 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
653 witness1.
stack.emplace_back(1);
654 witness1.
stack.emplace_back(witnessScript.
begin(), witnessScript.
end());
657 witness2.
stack.emplace_back(2);
658 witness2.
stack.emplace_back(witnessScript.
begin(), witnessScript.
end());
664 mtx_child1.
vin.resize(1);
665 mtx_child1.
vin[0].prevout.hash = ptx_parent->GetHash();
666 mtx_child1.
vin[0].prevout.n = 0;
668 mtx_child1.
vin[0].scriptWitness = witness1;
669 mtx_child1.
vout.resize(1);
671 mtx_child1.
vout[0].scriptPubKey = child_locking_script;
674 mtx_child2.
vin[0].scriptWitness = witness2;
682 BOOST_CHECK(ptx_child1->GetWitnessHash() != ptx_child2->GetWitnessHash());
689 Package package_parent_child1{ptx_parent, ptx_child1};
690 const auto submit_witness1 =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
691 package_parent_child1,
false, {});
693 BOOST_ERROR(err_witness1.value());
697 Package package_parent_child2{ptx_parent, ptx_child2};
698 const auto submit_witness2 =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
699 package_parent_child2,
false, {});
701 BOOST_ERROR(err_witness2.value());
703 auto it_parent2_deduped = submit_witness2.m_tx_results.find(ptx_parent->GetWitnessHash());
704 auto it_child2 = submit_witness2.m_tx_results.find(ptx_child2->GetWitnessHash());
707 BOOST_CHECK_EQUAL(ptx_child1->GetWitnessHash(), it_child2->second.m_other_wtxid.value());
712 const auto submit_segwit_dedup =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
713 package_parent_child1,
false, {});
715 BOOST_ERROR(err_segwit_dedup.value());
717 auto it_parent_dup = submit_segwit_dedup.m_tx_results.find(ptx_parent->GetWitnessHash());
718 auto it_child_dup = submit_segwit_dedup.m_tx_results.find(ptx_child1->GetWitnessHash());
733 auto mtx_grandchild = CreateValidMempoolTransaction(ptx_child2, 0,
735 grandchild_locking_script,
742 Package package_child2_grandchild{ptx_child2, ptx_grandchild};
743 const auto submit_spend_ignored =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
744 package_child2_grandchild,
false, {});
746 BOOST_ERROR(err_spend_ignored.value());
748 auto it_child2_ignored = submit_spend_ignored.m_tx_results.find(ptx_child2->GetWitnessHash());
749 auto it_grandchild = submit_spend_ignored.m_tx_results.find(ptx_grandchild->GetWitnessHash());
763 acs_witness.
stack.emplace_back(acs_script.
begin(), acs_script.
end());
766 auto mtx_parent1 = CreateValidMempoolTransaction(m_coinbase_txns[1], 0,
771 package_mixed.push_back(ptx_parent1);
777 parent2_witness1.
stack.emplace_back(1);
778 parent2_witness1.
stack.emplace_back(grandparent2_script.
begin(), grandparent2_script.
end());
780 parent2_witness2.
stack.emplace_back(2);
781 parent2_witness2.
stack.emplace_back(grandparent2_script.
begin(), grandparent2_script.
end());
784 auto mtx_grandparent2 = CreateValidMempoolTransaction(m_coinbase_txns[2], 0,
792 mtx_parent2_v1.
vin.resize(1);
793 mtx_parent2_v1.
vin[0].prevout.hash = ptx_grandparent2->GetHash();
794 mtx_parent2_v1.
vin[0].prevout.n = 0;
796 mtx_parent2_v1.
vin[0].scriptWitness = parent2_witness1;
797 mtx_parent2_v1.
vout.resize(1);
799 mtx_parent2_v1.
vout[0].scriptPubKey = acs_spk;
802 mtx_parent2_v2.
vin[0].scriptWitness = parent2_witness2;
807 const MempoolAcceptResult parent2_v2_result = m_node.chainman->ProcessTransaction(ptx_parent2_v2);
809 package_mixed.push_back(ptx_parent2_v1);
812 auto mtx_parent3 = CreateValidMempoolTransaction(m_coinbase_txns[3], 0,
817 package_mixed.push_back(ptx_parent3);
826 mtx_mixed_child.
vin.emplace_back(
COutPoint(ptx_parent1->GetHash(), 0));
827 mtx_mixed_child.
vin.emplace_back(
COutPoint(ptx_parent2_v1->GetHash(), 0));
828 mtx_mixed_child.
vin.emplace_back(
COutPoint(ptx_parent3->GetHash(), 0));
829 mtx_mixed_child.
vin[0].scriptWitness = acs_witness;
830 mtx_mixed_child.
vin[1].scriptWitness = acs_witness;
831 mtx_mixed_child.
vin[2].scriptWitness = acs_witness;
832 mtx_mixed_child.
vout.emplace_back((48 + 49 + 50 - 1) *
COIN, mixed_child_spk);
834 package_mixed.push_back(ptx_mixed_child);
842 const auto mixed_result =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package_mixed,
false, {});
844 BOOST_ERROR(err_mixed.value());
846 auto it_parent1 = mixed_result.m_tx_results.find(ptx_parent1->GetWitnessHash());
847 auto it_parent2 = mixed_result.m_tx_results.find(ptx_parent2_v1->GetWitnessHash());
848 auto it_parent3 = mixed_result.m_tx_results.find(ptx_parent3->GetWitnessHash());
849 auto it_child = mixed_result.m_tx_results.find(ptx_mixed_child->GetWitnessHash());
855 BOOST_CHECK_EQUAL(ptx_parent2_v2->GetWitnessHash(), it_parent2->second.m_other_wtxid.value());
859 BOOST_CHECK(it_parent3->second.m_effective_feerate.value() == expected_feerate);
860 BOOST_CHECK(it_child->second.m_effective_feerate.value() == expected_feerate);
861 std::vector<Wtxid> expected_wtxids({ptx_parent3->GetWitnessHash(), ptx_mixed_child->GetWitnessHash()});
862 BOOST_CHECK(it_parent3->second.m_wtxids_fee_calculations.value() == expected_wtxids);
863 BOOST_CHECK(it_child->second.m_wtxids_fee_calculations.value() == expected_wtxids);
873 size_t expected_pool_size = m_node.mempool->size();
885 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
888 parent_value,
false);
890 package_cpfp.push_back(tx_parent);
892 auto mtx_child = CreateValidMempoolTransaction(tx_parent, 0,
897 package_cpfp.push_back(tx_child);
902 m_node.mempool->PrioritiseTransaction(tx_parent->GetHash(), child_value - coinbase_value);
905 const auto submit_cpfp_deprio =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
906 package_cpfp,
false, {});
908 BOOST_ERROR(err_cpfp_deprio.value());
911 BOOST_CHECK_EQUAL(submit_cpfp_deprio.m_tx_results.find(tx_parent->GetWitnessHash())->second.m_state.GetResult(),
913 BOOST_CHECK_EQUAL(submit_cpfp_deprio.m_tx_results.find(tx_child->GetWitnessHash())->second.m_state.GetResult(),
915 BOOST_CHECK_EQUAL(submit_cpfp_deprio.m_tx_results.find(tx_parent->GetWitnessHash())->second.m_state.GetRejectReason(),
"mempool min fee not met");
921 WITH_LOCK(m_node.mempool->cs, m_node.mempool->ClearPrioritisation(tx_parent->GetHash()));
927 const auto submit_cpfp =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
928 package_cpfp,
false, {});
930 BOOST_ERROR(err_cpfp.value());
932 auto it_parent = submit_cpfp.m_tx_results.find(tx_parent->GetWitnessHash());
933 auto it_child = submit_cpfp.m_tx_results.find(tx_child->GetWitnessHash());
935 BOOST_CHECK(it_parent->second.m_base_fees.value() == coinbase_value - parent_value);
939 const CFeeRate expected_feerate(coinbase_value - child_value,
941 BOOST_CHECK(it_parent->second.m_effective_feerate.value() == expected_feerate);
942 BOOST_CHECK(it_child->second.m_effective_feerate.value() == expected_feerate);
943 std::vector<Wtxid> expected_wtxids({tx_parent->GetWitnessHash(), tx_child->GetWitnessHash()});
944 BOOST_CHECK(it_parent->second.m_wtxids_fee_calculations.value() == expected_wtxids);
945 BOOST_CHECK(it_child->second.m_wtxids_fee_calculations.value() == expected_wtxids);
948 expected_pool_size += 2;
958 auto mtx_parent_cheap = CreateValidMempoolTransaction(m_coinbase_txns[1], 0,
961 coinbase_value - parent_fee,
false);
963 package_still_too_low.push_back(tx_parent_cheap);
967 auto mtx_child_cheap = CreateValidMempoolTransaction(tx_parent_cheap, 0,
970 coinbase_value - parent_fee - child_fee,
false);
972 package_still_too_low.push_back(tx_child_cheap);
979 const auto submit_package_too_low =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
980 package_still_too_low,
false, {});
982 BOOST_ERROR(err_package_too_low.value());
985 BOOST_CHECK_EQUAL(submit_package_too_low.m_tx_results.at(tx_parent_cheap->GetWitnessHash()).m_state.GetResult(),
987 BOOST_CHECK(submit_package_too_low.m_tx_results.at(tx_parent_cheap->GetWitnessHash()).m_effective_feerate.value() ==
990 BOOST_CHECK_EQUAL(submit_package_too_low.m_tx_results.at(tx_child_cheap->GetWitnessHash()).m_state.GetResult(),
992 BOOST_CHECK(submit_package_too_low.m_tx_results.at(tx_child_cheap->GetWitnessHash()).m_effective_feerate.value() ==
996 BOOST_CHECK_EQUAL(submit_package_too_low.m_state.GetRejectReason(),
"transaction failed");
1002 m_node.mempool->PrioritiseTransaction(tx_child_cheap->GetHash(), 1 *
COIN);
1005 const auto submit_prioritised_package =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
1006 package_still_too_low,
false, {});
1008 BOOST_ERROR(err_prioritised.value());
1010 const CFeeRate expected_feerate(1 *
COIN + parent_fee + child_fee,
1012 BOOST_CHECK_EQUAL(submit_prioritised_package.m_tx_results.size(), package_still_too_low.size());
1013 auto it_parent = submit_prioritised_package.m_tx_results.find(tx_parent_cheap->GetWitnessHash());
1014 auto it_child = submit_prioritised_package.m_tx_results.find(tx_child_cheap->GetWitnessHash());
1016 BOOST_CHECK(it_parent->second.m_base_fees.value() == parent_fee);
1017 BOOST_CHECK(it_parent->second.m_effective_feerate.value() == expected_feerate);
1019 BOOST_CHECK(it_child->second.m_base_fees.value() == child_fee);
1020 BOOST_CHECK(it_child->second.m_effective_feerate.value() == expected_feerate);
1021 std::vector<Wtxid> expected_wtxids({tx_parent_cheap->GetWitnessHash(), tx_child_cheap->GetWitnessHash()});
1022 BOOST_CHECK(it_parent->second.m_wtxids_fee_calculations.value() == expected_wtxids);
1023 BOOST_CHECK(it_child->second.m_wtxids_fee_calculations.value() == expected_wtxids);
1025 expected_pool_size += 2;
1036 auto mtx_parent_rich = CreateValidMempoolTransaction(m_coinbase_txns[2], 0,
1039 coinbase_value - high_parent_fee,
false);
1041 package_rich_parent.push_back(tx_parent_rich);
1043 auto mtx_child_poor = CreateValidMempoolTransaction(tx_parent_rich, 0,
1046 coinbase_value - high_parent_fee,
false);
1048 package_rich_parent.push_back(tx_child_poor);
1053 const auto submit_rich_parent =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool,
1054 package_rich_parent,
false, {});
1056 BOOST_ERROR(err_rich_parent.value());
1060 BOOST_CHECK_EQUAL(submit_rich_parent.m_state.GetRejectReason(),
"transaction failed");
1062 auto it_parent = submit_rich_parent.m_tx_results.find(tx_parent_rich->GetWitnessHash());
1063 auto it_child = submit_rich_parent.m_tx_results.find(tx_child_poor->GetWitnessHash());
1066 BOOST_CHECK(it_parent->second.m_state.GetRejectReason() ==
"");
1067 BOOST_CHECK_MESSAGE(it_parent->second.m_base_fees.value() == high_parent_fee,
1068 strprintf(
"rich parent: expected fee %s, got %s", high_parent_fee, it_parent->second.m_base_fees.value()));
1072 BOOST_CHECK_EQUAL(it_child->second.m_state.GetRejectReason(),
"mempool min fee not met");
1074 expected_pool_size += 1;
1083 size_t expected_pool_size = m_node.mempool->size();
1097 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
1102 package1.push_back(tx_parent);
1103 package2.push_back(tx_parent);
1106 package1.push_back(tx_child_1);
1108 package2.push_back(tx_child_2);
1110 LOCK(m_node.mempool->cs);
1111 const auto submit1 =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package1,
false, std::nullopt);
1113 BOOST_ERROR(err_1.value());
1117 auto it_parent_1 = submit1.m_tx_results.find(tx_parent->GetWitnessHash());
1118 auto it_child_1 = submit1.m_tx_results.find(tx_child_1->GetWitnessHash());
1121 expected_pool_size += 2;
1124 const auto submit2 =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package2,
false, std::nullopt);
1126 BOOST_ERROR(err_2.value());
1130 auto it_parent_2 = submit2.m_tx_results.find(tx_parent->GetWitnessHash());
1131 auto it_child_2 = submit2.m_tx_results.find(tx_child_2->GetWitnessHash());
1137 BOOST_CHECK(!m_node.mempool->exists(tx_child_1->GetHash()));
1143 m_coinbase_txns[1], 0, 0,
1144 coinbaseKey, parent_spk, coinbase_value - 200,
false));
1146 tx_parent_1, 0, 101,
1147 child_key, child_spk, coinbase_value - 400,
false));
1150 m_coinbase_txns[1], 0, 0,
1151 coinbaseKey, parent_spk, coinbase_value - 800,
false));
1153 tx_parent_2, 0, 101,
1154 child_key, child_spk, coinbase_value - 800 - 200,
false));
1157 m_coinbase_txns[1], 0, 0,
1158 coinbaseKey, parent_spk, coinbase_value - 199,
false));
1160 tx_parent_3, 0, 101,
1161 child_key, child_spk, coinbase_value - 199 - 1300,
false));
1164 BOOST_CHECK(tx_parent_1->GetHash() != tx_parent_2->GetHash() && tx_parent_2->GetHash() != tx_parent_3->GetHash());
1167 Package package1{tx_parent_1, tx_child_1};
1169 Package package2{tx_parent_2, tx_child_2};
1171 Package package3{tx_parent_3, tx_child_3};
1173 const auto submit1 =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package1,
false, std::nullopt);
1175 BOOST_ERROR(err_1.value());
1177 auto it_parent_1 = submit1.m_tx_results.find(tx_parent_1->GetWitnessHash());
1178 auto it_child_1 = submit1.m_tx_results.find(tx_child_1->GetWitnessHash());
1181 expected_pool_size += 2;
1186 const auto submit2 =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package2,
false, std::nullopt);
1188 BOOST_ERROR(err_2.value());
1190 auto it_parent_2 = submit2.m_tx_results.find(tx_parent_2->GetWitnessHash());
1191 auto it_child_2 = submit2.m_tx_results.find(tx_child_2->GetWitnessHash());
1197 const auto submit3 =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package3,
false, std::nullopt);
1199 BOOST_ERROR(err_3.value());
1201 auto it_parent_3 = submit3.m_tx_results.find(tx_parent_3->GetWitnessHash());
1202 auto it_child_3 = submit3.m_tx_results.find(tx_child_3->GetWitnessHash());
1207 BOOST_CHECK(it_parent_3->second.m_replaced_transactions.size() == 2);
1208 BOOST_CHECK(it_child_3->second.m_replaced_transactions.empty());
1210 std::vector<Wtxid> expected_package3_wtxids({tx_parent_3->GetWitnessHash(), tx_child_3->GetWitnessHash()});
1212 BOOST_CHECK(it_parent_3->second.m_wtxids_fee_calculations.value() == expected_package3_wtxids);
1213 BOOST_CHECK(it_child_3->second.m_wtxids_fee_calculations.value() == expected_package3_wtxids);
1214 BOOST_CHECK_EQUAL(it_parent_3->second.m_effective_feerate.value().GetFee(package3_total_vsize), 199 + 1300);
1215 BOOST_CHECK_EQUAL(it_child_3->second.m_effective_feerate.value().GetFee(package3_total_vsize), 199 + 1300);
1221 const auto submit4 =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package1,
false, std::nullopt);
1223 BOOST_ERROR(err_4.value());
1225 m_node.mempool->PrioritiseTransaction(tx_child_1->GetHash(), 1363);
1226 const auto submit5 =
ProcessNewPackage(m_node.chainman->ActiveChainstate(), *m_node.mempool, package1,
false, std::nullopt);
1228 BOOST_ERROR(err_5.value());
1230 it_parent_1 = submit5.m_tx_results.find(tx_parent_1->GetWitnessHash());
1231 it_child_1 = submit5.m_tx_results.find(tx_child_1->GetWitnessHash());
1234 LOCK(m_node.mempool->cs);
1235 BOOST_CHECK(m_node.mempool->GetIter(tx_parent_1->GetHash()).has_value());
1236 BOOST_CHECK(m_node.mempool->GetIter(tx_child_1->GetHash()).has_value());
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.