Repository: bitcoin/bitcoin
File: src/test/orphanage_tests.cpp (C++)

Code before:
        BOOST_CHECK(orphanage.CountOrphans() < sizeBefore);
    }

    // Test LimitOrphanTxSize() function:
    FastRandomContext rng{/*fDeterministic=*/true};
    orphanage.LimitOrphans(40, rng);
    BOOST_CHECK(orphanage.CountOrphans() <= 40);
    orphanage.LimitOrphans(10, rng);
    BOOST_CHECK(orphanage.CountOrphans() <= 10);
    orphanage.LimitOrphans(0, rng);
    BOOST_CHECK(orphanage.CountOrphans() == 0);
}

BOOST_AUTO_TEST_CASE(get_children)
{
    FastRandomContext det_rand{true};
    std::vector<COutPoint> empty_outpoints;

    auto parent1 = MakeTransactionSpending(empty_outpoints, det_rand);
    auto parent2 = MakeTransactionSpending(empty_outpoints, det_rand);

    // Make sure these parents have different txids otherwise this test won't make sense.
    while (parent1->GetHash() == parent2->GetHash()) {
        parent2 = MakeTransactionSpending(empty_outpoints, det_rand);
    }

    // Create children to go into orphanage.
    auto child_p1n0 = MakeTransactionSpending({{parent1->GetHash(), 0}}, det_rand);
    auto child_p2n1 = MakeTransactionSpending({{parent2->GetHash(), 1}}, det_rand);
    // Spends the same tx twice. Should not cause duplicates.
    auto child_p1n0_p1n1 = MakeTransactionSpending({{parent1->GetHash(), 0}, {parent1->GetHash(), 1}}, det_rand);
    // Spends the same outpoint as previous tx. Should still be returned; don't assume outpoints are unique.
    auto child_p1n0_p2n0 = MakeTransactionSpending({{parent1->GetHash(), 0}, {parent2->GetHash(), 0}}, det_rand);

    const NodeId node1{1};
    const NodeId node2{2};

    // All orphans provided by node1
    {
        TxOrphanage orphanage;
        BOOST_CHECK(orphanage.AddTx(child_p1n0, node1));
        BOOST_CHECK(orphanage.AddTx(child_p2n1, node1));
        BOOST_CHECK(orphanage.AddTx(child_p1n0_p1n1, node1));
        BOOST_CHECK(orphanage.AddTx(child_p1n0_p2n0, node1));

        std::set<CTransactionRef> expected_parent1_children{child_p1n0, child_p1n0_p2n0, child_p1n0_p1n1};
        std::set<CTransactionRef> expected_parent2_children{child_p2n1, child_p1n0_p2n0};

        BOOST_CHECK(EqualTxns(expected_parent1_children, orphanage.GetChildrenFromSamePeer(parent1, node1)));
        BOOST_CHECK(EqualTxns(expected_parent2_children, orphanage.GetChildrenFromSamePeer(parent2, node1)));


Review comment (suggestion):
tidy nit:
```suggestion
    FastRandomContext det_rand{/*fDeterministic=*/true};
```

Code after:
            tx.vin[j].scriptSig = tx.vin[0].scriptSig;

        BOOST_CHECK(!orphanage.AddTx(MakeTransactionRef(tx), i));
    }

    // Test EraseOrphansFor:
    for (NodeId i = 0; i < 3; i++)
    {
        size_t sizeBefore = orphanage.CountOrphans();
        orphanage.EraseForPeer(i);
        BOOST_CHECK(orphanage.CountOrphans() < sizeBefore);
    }

    // Test LimitOrphanTxSize() function:
    FastRandomContext rng{/*fDeterministic=*/true};
    orphanage.LimitOrphans(40, rng);
    BOOST_CHECK(orphanage.CountOrphans() <= 40);
    orphanage.LimitOrphans(10, rng);
    BOOST_CHECK(orphanage.CountOrphans() <= 10);
    orphanage.LimitOrphans(0, rng);
    BOOST_CHECK(orphanage.CountOrphans() == 0);
}

BOOST_AUTO_TEST_CASE(same_txid_diff_witness)
{
    FastRandomContext det_rand{true};
    TxOrphanage orphanage;
    NodeId peer{0};

    std::vector<COutPoint> empty_outpoints;
    auto parent = MakeTransactionSpending(empty_outpoints, det_rand);

    // Create children to go into orphanage.
    auto child_normal = MakeTransactionSpending({{parent->GetHash(), 0}}, det_rand);
    auto child_mutated = MakeMutation(child_normal);

    const auto& normal_wtxid = child_normal->GetWitnessHash();
    const auto& mutated_wtxid = child_mutated->GetWitnessHash();
    BOOST_CHECK(normal_wtxid != mutated_wtxid);

    BOOST_CHECK(orphanage.AddTx(child_normal, peer));
    // EraseTx fails as transaction by this wtxid doesn't exist.
    BOOST_CHECK_EQUAL(orphanage.EraseTx(mutated_wtxid), 0);
    BOOST_CHECK(orphanage.HaveTx(normal_wtxid));
    BOOST_CHECK(!orphanage.HaveTx(mutated_wtxid));

    // Must succeed. Both transactions should be present in orphanage.
    BOOST_CHECK(orphanage.AddTx(child_mutated, peer));
    BOOST_CHECK(orphanage.HaveTx(normal_wtxid));
    BOOST_CHECK(orphanage.HaveTx(mutated_wtxid));