LCOV - code coverage report
Current view: top level - src - private_broadcast.cpp (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 100.0 % 88 88
Test Date: 2026-04-04 05:08:43 Functions: 100.0 % 11 11
Branches: 69.0 % 84 58

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2023-present The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or https://opensource.org/license/mit/.
       4                 :             : 
       5                 :             : #include <private_broadcast.h>
       6                 :             : #include <util/check.h>
       7                 :             : 
       8                 :             : #include <algorithm>
       9                 :             : 
      10                 :             : 
      11                 :          11 : bool PrivateBroadcast::Add(const CTransactionRef& tx)
      12                 :             :     EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
      13                 :             : {
      14                 :          11 :     LOCK(m_mutex);
      15         [ +  - ]:          11 :     const bool inserted{m_transactions.try_emplace(tx).second};
      16         [ +  - ]:          11 :     return inserted;
      17                 :          11 : }
      18                 :             : 
      19                 :       15171 : std::optional<size_t> PrivateBroadcast::Remove(const CTransactionRef& tx)
      20                 :             :     EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
      21                 :             : {
      22                 :       15171 :     LOCK(m_mutex);
      23                 :       15171 :     const auto handle{m_transactions.extract(tx)};
      24         [ +  + ]:       15171 :     if (handle) {
      25         [ +  - ]:           5 :         const auto p{DerivePriority(handle.mapped().send_statuses)};
      26                 :           5 :         return p.num_confirmed;
      27                 :             :     }
      28                 :       15166 :     return std::nullopt;
      29         [ +  - ]:       30342 : }
      30                 :             : 
      31                 :          14 : std::optional<CTransactionRef> PrivateBroadcast::PickTxForSend(const NodeId& will_send_to_nodeid, const CService& will_send_to_address)
      32                 :             :     EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
      33                 :             : {
      34                 :          14 :     LOCK(m_mutex);
      35                 :             : 
      36                 :          14 :     const auto it{std::ranges::max_element(
      37         [ +  - ]:          14 :             m_transactions,
      38                 :           5 :             [](const auto& a, const auto& b) { return a < b; },
      39                 :           5 :             [](const auto& el) { return DerivePriority(el.second.send_statuses); })};
      40                 :             : 
      41         [ +  + ]:          14 :     if (it != m_transactions.end()) {
      42                 :          12 :         auto& [tx, state]{*it};
      43         [ +  - ]:          12 :         state.send_statuses.emplace_back(will_send_to_nodeid, will_send_to_address, NodeClock::now());
      44                 :          12 :         return tx;
      45                 :             :     }
      46                 :             : 
      47                 :           2 :     return std::nullopt;
      48                 :          14 : }
      49                 :             : 
      50                 :          13 : std::optional<CTransactionRef> PrivateBroadcast::GetTxForNode(const NodeId& nodeid)
      51                 :             :     EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
      52                 :             : {
      53                 :          13 :     LOCK(m_mutex);
      54         [ +  - ]:          13 :     const auto tx_and_status{GetSendStatusByNode(nodeid)};
      55         [ +  + ]:          13 :     if (tx_and_status.has_value()) {
      56                 :          12 :         return tx_and_status.value().tx;
      57                 :             :     }
      58                 :           1 :     return std::nullopt;
      59                 :          13 : }
      60                 :             : 
      61                 :          12 : void PrivateBroadcast::NodeConfirmedReception(const NodeId& nodeid)
      62                 :             :     EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
      63                 :             : {
      64                 :          12 :     LOCK(m_mutex);
      65         [ +  - ]:          12 :     const auto tx_and_status{GetSendStatusByNode(nodeid)};
      66         [ +  + ]:          12 :     if (tx_and_status.has_value()) {
      67   [ -  +  +  - ]:          23 :         tx_and_status.value().send_status.confirmed = NodeClock::now();
      68                 :             :     }
      69                 :          12 : }
      70                 :             : 
      71                 :          15 : bool PrivateBroadcast::DidNodeConfirmReception(const NodeId& nodeid)
      72                 :             :     EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
      73                 :             : {
      74                 :          15 :     LOCK(m_mutex);
      75         [ +  - ]:          15 :     const auto tx_and_status{GetSendStatusByNode(nodeid)};
      76         [ +  + ]:          15 :     if (tx_and_status.has_value()) {
      77                 :          14 :         return tx_and_status.value().send_status.confirmed.has_value();
      78                 :             :     }
      79                 :             :     return false;
      80                 :          15 : }
      81                 :             : 
      82                 :           1 : bool PrivateBroadcast::HavePendingTransactions()
      83                 :             :     EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
      84                 :             : {
      85                 :           1 :     LOCK(m_mutex);
      86         [ +  - ]:           1 :     return !m_transactions.empty();
      87                 :           1 : }
      88                 :             : 
      89                 :          12 : std::vector<CTransactionRef> PrivateBroadcast::GetStale() const
      90                 :             :     EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
      91                 :             : {
      92                 :          12 :     LOCK(m_mutex);
      93                 :          12 :     const auto now{NodeClock::now()};
      94                 :          12 :     std::vector<CTransactionRef> stale;
      95   [ +  +  +  - ]:          25 :     for (const auto& [tx, state] : m_transactions) {
      96         [ +  - ]:          13 :         const Priority p{DerivePriority(state.send_statuses)};
      97         [ +  + ]:          13 :         if (p.num_confirmed == 0) {
      98   [ +  +  +  - ]:           9 :             if (state.time_added < now - INITIAL_STALE_DURATION) stale.push_back(tx);
      99                 :             :         } else {
     100   [ +  +  +  - ]:           4 :             if (p.last_confirmed < now - STALE_DURATION) stale.push_back(tx);
     101                 :             :         }
     102                 :             :     }
     103         [ +  - ]:          12 :     return stale;
     104                 :          12 : }
     105                 :             : 
     106                 :          14 : std::vector<PrivateBroadcast::TxBroadcastInfo> PrivateBroadcast::GetBroadcastInfo() const
     107                 :             :     EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
     108                 :             : {
     109                 :          14 :     LOCK(m_mutex);
     110                 :          14 :     std::vector<TxBroadcastInfo> entries;
     111         [ +  - ]:          14 :     entries.reserve(m_transactions.size());
     112                 :             : 
     113   [ +  +  -  + ]:          39 :     for (const auto& [tx, state] : m_transactions) {
     114                 :          25 :         std::vector<PeerSendInfo> peers;
     115   [ +  -  -  + ]:          25 :         peers.reserve(state.send_statuses.size());
     116         [ +  + ]:          61 :         for (const auto& status : state.send_statuses) {
     117         [ +  - ]:          72 :             peers.emplace_back(PeerSendInfo{.address = status.address, .sent = status.picked, .received = status.confirmed});
     118                 :             :         }
     119   [ +  -  +  - ]:          50 :         entries.emplace_back(TxBroadcastInfo{.tx = tx, .time_added = state.time_added, .peers = std::move(peers)});
     120                 :          25 :     }
     121                 :             : 
     122         [ +  - ]:          14 :     return entries;
     123                 :          14 : }
     124                 :             : 
     125                 :          28 : PrivateBroadcast::Priority PrivateBroadcast::DerivePriority(const std::vector<SendStatus>& sent_to)
     126                 :             : {
     127                 :          28 :     Priority p;
     128         [ -  + ]:          28 :     p.num_picked = sent_to.size();
     129         [ +  + ]:          63 :     for (const auto& send_status : sent_to) {
     130                 :          35 :         p.last_picked = std::max(p.last_picked, send_status.picked);
     131         [ +  + ]:          35 :         if (send_status.confirmed.has_value()) {
     132                 :          27 :             ++p.num_confirmed;
     133                 :          27 :             p.last_confirmed = std::max(p.last_confirmed, send_status.confirmed.value());
     134                 :             :         }
     135                 :             :     }
     136                 :          28 :     return p;
     137                 :             : }
     138                 :             : 
     139                 :          40 : std::optional<PrivateBroadcast::TxAndSendStatusForNode> PrivateBroadcast::GetSendStatusByNode(const NodeId& nodeid)
     140                 :             :     EXCLUSIVE_LOCKS_REQUIRED(m_mutex)
     141                 :             : {
     142                 :          40 :     AssertLockHeld(m_mutex);
     143         [ +  + ]:          49 :     for (auto& [tx, state] : m_transactions) {
     144         [ +  + ]:          91 :         for (auto& send_status : state.send_statuses) {
     145         [ +  + ]:          82 :             if (send_status.nodeid == nodeid) {
     146                 :          37 :                 return TxAndSendStatusForNode{.tx = tx, .send_status = send_status};
     147                 :             :             }
     148                 :             :         }
     149                 :             :     }
     150                 :           3 :     return std::nullopt;
     151                 :             : }
        

Generated by: LCOV version 2.0-1