LCOV - code coverage report
Current view: top level - src/test - private_broadcast_tests.cpp (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 100.0 % 82 82
Test Date: 2026-02-25 05:45:00 Functions: 100.0 % 5 5
Branches: 50.5 % 404 204

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2025-present The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :             : 
       5                 :             : #include <primitives/transaction.h>
       6                 :             : #include <private_broadcast.h>
       7                 :             : #include <test/util/setup_common.h>
       8                 :             : #include <util/time.h>
       9                 :             : 
      10                 :             : #include <algorithm>
      11                 :             : #include <boost/test/unit_test.hpp>
      12                 :             : 
      13                 :             : BOOST_FIXTURE_TEST_SUITE(private_broadcast_tests, BasicTestingSetup)
      14                 :             : 
      15                 :           2 : static CTransactionRef MakeDummyTx(uint32_t id, size_t num_witness)
      16                 :             : {
      17                 :           2 :     CMutableTransaction mtx;
      18         [ +  - ]:           2 :     mtx.vin.resize(1);
      19         [ +  + ]:           2 :     mtx.vin[0].nSequence = id;
      20         [ +  + ]:           2 :     if (num_witness > 0) {
      21                 :           1 :         mtx.vin[0].scriptWitness = CScriptWitness{};
      22         [ +  - ]:           1 :         mtx.vin[0].scriptWitness.stack.resize(num_witness);
      23                 :             :     }
      24         [ +  - ]:           4 :     return MakeTransactionRef(mtx);
      25                 :           2 : }
      26                 :             : 
      27   [ +  -  +  -  :           7 : BOOST_AUTO_TEST_CASE(basic)
          +  -  +  -  -  
          +  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  +  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  -  +  +  
                      - ]
      28                 :             : {
      29                 :           1 :     SetMockTime(Now<NodeSeconds>());
      30                 :             : 
      31         [ +  - ]:           1 :     PrivateBroadcast pb;
      32                 :           1 :     const NodeId recipient1{1};
      33                 :           1 :     in_addr ipv4Addr;
      34                 :           1 :     ipv4Addr.s_addr = 0xa0b0c001;
      35         [ +  - ]:           1 :     const CService addr1{ipv4Addr, 1111};
      36                 :             : 
      37                 :             :     // No transactions initially.
      38   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.PickTxForSend(/*will_send_to_nodeid=*/recipient1, /*will_send_to_address=*/addr1).has_value());
             +  -  +  - ]
      39   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(pb.GetStale().size(), 0);
                   +  - ]
      40   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.HavePendingTransactions());
             +  -  +  - ]
      41   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(pb.GetBroadcastInfo().size(), 0);
                   +  - ]
      42                 :             : 
      43                 :             :     // Make a transaction and add it.
      44         [ +  - ]:           1 :     const auto tx1{MakeDummyTx(/*id=*/1, /*num_witness=*/0)};
      45                 :             : 
      46   [ +  -  +  -  :           2 :     BOOST_CHECK(pb.Add(tx1));
             +  -  +  - ]
      47   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.Add(tx1));
             +  -  +  - ]
      48                 :             : 
      49                 :             :     // Make another transaction with same txid, different wtxid and add it.
      50         [ +  - ]:           1 :     const auto tx2{MakeDummyTx(/*id=*/1, /*num_witness=*/1)};
      51   [ +  -  +  -  :           2 :     BOOST_REQUIRE(tx1->GetHash() == tx2->GetHash());
                   +  - ]
      52   [ +  -  +  -  :           2 :     BOOST_REQUIRE(tx1->GetWitnessHash() != tx2->GetWitnessHash());
                   +  - ]
      53                 :             : 
      54   [ +  -  +  -  :           2 :     BOOST_CHECK(pb.Add(tx2));
             +  -  +  - ]
      55                 :           7 :     const auto find_tx_info{[](auto& infos, const CTransactionRef& tx) -> const PrivateBroadcast::TxBroadcastInfo& {
      56         [ +  + ]:          15 :         const auto it{std::ranges::find(infos, tx->GetWitnessHash(), [](const auto& info) { return info.tx->GetWitnessHash(); })};
      57         [ +  - ]:          12 :         BOOST_REQUIRE(it != infos.end());
      58                 :           6 :         return *it;
      59                 :             :     }};
      60                 :           3 :     const auto check_peer_counts{[&](size_t tx1_peer_count, size_t tx2_peer_count) {
      61                 :           2 :         const auto infos{pb.GetBroadcastInfo()};
      62   [ +  -  -  +  :           2 :         BOOST_CHECK_EQUAL(infos.size(), 2);
                   +  - ]
      63   [ +  -  +  -  :           2 :         BOOST_CHECK_EQUAL(find_tx_info(infos, tx1).peers.size(), tx1_peer_count);
             -  +  +  - ]
      64   [ +  -  +  -  :           2 :         BOOST_CHECK_EQUAL(find_tx_info(infos, tx2).peers.size(), tx2_peer_count);
             -  +  +  - ]
      65                 :           3 :     }};
      66                 :             : 
      67         [ +  - ]:           1 :     check_peer_counts(/*tx1_peer_count=*/0, /*tx2_peer_count=*/0);
      68                 :             : 
      69         [ +  - ]:           2 :     const auto tx_for_recipient1{pb.PickTxForSend(/*will_send_to_nodeid=*/recipient1, /*will_send_to_address=*/addr1).value()};
      70   [ +  -  +  -  :           3 :     BOOST_CHECK(tx_for_recipient1 == tx1 || tx_for_recipient1 == tx2);
          +  -  +  -  +  
                      - ]
      71                 :             : 
      72                 :             :     // A second pick must return the other transaction.
      73                 :           1 :     const NodeId recipient2{2};
      74         [ +  - ]:           1 :     const CService addr2{ipv4Addr, 2222};
      75         [ +  - ]:           2 :     const auto tx_for_recipient2{pb.PickTxForSend(/*will_send_to_nodeid=*/recipient2, /*will_send_to_address=*/addr2).value()};
      76   [ +  -  -  +  :           2 :     BOOST_CHECK(tx_for_recipient2 == tx1 || tx_for_recipient2 == tx2);
          -  -  +  -  +  
                      - ]
      77   [ +  -  +  - ]:           1 :     BOOST_CHECK_NE(tx_for_recipient1, tx_for_recipient2);
      78                 :             : 
      79         [ +  - ]:           1 :     check_peer_counts(/*tx1_peer_count=*/1, /*tx2_peer_count=*/1);
      80                 :             : 
      81                 :           1 :     const NodeId nonexistent_recipient{0};
      82                 :             : 
      83                 :             :     // Confirm transactions <-> recipients mapping is correct.
      84   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.GetTxForNode(nonexistent_recipient).has_value());
             +  -  +  - ]
      85   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(pb.GetTxForNode(recipient1).value(), tx_for_recipient1);
                   +  - ]
      86   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(pb.GetTxForNode(recipient2).value(), tx_for_recipient2);
                   +  - ]
      87                 :             : 
      88                 :             :     // Confirm none of the transactions' reception have been confirmed.
      89   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.DidNodeConfirmReception(recipient1));
             +  -  +  - ]
      90   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.DidNodeConfirmReception(recipient2));
             +  -  +  - ]
      91   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.DidNodeConfirmReception(nonexistent_recipient));
             +  -  +  - ]
      92                 :             : 
      93   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(pb.GetStale().size(), 2);
                   +  - ]
      94                 :             : 
      95                 :             :     // Confirm reception by recipient1.
      96         [ +  - ]:           1 :     pb.NodeConfirmedReception(nonexistent_recipient); // Dummy call.
      97         [ +  - ]:           1 :     pb.NodeConfirmedReception(recipient1);
      98                 :             : 
      99   [ +  -  +  -  :           2 :     BOOST_CHECK(pb.DidNodeConfirmReception(recipient1));
             +  -  +  - ]
     100   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.DidNodeConfirmReception(recipient2));
             +  -  +  - ]
     101                 :             : 
     102         [ +  - ]:           1 :     const auto infos{pb.GetBroadcastInfo()};
     103   [ +  -  -  +  :           1 :     BOOST_CHECK_EQUAL(infos.size(), 2);
                   +  - ]
     104                 :           1 :     {
     105         [ +  - ]:           1 :         const auto& [tx, peers]{find_tx_info(infos, tx_for_recipient1)};
     106   [ +  -  -  +  :           1 :         BOOST_CHECK_EQUAL(peers.size(), 1);
                   +  - ]
     107   [ +  -  +  -  :           1 :         BOOST_CHECK_EQUAL(peers[0].address.ToStringAddrPort(), addr1.ToStringAddrPort());
             +  -  +  - ]
     108   [ +  -  +  -  :           2 :         BOOST_CHECK(peers[0].received.has_value());
                   +  - ]
     109                 :             :     }
     110                 :           1 :     {
     111         [ +  - ]:           1 :         const auto& [tx, peers]{find_tx_info(infos, tx_for_recipient2)};
     112   [ +  -  -  +  :           1 :         BOOST_CHECK_EQUAL(peers.size(), 1);
                   +  - ]
     113   [ +  -  +  -  :           1 :         BOOST_CHECK_EQUAL(peers[0].address.ToStringAddrPort(), addr2.ToStringAddrPort());
             +  -  +  - ]
     114   [ +  -  +  -  :           2 :         BOOST_CHECK(!peers[0].received.has_value());
                   +  - ]
     115                 :             :     }
     116                 :             : 
     117   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(pb.GetStale().size(), 1);
                   +  - ]
     118   [ +  -  +  -  :           1 :     BOOST_CHECK_EQUAL(pb.GetStale()[0], tx_for_recipient2);
                   +  - ]
     119                 :             : 
     120         [ +  - ]:           1 :     SetMockTime(Now<NodeSeconds>() + 10h);
     121                 :             : 
     122   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(pb.GetStale().size(), 2);
                   +  - ]
     123                 :             : 
     124   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(pb.Remove(tx_for_recipient1).value(), 1);
                   +  - ]
     125   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.Remove(tx_for_recipient1).has_value());
             +  -  +  - ]
     126   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(pb.Remove(tx_for_recipient2).value(), 0);
                   +  - ]
     127   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.Remove(tx_for_recipient2).has_value());
             +  -  +  - ]
     128                 :             : 
     129   [ +  -  +  -  :           2 :     BOOST_CHECK_EQUAL(pb.GetBroadcastInfo().size(), 0);
                   +  - ]
     130         [ +  - ]:           1 :     const CService addr_nonexistent{ipv4Addr, 3333};
     131   [ +  -  +  -  :           2 :     BOOST_CHECK(!pb.PickTxForSend(/*will_send_to_nodeid=*/nonexistent_recipient, /*will_send_to_address=*/addr_nonexistent).has_value());
                   +  - ]
     132   [ +  -  +  -  :           5 : }
             +  -  +  - ]
     133                 :             : 
     134                 :             : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1