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

Code before:
        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));

    // Outpoints map should track all entries: check that both are returned as children of the parent.
    std::set<CTransactionRef> expected_children{child_normal, child_mutated};
    BOOST_CHECK(EqualTxns(expected_children, orphanage.GetChildrenFromSamePeer(parent, peer)));

    // Erase by wtxid: mutated first
    BOOST_CHECK_EQUAL(orphanage.EraseTx(mutated_wtxid), 1);
    BOOST_CHECK(orphanage.HaveTx(normal_wtxid));
    BOOST_CHECK(!orphanage.HaveTx(mutated_wtxid));


Review comment (suggestion):
Would be nice if the constants were moved to txorphanage.h so we don't need the magic number here. Could be useful in other tests as well.

Code after:
    size_t expected_num_orphans = orphanage.CountOrphans();

    // Non-existent peer; nothing should be deleted
    orphanage.EraseForPeer(/*peer=*/-1);
    BOOST_CHECK_EQUAL(orphanage.CountOrphans(), expected_num_orphans);

    // Each of first three peers stored
    // two transactions each.
    for (NodeId i = 0; i < 3; i++)
    {
        orphanage.EraseForPeer(i);
        expected_num_orphans -= 2;
        BOOST_CHECK(orphanage.CountOrphans() == expected_num_orphans);
    }

    // Test LimitOrphanTxSize() function, nothing should timeout:
    FastRandomContext rng{/*fDeterministic=*/true};
    orphanage.LimitOrphans(/*max_orphans=*/expected_num_orphans, rng);
    BOOST_CHECK_EQUAL(orphanage.CountOrphans(), expected_num_orphans);
    expected_num_orphans -= 1;
    orphanage.LimitOrphans(/*max_orphans=*/expected_num_orphans, rng);
    BOOST_CHECK_EQUAL(orphanage.CountOrphans(), expected_num_orphans);
    assert(expected_num_orphans > 40);
    orphanage.LimitOrphans(40, rng);
    BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 40);
    orphanage.LimitOrphans(10, rng);
    BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 10);
    orphanage.LimitOrphans(0, rng);
    BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 0);

    // Add one more orphan, check timeout logic
    auto timeout_tx = MakeTransactionSpending(/*outpoints=*/{}, rng);
    orphanage.AddTx(timeout_tx, 0);
    orphanage.LimitOrphans(1, rng);
    BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 1);

    // One second shy of expiration
    SetMockTime(now + ORPHAN_TX_EXPIRE_TIME - 1s);
    orphanage.LimitOrphans(1, rng);
    BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 1);

    // Jump one more second, orphan should be timed out on limiting
    SetMockTime(now + ORPHAN_TX_EXPIRE_TIME);
    BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 1);
    orphanage.LimitOrphans(1, rng);
    BOOST_CHECK_EQUAL(orphanage.CountOrphans(), 0);
}

BOOST_AUTO_TEST_CASE(same_txid_diff_witness)
{
    FastRandomContext det_rand{true};