144 std::vector<COutPoint> all_unspent_outpoints({
154 for (
const auto& outpoint : all_unspent_outpoints)
BOOST_CHECK(!pool.
isSpent(outpoint));
156 std::vector<COutPoint> all_spent_outpoints({
164 std::vector<COutPoint> all_parent_outputs({
176 std::vector<CTransactionRef> all_transactions{tx0, tx1, tx2, tx3, tx4, tx5, tx6, tx7};
177 struct TxDimensions {
180 std::map<uint256, TxDimensions> tx_dims;
181 for (
const auto& tx : all_transactions) {
183 tx_dims.emplace(tx->GetHash(), TxDimensions{entry.GetTxSize(), entry.GetModifiedFee(),
184 CFeeRate(entry.GetModifiedFee(), entry.GetTxSize())});
194 for (
const auto& outpoint : nonexistent_outpoints)
BOOST_CHECK(!pool.
isSpent(outpoint));
195 for (
const auto& feerate : various_normal_feerates) {
201 BOOST_CHECK(bump_fees.size() == nonexistent_outpoints.size());
202 for (
const auto& outpoint: nonexistent_outpoints) {
203 auto it = bump_fees.find(outpoint);
210 for (
const auto& target_feerate : various_normal_feerates) {
219 const TxDimensions& tx0_dimensions = tx_dims.find(tx0->GetHash())->second;
221 if (target_feerate <= tx0_dimensions.feerate) {
225 BOOST_CHECK_EQUAL(bumpfee0, target_feerate.GetFee(tx0_dimensions.vsize) - tx0_dimensions.mod_fee);
229 const TxDimensions& tx2_dimensions = tx_dims.find(tx2->GetHash())->second;
230 const TxDimensions& tx3_dimensions = tx_dims.find(tx3->GetHash())->second;
231 const CFeeRate tx2_feerate =
CFeeRate(tx2_dimensions.mod_fee + tx3_dimensions.mod_fee, tx2_dimensions.vsize + tx3_dimensions.vsize);
233 if (target_feerate <= tx2_feerate) {
238 BOOST_CHECK_EQUAL(bumpfee2, target_feerate.GetFee(tx2_dimensions.vsize) - tx2_dimensions.mod_fee);
249 const TxDimensions& tx4_dimensions = tx_dims.find(tx4->GetHash())->second;
250 const TxDimensions& tx5_dimensions = tx_dims.find(tx5->GetHash())->second;
251 const CFeeRate tx4_feerate =
CFeeRate(tx4_dimensions.mod_fee + tx5_dimensions.mod_fee, tx4_dimensions.vsize + tx5_dimensions.vsize);
253 if (target_feerate <= tx4_feerate) {
258 BOOST_CHECK_EQUAL(bumpfee4, target_feerate.GetFee(tx4_dimensions.vsize) - tx4_dimensions.mod_fee);
264 for (
const auto& target_feerate : various_normal_feerates) {
267 auto bump_fees_all_spent = mini_miner_all_spent.
CalculateBumpFees(target_feerate);
272 auto bump_fees_all_parents = mini_miner_all_parents.
CalculateBumpFees(target_feerate);
275 for (
auto& bump_fees : {bump_fees_all_parents, bump_fees_all_spent}) {
281 const TxDimensions& tx0_dimensions = tx_dims.find(tx0->GetHash())->second;
283 if (target_feerate <= tx0_dimensions.feerate) {
287 BOOST_CHECK_EQUAL(it0_spent, target_feerate.GetFee(tx0_dimensions.vsize) - tx0_dimensions.mod_fee);
291 const TxDimensions& tx2_dimensions = tx_dims.find(tx2->GetHash())->second;
292 const CFeeRate tx2_feerate_unbumped = tx2_dimensions.feerate;
293 auto it2_spent =
Find(bump_fees,
COutPoint{tx2->GetHash(), 0});
294 if (target_feerate <= tx2_feerate_unbumped) {
298 BOOST_CHECK_EQUAL(it2_spent, target_feerate.GetFee(tx2_dimensions.vsize) - tx2_dimensions.mod_fee);
302 const TxDimensions& tx4_dimensions = tx_dims.find(tx4->GetHash())->second;
303 const CFeeRate tx4_feerate_unbumped = tx4_dimensions.feerate;
304 auto it4_spent =
Find(bump_fees,
COutPoint{tx4->GetHash(), 0});
305 if (target_feerate <= tx4_feerate_unbumped) {
309 BOOST_CHECK_EQUAL(it4_spent, target_feerate.GetFee(tx4_dimensions.vsize) - tx4_dimensions.mod_fee);
317 std::vector<node::MiniMinerMempoolEntry> miniminer_info;
319 const int32_t tx0_vsize{tx_dims.at(tx0->GetHash()).vsize};
320 const int32_t tx1_vsize{tx_dims.at(tx1->GetHash()).vsize};
321 const int32_t tx2_vsize{tx_dims.at(tx2->GetHash()).vsize};
322 const int32_t tx3_vsize{tx_dims.at(tx3->GetHash()).vsize};
323 const int32_t tx4_vsize{tx_dims.at(tx4->GetHash()).vsize};
324 const int32_t tx5_vsize{tx_dims.at(tx5->GetHash()).vsize};
325 const int32_t tx6_vsize{tx_dims.at(tx6->GetHash()).vsize};
326 const int32_t tx7_vsize{tx_dims.at(tx7->GetHash()).vsize};
328 miniminer_info.emplace_back(tx0,tx0_vsize,tx0_vsize,
med_fee,
med_fee);
329 miniminer_info.emplace_back(tx1, tx1_vsize, tx0_vsize + tx1_vsize,
med_fee, 2*
med_fee);
330 miniminer_info.emplace_back(tx2, tx2_vsize, tx2_vsize,
low_fee,
low_fee);
332 miniminer_info.emplace_back(tx4, tx4_vsize, tx4_vsize,
low_fee,
low_fee);
333 miniminer_info.emplace_back(tx5, tx5_vsize, tx4_vsize + tx5_vsize, tx5_mod_fee,
low_fee + tx5_mod_fee);
337 std::map<Txid, std::set<Txid>> descendant_caches;
338 descendant_caches.emplace(tx0->GetHash(), std::set<Txid>{tx0->GetHash(), tx1->GetHash()});
339 descendant_caches.emplace(tx1->GetHash(), std::set<Txid>{tx1->GetHash()});
340 descendant_caches.emplace(tx2->GetHash(), std::set<Txid>{tx2->GetHash(), tx3->GetHash()});
341 descendant_caches.emplace(tx3->GetHash(), std::set<Txid>{tx3->GetHash()});
342 descendant_caches.emplace(tx4->GetHash(), std::set<Txid>{tx4->GetHash(), tx5->GetHash()});
343 descendant_caches.emplace(tx5->GetHash(), std::set<Txid>{tx5->GetHash()});
344 descendant_caches.emplace(tx6->GetHash(), std::set<Txid>{tx6->GetHash(), tx7->GetHash()});
345 descendant_caches.emplace(tx7->GetHash(), std::set<Txid>{tx7->GetHash()});
352 for (
const auto& sequences : {miniminer_manual.
Linearize(), miniminer_pool.
Linearize()}) {
426 std::vector<CTransactionRef> all_transactions{tx0, tx1, tx2, tx3, tx4, tx5, tx6, tx7};
427 std::vector<int64_t> tx_vsizes;
428 tx_vsizes.reserve(all_transactions.size());
431 std::vector<COutPoint> all_unspent_outpoints({
443 for (
const auto& outpoint : all_unspent_outpoints)
BOOST_CHECK(!pool.
isSpent(outpoint));
451 BOOST_CHECK(tx3_anc_feerate ==
CFeeRate(tx3_entry.GetModFeesWithAncestors(), tx3_entry.GetSizeWithAncestors()));
455 BOOST_CHECK(tx6_anc_feerate ==
CFeeRate(tx6_entry.GetModFeesWithAncestors(), tx6_entry.GetSizeWithAncestors()));
458 BOOST_CHECK(tx7_anc_feerate ==
CFeeRate(tx7_entry.GetModFeesWithAncestors(), tx7_entry.GetSizeWithAncestors()));
472 const auto tx0_bumpfee = bump_fees.find(
COutPoint{tx0->GetHash(), 1});
475 const auto tx3_bumpfee = bump_fees.find(
COutPoint{tx3->GetHash(), 0});
479 const auto tx6_bumpfee = bump_fees.find(
COutPoint{tx6->GetHash(), 0});
483 const auto tx7_bumpfee = bump_fees.find(
COutPoint{tx7->GetHash(), 0});
489 BOOST_CHECK(mini_miner_total_tx3.IsReadyToCalculate());
490 const auto tx3_bump_fee = mini_miner_total_tx3.CalculateTotalBumpFees(very_high_feerate);
491 BOOST_CHECK(!mini_miner_total_tx3.IsReadyToCalculate());
497 BOOST_CHECK(mini_miner_tx6_tx7.IsReadyToCalculate());
498 const auto tx6_tx7_bumpfee = mini_miner_tx6_tx7.CalculateTotalBumpFees(very_high_feerate);
499 BOOST_CHECK(!mini_miner_tx6_tx7.IsReadyToCalculate());
506 const auto just_below_tx4 =
CFeeRate(tx4_feerate.GetFeePerK() - 5);
513 const auto tx6_bumpfee = bump_fees.find(
COutPoint{tx6->GetHash(), 0});
516 const auto tx7_bumpfee = bump_fees.find(
COutPoint{tx7->GetHash(), 0});
521 BOOST_CHECK(mini_miner_tx6_tx7.IsReadyToCalculate());
522 const auto tx6_tx7_bumpfee = mini_miner_tx6_tx7.CalculateTotalBumpFees(just_below_tx4);
523 BOOST_CHECK(!mini_miner_tx6_tx7.IsReadyToCalculate());
537 const auto tx6_bumpfee = bump_fees.find(
COutPoint{tx6->GetHash(), 0});
540 const auto tx7_bumpfee = bump_fees.find(
COutPoint{tx7->GetHash(), 0});
545 std::vector<node::MiniMinerMempoolEntry> miniminer_info;
546 miniminer_info.emplace_back(tx0,tx_vsizes[0], tx_vsizes[0],
low_fee,
low_fee);
547 miniminer_info.emplace_back(tx1, tx_vsizes[1], tx_vsizes[1],
med_fee,
med_fee);
548 miniminer_info.emplace_back(tx2, tx_vsizes[2], tx_vsizes[2],
high_fee,
high_fee);
550 miniminer_info.emplace_back(tx4, tx_vsizes[4], tx_vsizes[4],
high_fee,
high_fee);
555 std::map<Txid, std::set<Txid>> descendant_caches;
556 descendant_caches.emplace(tx0->GetHash(), std::set<Txid>{tx0->GetHash(), tx3->GetHash()});
557 descendant_caches.emplace(tx1->GetHash(), std::set<Txid>{tx1->GetHash(), tx3->GetHash()});
558 descendant_caches.emplace(tx2->GetHash(), std::set<Txid>{tx2->GetHash(), tx3->GetHash()});
559 descendant_caches.emplace(tx3->GetHash(), std::set<Txid>{tx3->GetHash()});
560 descendant_caches.emplace(tx4->GetHash(), std::set<Txid>{tx4->GetHash(), tx5->GetHash(), tx6->GetHash(), tx7->GetHash()});
561 descendant_caches.emplace(tx5->GetHash(), std::set<Txid>{tx5->GetHash(), tx6->GetHash(), tx7->GetHash()});
562 descendant_caches.emplace(tx6->GetHash(), std::set<Txid>{tx6->GetHash()});
563 descendant_caches.emplace(tx7->GetHash(), std::set<Txid>{tx7->GetHash()});
570 for (
const auto& sequences : {miniminer_manual.
Linearize(), miniminer_pool.
Linearize()}) {
594 auto convert_to_uint256_vec = [](
const std::vector<Txid>& vec) -> std::vector<uint256> {
595 std::vector<uint256> out;
596 std::transform(vec.begin(), vec.end(), std::back_inserter(out),
597 [](
const Txid& txid) { return txid.ToUint256(); });
603 std::vector<Txid> chain_txids;
604 auto& lasttx = m_coinbase_txns[0];
605 for (
auto i{0}; i < 500; ++i) {
608 chain_txids.push_back(tx->GetHash());
611 const auto cluster_500tx = pool.
GatherClusters({lasttx->GetHash()});
614 const auto vec_iters_500 = pool.
GetIterVec(convert_to_uint256_vec(chain_txids));
615 for (
const auto& iter : vec_iters_500)
BOOST_CHECK(cluster_500tx_set.count(iter));
620 const auto cluster_501 = pool.
GatherClusters({tx_501->GetHash()});
629 std::vector<Txid> zigzag_txids;
630 for (
auto p{0}; p < 50; ++p) {
633 zigzag_txids.push_back(txp->GetHash());
635 for (
auto c{0}; c < 49; ++c) {
638 zigzag_txids.push_back(txc->GetHash());
640 const auto vec_iters_zigzag = pool.
GetIterVec(convert_to_uint256_vec(zigzag_txids));
642 const std::vector<size_t> indices{0, 22, 72, zigzag_txids.size() - 1};
643 for (
const auto index : indices) {
648 for (
const auto& iter : vec_iters_zigzag)
BOOST_CHECK(clusterset.count(iter));
659 auto grandparent_zero_fee =
make_tx({{m_coinbase_txns.at(0)->GetHash(), 0}}, 1);
660 auto parent_high_feerate =
make_tx({{grandparent_zero_fee->GetHash(), 0}}, 1);
662 auto grandparent_double_low_feerate =
make_tx({{m_coinbase_txns.at(2)->GetHash(), 0}}, 1);
663 auto parent_med_feerate =
make_tx({{grandparent_double_low_feerate->GetHash(), 0}}, 1);
665 auto grandparent_low_feerate =
make_tx({{m_coinbase_txns.at(1)->GetHash(), 0}}, 1);
666 auto parent_double_low_feerate =
make_tx({{grandparent_low_feerate->GetHash(), 0}}, 1);
668 auto child =
make_tx({{parent_high_feerate->GetHash(), 0}, {parent_double_low_feerate->GetHash(), 0}, {parent_med_feerate->GetHash(), 0}}, 1);
671 const int64_t tx_vsize{100};
672 const int64_t child_vsize{1000};
674 std::vector<node::MiniMinerMempoolEntry> miniminer_info;
675 miniminer_info.emplace_back(grandparent_zero_fee, tx_vsize,tx_vsize, 0,0);
676 miniminer_info.emplace_back(parent_high_feerate, tx_vsize, 2*tx_vsize,
high_fee,
high_fee);
677 miniminer_info.emplace_back(grandparent_double_low_feerate, tx_vsize, tx_vsize, 2*
low_fee, 2*
low_fee);
679 miniminer_info.emplace_back(grandparent_low_feerate, tx_vsize, tx_vsize,
low_fee,
low_fee);
680 miniminer_info.emplace_back(parent_double_low_feerate, tx_vsize, 2*tx_vsize, 2*
low_fee, 3*
low_fee);
682 std::map<Txid, std::set<Txid>> descendant_caches;
683 descendant_caches.emplace(grandparent_zero_fee->GetHash(), std::set<Txid>{grandparent_zero_fee->GetHash(), parent_high_feerate->GetHash(), child->GetHash()});
684 descendant_caches.emplace(grandparent_low_feerate->GetHash(), std::set<Txid>{grandparent_low_feerate->GetHash(), parent_double_low_feerate->GetHash(), child->GetHash()});
685 descendant_caches.emplace(grandparent_double_low_feerate->GetHash(), std::set<Txid>{grandparent_double_low_feerate->GetHash(), parent_med_feerate->GetHash(), child->GetHash()});
686 descendant_caches.emplace(parent_high_feerate->GetHash(), std::set<Txid>{parent_high_feerate->GetHash(), child->GetHash()});
687 descendant_caches.emplace(parent_med_feerate->GetHash(), std::set<Txid>{parent_med_feerate->GetHash(), child->GetHash()});
688 descendant_caches.emplace(parent_double_low_feerate->GetHash(), std::set<Txid>{parent_double_low_feerate->GetHash(), child->GetHash()});
689 descendant_caches.emplace(child->GetHash(), std::set<Txid>{child->GetHash()});
693 const auto sequences{miniminer_manual.
Linearize()};