21 #include <boost/test/unit_test.hpp> 32 mtx.
vin.resize(num_inputs);
33 mtx.
vout.resize(num_outputs);
35 for (
size_t i{0}; i < num_inputs; ++i) {
37 mtx.
vin[i].prevout.n = 0;
38 mtx.
vin[i].scriptSig = random_script;
40 for (
size_t o{0}; o < num_outputs; ++o) {
42 mtx.
vout[o].scriptPubKey = random_script;
50 ParseHex(
"02000000000101964b8aa63509579ca6086e6012eeaa4c2f4dd1e283da29b67c8eea38b3c6fd220000000000fdffffff0294c618000000000017a9145afbbb42f4e83312666d0697f9e66259912ecde38768fa2c0000000000160014897388a0889390fd0e153a22bb2cf9d8f019faf50247304402200547406380719f84d68cf4e96cc3e4a1688309ef475b150be2b471c70ea562aa02206d255f5acc40fd95981874d77201d2eb07883657ce1c796513f32b6079545cdf0121023ae77335cefcb5ab4c1dc1fb0d2acfece184e593727d7d5906c78e564c7c11d125cf0c00"),
57 ParseHex(
"01000000010b26e9b7735eb6aabdf358bab62f9816a21ba9ebdb719d5299e88607d722c190000000008b4830450220070aca44506c5cef3a16ed519d7c3c39f8aab192c4e1c90d065f37b8a4af6141022100a8e160b856c2d43d27d8fba71e5aef6405b8643ac4cb7cb3c462aced7f14711a0141046d11fee51b0e60666d5049a9101a72741df480b96ee26488a4d3466b95c9a40ac5eeef87e10a5cd336c19a84565f80fa6c547957b7700ff4dfbdefe76036c339ffffffff021bff3d11000000001976a91404943fdd508053c75000106d3bc6e2754dbcff1988ac2f15de00000000001976a914a266436d2965547608b9e15d9032a7b9d64fa43188ac00000000"),
64 ParseHex(
"0200000000010177862801f77c2c068a70372b4c435ef8dd621291c36a64eb4dd491f02218f5324600000000fdffffff014a0100000000000022512035ea312034cfac01e956a269f3bf147f569c2fbb00180677421262da042290d803402be713325ff285e66b0380f53f2fae0d0fb4e16f378a440fed51ce835061437566729d4883bc917632f3cff474d6384bc8b989961a1d730d4a87ed38ad28bd337b20f1d658c6c138b1c312e072b4446f50f01ae0da03a42e6274f8788aae53416a7fac0063036f7264010118746578742f706c61696e3b636861727365743d7574662d3800357b2270223a226272632d3230222c226f70223a226d696e74222c227469636b223a224342414c222c22616d74223a2236393639227d6821c1f1d658c6c138b1c312e072b4446f50f01ae0da03a42e6274f8788aae53416a7f00000000"),
70 Wtxid wtxid_1{
Wtxid::FromHex(
"85cd1a31eb38f74ed5742ec9cb546712ab5aaf747de28a9168b53e846cbda17f").value()};
71 Wtxid wtxid_2{
Wtxid::FromHex(
"b4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b").value()};
72 Wtxid wtxid_3{
Wtxid::FromHex(
"e065bac15f62bb4e761d761db928ddee65a47296b2b776785abb912cdec474e3").value()};
81 Txid txid_1{
Txid::FromHex(
"bd0f71c1d5e50589063e134fad22053cdae5ab2320db5bf5e540198b0b5a4e69").value()};
82 Txid txid_2{
Txid::FromHex(
"b4749f017444b051c44dfd2720e88f314ff94f3dd6d56d40ef65854fcd7fff6b").value()};
83 Txid txid_3{
Txid::FromHex(
"ee707be5201160e32c4fc715bec227d1aeea5940fb4295605e7373edce3b1a93").value()};
90 BOOST_CHECK(txid_1.ToUint256() != wtxid_1.ToUint256());
91 BOOST_CHECK(txid_2.ToUint256() == wtxid_2.ToUint256());
92 BOOST_CHECK(txid_3.ToUint256() != wtxid_3.ToUint256());
101 std::vector<CTransactionRef> package_123{ptx_1, ptx_2, ptx_3};
102 std::vector<CTransactionRef> package_132{ptx_1, ptx_3, ptx_2};
103 std::vector<CTransactionRef> package_231{ptx_2, ptx_3, ptx_1};
104 std::vector<CTransactionRef> package_213{ptx_2, ptx_1, ptx_3};
105 std::vector<CTransactionRef> package_312{ptx_3, ptx_1, ptx_2};
106 std::vector<CTransactionRef> package_321{ptx_3, ptx_2, ptx_1};
108 uint256 calculated_hash_123 = (
HashWriter() << wtxid_1 << wtxid_2 << wtxid_3).GetSHA256();
110 uint256 hash_if_by_txid = (
HashWriter() << wtxid_2 << wtxid_1 << wtxid_3).GetSHA256();
111 BOOST_CHECK(hash_if_by_txid != calculated_hash_123);
113 uint256 hash_if_use_txid = (
HashWriter() << txid_2 << txid_1 << txid_3).GetSHA256();
114 BOOST_CHECK(hash_if_use_txid != calculated_hash_123);
116 uint256 hash_if_use_int_order = (
HashWriter() << wtxid_2 << wtxid_1 << wtxid_3).GetSHA256();
117 BOOST_CHECK(hash_if_use_int_order != calculated_hash_123);
144 size_t total_weight{0};
146 package_too_large.push_back(large_ptx);
147 total_weight += size_large;
156 Package package_duplicate_txids_empty;
157 for (
auto i{0}; i < 3; ++i) {
171 tx_zero_1.
vin.emplace_back(same_prevout);
172 tx_zero_2.
vin.emplace_back(same_prevout);
189 dup_tx.vin.emplace_back(rand_prevout);
190 dup_tx.vin.emplace_back(rand_prevout);
205 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
207 parent_locking_script,
213 auto mtx_child = CreateValidMempoolTransaction(tx_parent, 0,
215 child_locking_script,
218 Package package_parent_child{tx_parent, tx_child};
221 BOOST_ERROR(err_parent_child.value());
223 auto it_parent = result_parent_child.
m_tx_results.find(tx_parent->GetWitnessHash());
224 auto it_child = result_parent_child.m_tx_results.find(tx_child->GetWitnessHash());
227 BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().size(), 1);
228 BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().front(), tx_parent->GetWitnessHash());
232 BOOST_CHECK_EQUAL(it_child->second.m_wtxids_fee_calculations.value().front(), tx_child->GetWitnessHash());
237 Package package_single_giant{giant_ptx};
240 BOOST_ERROR(err_single_large.value());
243 BOOST_CHECK_EQUAL(result_single_large.m_state.GetRejectReason(),
"transaction failed");
244 auto it_giant_tx = result_single_large.m_tx_results.find(giant_ptx->GetWitnessHash());
262 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0, 0, coinbaseKey, spk,
266 auto mtx_child = CreateValidMempoolTransaction(tx_parent, 0, 101, placeholder_key, spk2,
286 for (
int i{0}; i < 24; ++i) {
287 auto parent =
MakeTransactionRef(CreateValidMempoolTransaction(m_coinbase_txns[i + 1],
288 0, 0, coinbaseKey, spk,
CAmount(48 *
COIN),
false));
289 package.emplace_back(parent);
290 child.
vin.emplace_back(
COutPoint(parent->GetHash(), 0));
292 child.
vout.emplace_back(47 *
COIN, spk2);
299 std::shuffle(package.begin(), package.end(), rng);
307 package.erase(package.begin());
311 package.insert(package.begin(), m_coinbase_txns[0]);
318 mtx_parent.
vin.emplace_back(
COutPoint(m_coinbase_txns[0]->GetHash(), 0));
319 mtx_parent.
vout.emplace_back(20 *
COIN, spk);
320 mtx_parent.
vout.emplace_back(20 *
COIN, spk2);
324 mtx_parent_also_child.
vin.emplace_back(
COutPoint(tx_parent->GetHash(), 0));
325 mtx_parent_also_child.
vout.emplace_back(20 *
COIN, spk);
329 mtx_child.
vin.emplace_back(
COutPoint(tx_parent->GetHash(), 1));
330 mtx_child.
vin.emplace_back(
COutPoint(tx_parent_also_child->GetHash(), 0));
331 mtx_child.
vout.emplace_back(39 *
COIN, spk);
357 for (
size_t i{0}; i < 10; ++i) {
358 auto mtx = CreateValidMempoolTransaction(m_coinbase_txns[i + 25], 0,
360 parent_locking_script,
365 package_unrelated,
false, {});
367 BOOST_CHECK(result_unrelated_submit.m_state.IsInvalid());
369 BOOST_CHECK_EQUAL(result_unrelated_submit.m_state.GetRejectReason(),
"package-not-child-with-parents");
375 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
377 parent_locking_script,
380 package_parent_child.push_back(tx_parent);
381 package_3gen.push_back(tx_parent);
385 auto mtx_child = CreateValidMempoolTransaction(tx_parent, 0,
387 child_locking_script,
390 package_parent_child.push_back(tx_child);
391 package_3gen.push_back(tx_child);
395 auto mtx_grandchild = CreateValidMempoolTransaction(tx_child, 0,
397 grandchild_locking_script,
400 package_3gen.push_back(tx_grandchild);
405 package_3gen,
false, {});
406 BOOST_CHECK(result_3gen_submit.m_state.IsInvalid());
408 BOOST_CHECK_EQUAL(result_3gen_submit.m_state.GetRejectReason(),
"package-not-child-with-parents");
416 bad_witness.
stack.emplace_back(1);
418 mtx_parent_invalid.
vin[0].scriptWitness = bad_witness;
420 Package package_invalid_parent{tx_parent_invalid, tx_child};
422 package_invalid_parent,
false, {});
424 BOOST_ERROR(err_parent_invalid.value());
426 auto it_parent = result_quit_early.
m_tx_results.find(tx_parent_invalid->GetWitnessHash());
427 auto it_child = result_quit_early.m_tx_results.find(tx_child->GetWitnessHash());
429 BOOST_CHECK_EQUAL(it_parent->second.m_state.GetRejectReason(),
"bad-witness-nonstandard");
431 BOOST_CHECK_EQUAL(it_child->second.m_state.GetRejectReason(),
"bad-txns-inputs-missingorspent");
437 mtx_child.vin.emplace_back(
COutPoint(package_unrelated[0]->GetHash(), 0));
438 Package package_missing_parent;
439 package_missing_parent.push_back(tx_parent);
443 package_missing_parent,
false, {});
444 BOOST_CHECK(result_missing_parent.m_state.IsInvalid());
446 BOOST_CHECK_EQUAL(result_missing_parent.m_state.GetRejectReason(),
"package-not-child-with-unconfirmed-parents");
453 package_parent_child,
false, {});
454 expected_pool_size += 2;
455 BOOST_CHECK_MESSAGE(submit_parent_child.m_state.IsValid(),
456 "Package validation unexpectedly failed: " << submit_parent_child.m_state.GetRejectReason());
457 BOOST_CHECK_EQUAL(submit_parent_child.m_tx_results.size(), package_parent_child.size());
458 auto it_parent = submit_parent_child.m_tx_results.find(tx_parent->GetWitnessHash());
459 auto it_child = submit_parent_child.m_tx_results.find(tx_child->GetWitnessHash());
460 BOOST_CHECK(it_parent != submit_parent_child.m_tx_results.end());
463 BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().size(), 1);
464 BOOST_CHECK_EQUAL(it_parent->second.m_wtxids_fee_calculations.value().front(), tx_parent->GetWitnessHash());
467 BOOST_CHECK_EQUAL(it_child->second.m_wtxids_fee_calculations.value().front(), tx_child->GetWitnessHash());
475 package_parent_child,
false, {});
477 BOOST_ERROR(err_deduped.value());
479 auto it_parent_deduped = submit_deduped.
m_tx_results.find(tx_parent->GetWitnessHash());
480 auto it_child_deduped = submit_deduped.m_tx_results.find(tx_child->GetWitnessHash());
502 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
510 witness1.
stack.emplace_back(1);
511 witness1.
stack.emplace_back(witnessScript.
begin(), witnessScript.
end());
514 witness2.
stack.emplace_back(2);
515 witness2.
stack.emplace_back(witnessScript.
begin(), witnessScript.
end());
521 mtx_child1.
vin.resize(1);
522 mtx_child1.
vin[0].prevout.hash = ptx_parent->GetHash();
523 mtx_child1.
vin[0].prevout.n = 0;
525 mtx_child1.
vin[0].scriptWitness = witness1;
526 mtx_child1.
vout.resize(1);
528 mtx_child1.
vout[0].scriptPubKey = child_locking_script;
531 mtx_child2.
vin[0].scriptWitness = witness2;
539 BOOST_CHECK(ptx_child1->GetWitnessHash() != ptx_child2->GetWitnessHash());
546 Package package_parent_child1{ptx_parent, ptx_child1};
548 package_parent_child1,
false, {});
550 BOOST_ERROR(err_witness1.value());
554 Package package_parent_child2{ptx_parent, ptx_child2};
556 package_parent_child2,
false, {});
558 BOOST_ERROR(err_witness2.value());
560 auto it_parent2_deduped = submit_witness2.
m_tx_results.find(ptx_parent->GetWitnessHash());
561 auto it_child2 = submit_witness2.m_tx_results.find(ptx_child2->GetWitnessHash());
564 BOOST_CHECK_EQUAL(ptx_child1->GetWitnessHash(), it_child2->second.m_other_wtxid.value());
570 package_parent_child1,
false, {});
572 BOOST_ERROR(err_segwit_dedup.value());
574 auto it_parent_dup = submit_segwit_dedup.
m_tx_results.find(ptx_parent->GetWitnessHash());
575 auto it_child_dup = submit_segwit_dedup.m_tx_results.find(ptx_child1->GetWitnessHash());
590 auto mtx_grandchild = CreateValidMempoolTransaction(ptx_child2, 0,
592 grandchild_locking_script,
599 Package package_child2_grandchild{ptx_child2, ptx_grandchild};
601 package_child2_grandchild,
false, {});
603 BOOST_ERROR(err_spend_ignored.value());
605 auto it_child2_ignored = submit_spend_ignored.
m_tx_results.find(ptx_child2->GetWitnessHash());
606 auto it_grandchild = submit_spend_ignored.m_tx_results.find(ptx_grandchild->GetWitnessHash());
620 acs_witness.
stack.emplace_back(acs_script.
begin(), acs_script.
end());
623 auto mtx_parent1 = CreateValidMempoolTransaction(m_coinbase_txns[1], 0,
628 package_mixed.push_back(ptx_parent1);
634 parent2_witness1.
stack.emplace_back(1);
635 parent2_witness1.
stack.emplace_back(grandparent2_script.
begin(), grandparent2_script.
end());
637 parent2_witness2.
stack.emplace_back(2);
638 parent2_witness2.
stack.emplace_back(grandparent2_script.
begin(), grandparent2_script.
end());
641 auto mtx_grandparent2 = CreateValidMempoolTransaction(m_coinbase_txns[2], 0,
649 mtx_parent2_v1.
vin.resize(1);
650 mtx_parent2_v1.
vin[0].prevout.hash = ptx_grandparent2->GetHash();
651 mtx_parent2_v1.
vin[0].prevout.n = 0;
653 mtx_parent2_v1.
vin[0].scriptWitness = parent2_witness1;
654 mtx_parent2_v1.
vout.resize(1);
656 mtx_parent2_v1.
vout[0].scriptPubKey = acs_spk;
659 mtx_parent2_v2.
vin[0].scriptWitness = parent2_witness2;
666 package_mixed.push_back(ptx_parent2_v1);
669 auto mtx_parent3 = CreateValidMempoolTransaction(m_coinbase_txns[3], 0,
674 package_mixed.push_back(ptx_parent3);
683 mtx_mixed_child.
vin.emplace_back(
COutPoint(ptx_parent1->GetHash(), 0));
684 mtx_mixed_child.
vin.emplace_back(
COutPoint(ptx_parent2_v1->GetHash(), 0));
685 mtx_mixed_child.
vin.emplace_back(
COutPoint(ptx_parent3->GetHash(), 0));
686 mtx_mixed_child.
vin[0].scriptWitness = acs_witness;
687 mtx_mixed_child.
vin[1].scriptWitness = acs_witness;
688 mtx_mixed_child.
vin[2].scriptWitness = acs_witness;
689 mtx_mixed_child.
vout.emplace_back((48 + 49 + 50 - 1) *
COIN, mixed_child_spk);
691 package_mixed.push_back(ptx_mixed_child);
701 BOOST_ERROR(err_mixed.value());
703 auto it_parent1 = mixed_result.
m_tx_results.find(ptx_parent1->GetWitnessHash());
704 auto it_parent2 = mixed_result.m_tx_results.find(ptx_parent2_v1->GetWitnessHash());
705 auto it_parent3 = mixed_result.m_tx_results.find(ptx_parent3->GetWitnessHash());
706 auto it_child = mixed_result.m_tx_results.find(ptx_mixed_child->GetWitnessHash());
712 BOOST_CHECK_EQUAL(ptx_parent2_v2->GetWitnessHash(), it_parent2->second.m_other_wtxid.value());
716 BOOST_CHECK(it_parent3->second.m_effective_feerate.value() == expected_feerate);
717 BOOST_CHECK(it_child->second.m_effective_feerate.value() == expected_feerate);
718 std::vector<Wtxid> expected_wtxids({ptx_parent3->GetWitnessHash(), ptx_mixed_child->GetWitnessHash()});
719 BOOST_CHECK(it_parent3->second.m_wtxids_fee_calculations.value() == expected_wtxids);
720 BOOST_CHECK(it_child->second.m_wtxids_fee_calculations.value() == expected_wtxids);
742 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
745 parent_value,
false);
747 package_cpfp.push_back(tx_parent);
749 auto mtx_child = CreateValidMempoolTransaction(tx_parent, 0,
754 package_cpfp.push_back(tx_child);
759 m_node.
mempool->PrioritiseTransaction(tx_parent->GetHash(), child_value - coinbase_value);
763 package_cpfp,
false, {});
765 BOOST_ERROR(err_cpfp_deprio.value());
768 BOOST_CHECK_EQUAL(submit_cpfp_deprio.m_tx_results.find(tx_parent->GetWitnessHash())->second.m_state.GetResult(),
770 BOOST_CHECK_EQUAL(submit_cpfp_deprio.m_tx_results.find(tx_child->GetWitnessHash())->second.m_state.GetResult(),
772 BOOST_CHECK(submit_cpfp_deprio.m_tx_results.find(tx_parent->GetWitnessHash())->second.m_state.GetRejectReason() ==
"min relay fee not met");
785 package_cpfp,
false, {});
787 BOOST_ERROR(err_cpfp.value());
789 auto it_parent = submit_cpfp.
m_tx_results.find(tx_parent->GetWitnessHash());
790 auto it_child = submit_cpfp.m_tx_results.find(tx_child->GetWitnessHash());
792 BOOST_CHECK(it_parent->second.m_base_fees.value() == coinbase_value - parent_value);
796 const CFeeRate expected_feerate(coinbase_value - child_value,
798 BOOST_CHECK(it_parent->second.m_effective_feerate.value() == expected_feerate);
799 BOOST_CHECK(it_child->second.m_effective_feerate.value() == expected_feerate);
800 std::vector<Wtxid> expected_wtxids({tx_parent->GetWitnessHash(), tx_child->GetWitnessHash()});
801 BOOST_CHECK(it_parent->second.m_wtxids_fee_calculations.value() == expected_wtxids);
802 BOOST_CHECK(it_child->second.m_wtxids_fee_calculations.value() == expected_wtxids);
805 expected_pool_size += 2;
815 auto mtx_parent_cheap = CreateValidMempoolTransaction(m_coinbase_txns[1], 0,
818 coinbase_value - parent_fee,
false);
820 package_still_too_low.push_back(tx_parent_cheap);
824 auto mtx_child_cheap = CreateValidMempoolTransaction(tx_parent_cheap, 0,
827 coinbase_value - parent_fee - child_fee,
false);
829 package_still_too_low.push_back(tx_child_cheap);
837 package_still_too_low,
false, {});
839 BOOST_ERROR(err_package_too_low.value());
842 BOOST_CHECK_EQUAL(submit_package_too_low.m_tx_results.at(tx_parent_cheap->GetWitnessHash()).m_state.GetResult(),
844 BOOST_CHECK(submit_package_too_low.m_tx_results.at(tx_parent_cheap->GetWitnessHash()).m_effective_feerate.value() ==
847 BOOST_CHECK_EQUAL(submit_package_too_low.m_tx_results.at(tx_child_cheap->GetWitnessHash()).m_state.GetResult(),
849 BOOST_CHECK(submit_package_too_low.m_tx_results.at(tx_child_cheap->GetWitnessHash()).m_effective_feerate.value() ==
853 BOOST_CHECK_EQUAL(submit_package_too_low.m_state.GetRejectReason(),
"transaction failed");
863 package_still_too_low,
false, {});
865 BOOST_ERROR(err_prioritised.value());
867 const CFeeRate expected_feerate(1 *
COIN + parent_fee + child_fee,
869 BOOST_CHECK_EQUAL(submit_prioritised_package.m_tx_results.size(), package_still_too_low.size());
870 auto it_parent = submit_prioritised_package.m_tx_results.find(tx_parent_cheap->GetWitnessHash());
871 auto it_child = submit_prioritised_package.m_tx_results.find(tx_child_cheap->GetWitnessHash());
873 BOOST_CHECK(it_parent->second.m_base_fees.value() == parent_fee);
874 BOOST_CHECK(it_parent->second.m_effective_feerate.value() == expected_feerate);
876 BOOST_CHECK(it_child->second.m_base_fees.value() == child_fee);
877 BOOST_CHECK(it_child->second.m_effective_feerate.value() == expected_feerate);
878 std::vector<Wtxid> expected_wtxids({tx_parent_cheap->GetWitnessHash(), tx_child_cheap->GetWitnessHash()});
879 BOOST_CHECK(it_parent->second.m_wtxids_fee_calculations.value() == expected_wtxids);
880 BOOST_CHECK(it_child->second.m_wtxids_fee_calculations.value() == expected_wtxids);
882 expected_pool_size += 2;
893 auto mtx_parent_rich = CreateValidMempoolTransaction(m_coinbase_txns[2], 0,
896 coinbase_value - high_parent_fee,
false);
898 package_rich_parent.push_back(tx_parent_rich);
900 auto mtx_child_poor = CreateValidMempoolTransaction(tx_parent_rich, 0,
903 coinbase_value - high_parent_fee,
false);
905 package_rich_parent.push_back(tx_child_poor);
911 package_rich_parent,
false, {});
913 BOOST_ERROR(err_rich_parent.value());
917 BOOST_CHECK_EQUAL(submit_rich_parent.m_state.GetRejectReason(),
"transaction failed");
919 auto it_parent = submit_rich_parent.m_tx_results.find(tx_parent_rich->GetWitnessHash());
920 auto it_child = submit_rich_parent.m_tx_results.find(tx_child_poor->GetWitnessHash());
923 BOOST_CHECK(it_parent->second.m_state.GetRejectReason() ==
"");
924 BOOST_CHECK_MESSAGE(it_parent->second.m_base_fees.value() == high_parent_fee,
925 strprintf(
"rich parent: expected fee %s, got %s", high_parent_fee, it_parent->second.m_base_fees.value()));
929 BOOST_CHECK(it_child->second.m_state.GetRejectReason() ==
"min relay fee not met");
931 expected_pool_size += 1;
954 auto mtx_parent = CreateValidMempoolTransaction(m_coinbase_txns[0], 0,
959 package1.push_back(tx_parent);
960 package2.push_back(tx_parent);
963 package1.push_back(tx_child_1);
965 package2.push_back(tx_child_2);
970 BOOST_ERROR(err_1.value());
974 auto it_parent_1 = submit1.
m_tx_results.find(tx_parent->GetWitnessHash());
975 auto it_child_1 = submit1.m_tx_results.find(tx_child_1->GetWitnessHash());
978 expected_pool_size += 2;
983 BOOST_ERROR(err_2.value());
987 auto it_parent_2 = submit2.
m_tx_results.find(tx_parent->GetWitnessHash());
988 auto it_child_2 = submit2.m_tx_results.find(tx_child_2->GetWitnessHash());
1000 m_coinbase_txns[1], 0, 0,
1001 coinbaseKey, parent_spk, coinbase_value - 200,
false));
1003 tx_parent_1, 0, 101,
1004 child_key, child_spk, coinbase_value - 400,
false));
1007 m_coinbase_txns[1], 0, 0,
1008 coinbaseKey, parent_spk, coinbase_value - 800,
false));
1010 tx_parent_2, 0, 101,
1011 child_key, child_spk, coinbase_value - 800 - 200,
false));
1014 m_coinbase_txns[1], 0, 0,
1015 coinbaseKey, parent_spk, coinbase_value - 199,
false));
1017 tx_parent_3, 0, 101,
1018 child_key, child_spk, coinbase_value - 199 - 1300,
false));
1021 BOOST_CHECK(tx_parent_1->GetHash() != tx_parent_2->GetHash() && tx_parent_2->GetHash() != tx_parent_3->GetHash());
1024 Package package1{tx_parent_1, tx_child_1};
1026 Package package2{tx_parent_2, tx_child_2};
1028 Package package3{tx_parent_3, tx_child_3};
1032 BOOST_ERROR(err_1.value());
1034 auto it_parent_1 = submit1.
m_tx_results.find(tx_parent_1->GetWitnessHash());
1035 auto it_child_1 = submit1.m_tx_results.find(tx_child_1->GetWitnessHash());
1038 expected_pool_size += 2;
1045 BOOST_ERROR(err_2.value());
1047 auto it_parent_2 = submit2.
m_tx_results.find(tx_parent_2->GetWitnessHash());
1048 auto it_child_2 = submit2.m_tx_results.find(tx_child_2->GetWitnessHash());
1056 BOOST_ERROR(err_3.value());
1058 auto it_parent_3 = submit3.
m_tx_results.find(tx_parent_3->GetWitnessHash());
1059 auto it_child_3 = submit3.m_tx_results.find(tx_child_3->GetWitnessHash());
1064 BOOST_CHECK(it_parent_3->second.m_replaced_transactions.size() == 2);
1065 BOOST_CHECK(it_child_3->second.m_replaced_transactions.empty());
1067 std::vector<Wtxid> expected_package3_wtxids({tx_parent_3->GetWitnessHash(), tx_child_3->GetWitnessHash()});
1069 BOOST_CHECK(it_parent_3->second.m_wtxids_fee_calculations.value() == expected_package3_wtxids);
1070 BOOST_CHECK(it_child_3->second.m_wtxids_fee_calculations.value() == expected_package3_wtxids);
1071 BOOST_CHECK_EQUAL(it_parent_3->second.m_effective_feerate.value().GetFee(package3_total_vsize), 199 + 1300);
1072 BOOST_CHECK_EQUAL(it_child_3->second.m_effective_feerate.value().GetFee(package3_total_vsize), 199 + 1300);
std::shared_ptr< const CTransaction > CTransactionRef
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
uint256 GetPackageHash(const std::vector< CTransactionRef > &transactions)
Get the hash of these transactions' wtxids, concatenated in lexicographical order (treating the wtxid...
The package itself is invalid (e.g. too many transactions).
Valid, transaction was already in the mempool.
bool IsChildWithParents(const Package &package)
Context-free check that a package is exactly one child and its parents; not all parents need to be pr...
bool IsTopoSortedPackage(const Package &txns, std::unordered_set< uint256, SaltedTxidHasher > &later_txids)
IsTopoSortedPackage where a set of txids has been pre-populated.
CPubKey GetPubKey() const
Compute the public key from a private key.
static const CScript P2WSH_OP_TRUE
std::vector< CTransactionRef > Package
A package is an ordered list of transactions.
transaction was missing some of its inputs
constexpr deserialize_type deserialize
std::vector< std::vector< unsigned char > > stack
bool IsChildWithParentsTree(const Package &package)
Context-free check that a package IsChildWithParents() and none of the parents depend on each other (...
std::map< uint256, MempoolAcceptResult > m_tx_results
Map from wtxid to finished MempoolAcceptResults.
violated mempool's fee/size/descendant/RBF/etc limits
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)
Compute the virtual transaction size (weight reinterpreted as bytes).
const ResultType m_result_type
Result type.
static int32_t GetTransactionWeight(const CTransaction &tx)
std::unique_ptr< CTxMemPool > mempool
static constexpr unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT_KVB
Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors.
CKey GenerateRandomKey(bool compressed) noexcept
int64_t CAmount
Amount in satoshis (Can be negative)
Transaction might have a witness prior to SegWit activation, or witness may have been malleated (whic...
Double ended buffer combining vector and stream-like interfaces.
A writer stream (for serialization) that computes a 256-bit hash.
BOOST_AUTO_TEST_SUITE_END()
std::optional< std::string > CheckPackageMempoolAcceptResult(const Package &txns, const PackageMempoolAcceptResult &result, bool expect_valid, const CTxMemPool *mempool)
Check expected properties for every PackageMempoolAcceptResult, regardless of value.
At least one tx is invalid.
Testing fixture that pre-creates a 100-block REGTEST-mode block chain.
An outpoint - a combination of a transaction hash and an index n into its vout.
static uint256 InsecureRand256()
std::vector< CTxOut > vout
fails some policy, but might be acceptable if submitted in a (different) package
Validation result for a transaction evaluated by MemPoolAccept (single or package).
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::vector< unsigned char > ToByteVector(const T &in)
bool IsWellFormedPackage(const Package &txns, PackageValidationState &state, bool require_sorted)
Context-free package policy checks:
static const CAmount low_fee_amt
#define BOOST_CHECK_EQUAL(v1, v2)
Serialized script, used inside transaction inputs and outputs.
static transaction_identifier FromUint256(const uint256 &id)
BOOST_FIXTURE_TEST_CASE(package_hash_tests, TestChain100Setup)
PackageMempoolAcceptResult ProcessNewPackage(Chainstate &active_chainstate, CTxMemPool &pool, const Package &package, bool test_accept, const std::optional< CFeeRate > &client_maxfeerate)
Validate (and maybe submit) a package to the mempool.
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
BOOST_AUTO_TEST_SUITE(cuckoocache_tests)
Test Suite for CuckooCache.
A mutable version of CTransaction.
static constexpr CAmount CENT
static constexpr uint32_t MAX_PACKAGE_COUNT
Default maximum number of transactions in a package.
An encapsulated private key.
The basic transaction that is broadcasted on the network and contained in blocks. ...
std::string GetRejectReason() const
CTransactionRef create_placeholder_tx(size_t num_inputs, size_t num_outputs)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
bool IsConsistentPackage(const Package &txns)
Checks that these transactions don't conflict, i.e., spend the same prevout.
static std::optional< transaction_identifier > FromHex(std::string_view hex)
std::unique_ptr< ChainstateManager > chainman
static GenTxid Txid(const uint256 &hash)
const Wtxid & GetWitnessHash() const LIFETIMEBOUND
const Txid & GetHash() const LIFETIMEBOUND
static constexpr TransactionSerParams TX_WITH_WITNESS
#define BOOST_CHECK(expr)
static constexpr uint32_t MAX_PACKAGE_WEIGHT
Default maximum total weight of transactions in a package in weight to allow for context-less checks...
transaction_identifier represents the two canonical transaction identifier types (txid, wtxid).
static constexpr CAmount COIN
The amount of satoshis in one BTC.