Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251{252PrivateBroadcast pb{PrivateBroadcast::MAX_TRANSACTIONS, /*max_send_attempts=*/1};253const auto tx{MakeDummyTx(/*id=*/1, /*num_witness=*/0)};254const auto equivalent_tx{MakeDummyTx(/*id=*/1, /*num_witness=*/0)};255BOOST_REQUIRE(tx != equivalent_tx);256BOOST_REQUIRE(tx->GetWitnessHash() == equivalent_tx->GetWitnessHash());258in_addr ipv4_addr;259ipv4_addr.s_addr = 0xa0b0c001;260const CService address{ipv4_addr, 1111};261BOOST_REQUIRE_EQUAL(pb.Add(tx), PrivateBroadcast::AddResult::Added);262BOOST_REQUIRE_EQUAL(pb.PickTxForSend(/*will_send_to_nodeid=*/0, address).value(), tx);263pb.NodeConfirmedReception(/*nodeid=*/0);264const auto confirmed_info{pb.GetBroadcastInfo()};265BOOST_REQUIRE_EQUAL(confirmed_info.size(), 1);266BOOST_REQUIRE_EQUAL(confirmed_info[0].peers.size(), 1);267BOOST_CHECK(confirmed_info[0].peers[0].received.has_value());268BOOST_CHECK(!pb.HavePendingTransactions());270// A distinct CTransactionRef with the same WTXID must reset the exhausted271// transaction, including its send and confirmation history.272BOOST_REQUIRE_EQUAL(pb.Add(equivalent_tx), PrivateBroadcast::AddResult::Added);273BOOST_CHECK(pb.HavePendingTransactions());274BOOST_CHECK(!pb.GetTxForNode(/*nodeid=*/0).has_value());275const auto info{pb.GetBroadcastInfo()};276BOOST_REQUIRE_EQUAL(info.size(), 1);277BOOST_CHECK(info[0].tx->GetWitnessHash() == tx->GetWitnessHash());278BOOST_CHECK(info[0].peers.empty());279BOOST_CHECK_EQUAL(pb.Remove(equivalent_tx).value(), 1);280}282BOOST_AUTO_TEST_CASE(rejection_at_cap)283{284PrivateBroadcast pb;285constexpr size_t num_cap{PrivateBroadcast::MAX_TRANSACTIONS};286constexpr size_t num_over{5};288// Fill the queue exactly to the cap; every distinct Add() succeeds.289std::vector<CTransactionRef> txs;290txs.reserve(num_cap);291for (size_t i{0}; i < num_cap; ++i) {292auto tx{MakeDummyTx(/*id=*/static_cast<uint32_t>(i), /*num_witness=*/0)};293BOOST_REQUIRE_EQUAL(pb.Add(tx), PrivateBroadcast::AddResult::Added);294txs.push_back(std::move(tx));295}296BOOST_CHECK_EQUAL(pb.GetBroadcastInfo().size(), num_cap);298// Further distinct transactions are rejected, and the queue is unchanged.299for (size_t i{0}; i < num_over; ++i) {300const auto tx{MakeDummyTx(/*id=*/static_cast<uint32_t>(num_cap + i), /*num_witness=*/0)};301BOOST_CHECK_EQUAL(pb.Add(tx), PrivateBroadcast::AddResult::QueueFull);302}303BOOST_CHECK_EQUAL(pb.GetBroadcastInfo().size(), num_cap);305// Nothing was evicted: all originally-added transactions are still present.306const auto infos{pb.GetBroadcastInfo()};307std::set<uint256> present_wtxids;308for (const auto& info : infos) {309present_wtxids.insert(info.tx->GetWitnessHash().ToUint256());310}311BOOST_CHECK_EQUAL(present_wtxids.size(), infos.size());312for (size_t i{0}; i < num_cap; ++i) {313BOOST_CHECK_MESSAGE(present_wtxids.contains(txs[i]->GetWitnessHash().ToUint256()),314"tx index " << i << " should still be present");315}317// Re-adding an already-present tx is AlreadyPresent even at the cap (not QueueFull).318BOOST_CHECK_EQUAL(pb.Add(txs[0]), PrivateBroadcast::AddResult::AlreadyPresent);319BOOST_CHECK_EQUAL(pb.GetBroadcastInfo().size(), num_cap);321// Removing one frees exactly one slot for a new transaction.322BOOST_REQUIRE(pb.Remove(txs[0]).has_value());323BOOST_CHECK_EQUAL(pb.GetBroadcastInfo().size(), num_cap - 1);324const auto fresh{MakeDummyTx(/*id=*/0xffffffff, /*num_witness=*/0)};325BOOST_CHECK_EQUAL(pb.Add(fresh), PrivateBroadcast::AddResult::Added);326BOOST_CHECK_EQUAL(pb.GetBroadcastInfo().size(), num_cap);328// A previously-removed tx can be added again as a brand-new entry.329BOOST_REQUIRE(pb.Remove(fresh).has_value());330BOOST_CHECK_EQUAL(pb.Add(fresh), PrivateBroadcast::AddResult::Added);331BOOST_CHECK_EQUAL(pb.GetBroadcastInfo().size(), num_cap);332}334BOOST_AUTO_TEST_SUITE_END()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.