_ZN11ArgsManagerD2Ev:
  130|      2|ArgsManager::~ArgsManager() = default;

_ZN15ChaCha20AlignedD2Ev:
   42|      4|{
   43|      4|    memory_cleanse(input, sizeof(input));
   44|      4|}
_ZN8ChaCha20D2Ev:
  332|      4|{
  333|      4|    memory_cleanse(m_buffer.data(), m_buffer.size());
  334|      4|}

_ZN9ChainCodeD2Ev:
   28|      2|    ~ChainCode() { memory_cleanse(data(), size()); }

_ZN11CNetCleanupD2Ev:
 3676|      2|    {
 3677|       |#ifdef WIN32
 3678|       |        // Shutdown Windows Sockets
 3679|       |        WSACleanup();
 3680|       |#endif
 3681|      2|    }

_Z23ProtectNoBanConnectionsRNSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEE:
   88|  5.20k|{
   89|  5.20k|    eviction_candidates.erase(std::remove_if(eviction_candidates.begin(), eviction_candidates.end(),
   90|  5.20k|                                             [](NodeEvictionCandidate const& n) {
   91|  5.20k|                                                 return n.m_noban;
   92|  5.20k|                                             }),
   93|  5.20k|                              eviction_candidates.end());
   94|  5.20k|}
_Z26ProtectOutboundConnectionsRNSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEE:
   97|  5.20k|{
   98|  5.20k|    eviction_candidates.erase(std::remove_if(eviction_candidates.begin(), eviction_candidates.end(),
   99|  5.20k|                                             [](NodeEvictionCandidate const& n) {
  100|  5.20k|                                                 return n.m_conn_type != ConnectionType::INBOUND;
  101|  5.20k|                                             }),
  102|  5.20k|                              eviction_candidates.end());
  103|  5.20k|}
_Z32ProtectEvictionCandidatesByRatioRNSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEE:
  106|  5.20k|{
  107|       |    // Protect the half of the remaining nodes which have been connected the longest.
  108|       |    // This replicates the non-eviction implicit behavior, and precludes attacks that start later.
  109|       |    // To favorise the diversity of our peer connections, reserve up to half of these protected
  110|       |    // spots for Tor/onion, localhost, I2P, and CJDNS peers, even if they're not longest uptime
  111|       |    // overall. This helps protect these higher-latency peers that tend to be otherwise
  112|       |    // disadvantaged under our eviction criteria.
  113|  5.20k|    const size_t initial_size = eviction_candidates.size();
  114|  5.20k|    const size_t total_protect_size{initial_size / 2};
  115|       |
  116|       |    // Disadvantaged networks to protect. In the case of equal counts, earlier array members
  117|       |    // have the first opportunity to recover unused slots from the previous iteration.
  118|  5.20k|    struct Net { bool is_local; Network id; size_t count; };
  119|  5.20k|    std::array<Net, 4> networks{
  120|  5.20k|        {{false, NET_CJDNS, 0}, {false, NET_I2P, 0}, {/*localhost=*/true, NET_MAX, 0}, {false, NET_ONION, 0}}};
  121|       |
  122|       |    // Count and store the number of eviction candidates per network.
  123|  20.8k|    for (Net& n : networks) {
  ------------------
  |  Branch (123:17): [True: 20.8k, False: 5.20k]
  ------------------
  124|  20.8k|        n.count = std::count_if(eviction_candidates.cbegin(), eviction_candidates.cend(),
  125|  20.8k|                                [&n](const NodeEvictionCandidate& c) {
  126|  20.8k|                                    return n.is_local ? c.m_is_local : c.m_network == n.id;
  127|  20.8k|                                });
  128|  20.8k|    }
  129|       |    // Sort `networks` by ascending candidate count, to give networks having fewer candidates
  130|       |    // the first opportunity to recover unused protected slots from the previous iteration.
  131|  5.20k|    std::stable_sort(networks.begin(), networks.end(), [](Net a, Net b) { return a.count < b.count; });
  132|       |
  133|       |    // Protect up to 25% of the eviction candidates by disadvantaged network.
  134|  5.20k|    const size_t max_protect_by_network{total_protect_size / 2};
  135|  5.20k|    size_t num_protected{0};
  136|       |
  137|  15.4k|    while (num_protected < max_protect_by_network) {
  ------------------
  |  Branch (137:12): [True: 11.0k, False: 4.40k]
  ------------------
  138|       |        // Count the number of disadvantaged networks from which we have peers to protect.
  139|  11.0k|        auto num_networks = std::count_if(networks.begin(), networks.end(), [](const Net& n) { return n.count; });
  140|  11.0k|        if (num_networks == 0) {
  ------------------
  |  Branch (140:13): [True: 561, False: 10.4k]
  ------------------
  141|    561|            break;
  142|    561|        }
  143|  10.4k|        const size_t disadvantaged_to_protect{max_protect_by_network - num_protected};
  144|  10.4k|        const size_t protect_per_network{std::max(disadvantaged_to_protect / num_networks, static_cast<size_t>(1))};
  145|       |        // Early exit flag if there are no remaining candidates by disadvantaged network.
  146|  10.4k|        bool protected_at_least_one{false};
  147|       |
  148|  40.5k|        for (Net& n : networks) {
  ------------------
  |  Branch (148:21): [True: 40.5k, False: 7.20k]
  ------------------
  149|  40.5k|            if (n.count == 0) continue;
  ------------------
  |  Branch (149:17): [True: 14.7k, False: 25.8k]
  ------------------
  150|  25.8k|            const size_t before = eviction_candidates.size();
  151|  25.8k|            EraseLastKElements(eviction_candidates, CompareNodeNetworkTime(n.is_local, n.id),
  152|  25.8k|                               protect_per_network, [&n](const NodeEvictionCandidate& c) {
  153|  25.8k|                                   return n.is_local ? c.m_is_local : c.m_network == n.id;
  154|  25.8k|                               });
  155|  25.8k|            const size_t after = eviction_candidates.size();
  156|  25.8k|            if (before > after) {
  ------------------
  |  Branch (156:17): [True: 17.4k, False: 8.37k]
  ------------------
  157|  17.4k|                protected_at_least_one = true;
  158|  17.4k|                const size_t delta{before - after};
  159|  17.4k|                num_protected += delta;
  160|  17.4k|                if (num_protected >= max_protect_by_network) {
  ------------------
  |  Branch (160:21): [True: 3.23k, False: 14.1k]
  ------------------
  161|  3.23k|                    break;
  162|  3.23k|                }
  163|  14.1k|                n.count -= delta;
  164|  14.1k|            }
  165|  25.8k|        }
  166|  10.4k|        if (!protected_at_least_one) {
  ------------------
  |  Branch (166:13): [True: 240, False: 10.2k]
  ------------------
  167|    240|            break;
  168|    240|        }
  169|  10.4k|    }
  170|       |
  171|       |    // Calculate how many we removed, and update our total number of peers that
  172|       |    // we want to protect based on uptime accordingly.
  173|  5.20k|    assert(num_protected == initial_size - eviction_candidates.size());
  ------------------
  |  Branch (173:5): [True: 5.20k, False: 0]
  ------------------
  174|  5.20k|    const size_t remaining_to_protect{total_protect_size - num_protected};
  175|  5.20k|    EraseLastKElements(eviction_candidates, ReverseCompareNodeTimeConnected, remaining_to_protect);
  176|  5.20k|}
_Z17SelectNodeToEvictONSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEE:
  179|  5.20k|{
  180|       |    // Protect connections with certain characteristics
  181|       |
  182|  5.20k|    ProtectNoBanConnections(vEvictionCandidates);
  183|       |
  184|  5.20k|    ProtectOutboundConnections(vEvictionCandidates);
  185|       |
  186|       |    // Deterministically select 4 peers to protect by netgroup.
  187|       |    // An attacker cannot predict which netgroups will be protected
  188|  5.20k|    EraseLastKElements(vEvictionCandidates, CompareNetGroupKeyed, 4);
  189|       |    // Protect the 8 nodes with the lowest minimum ping time.
  190|       |    // An attacker cannot manipulate this metric without physically moving nodes closer to the target.
  191|  5.20k|    EraseLastKElements(vEvictionCandidates, ReverseCompareNodeMinPingTime, 8);
  192|       |    // Protect 4 nodes that most recently sent us novel transactions accepted into our mempool.
  193|       |    // An attacker cannot manipulate this metric without performing useful work.
  194|  5.20k|    EraseLastKElements(vEvictionCandidates, CompareNodeTXTime, 4);
  195|       |    // Protect up to 8 non-tx-relay peers that have sent us novel blocks.
  196|  5.20k|    EraseLastKElements(vEvictionCandidates, CompareNodeBlockRelayOnlyTime, 8,
  197|  5.20k|                       [](const NodeEvictionCandidate& n) { return !n.m_relay_txs && n.fRelevantServices; });
  198|       |
  199|       |    // Protect 4 nodes that most recently sent us novel blocks.
  200|       |    // An attacker cannot manipulate this metric without performing useful work.
  201|  5.20k|    EraseLastKElements(vEvictionCandidates, CompareNodeBlockTime, 4);
  202|       |
  203|       |    // Protect some of the remaining eviction candidates by ratios of desirable
  204|       |    // or disadvantaged characteristics.
  205|  5.20k|    ProtectEvictionCandidatesByRatio(vEvictionCandidates);
  206|       |
  207|  5.20k|    if (vEvictionCandidates.empty()) return std::nullopt;
  ------------------
  |  Branch (207:9): [True: 841, False: 4.36k]
  ------------------
  208|       |
  209|       |    // If any remaining peers are preferred for eviction consider only them.
  210|       |    // This happens after the other preferences since if a peer is really the best by other criteria (esp relaying blocks)
  211|       |    //  then we probably don't want to evict it no matter what.
  212|  4.36k|    if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](NodeEvictionCandidate const &n){return n.prefer_evict;})) {
  ------------------
  |  Branch (212:9): [True: 637, False: 3.73k]
  ------------------
  213|    637|        vEvictionCandidates.erase(std::remove_if(vEvictionCandidates.begin(),vEvictionCandidates.end(),
  214|    637|                                  [](NodeEvictionCandidate const &n){return !n.prefer_evict;}),vEvictionCandidates.end());
  215|    637|    }
  216|       |
  217|       |    // Identify the network group with the most connections and youngest member.
  218|       |    // (vEvictionCandidates is already sorted by reverse connect time)
  219|  4.36k|    uint64_t naMostConnections;
  220|  4.36k|    unsigned int nMostConnections = 0;
  221|  4.36k|    NodeClock::time_point nMostConnectionsTime{NodeClock::epoch};
  222|  4.36k|    std::map<uint64_t, std::vector<NodeEvictionCandidate> > mapNetGroupNodes;
  223|   442k|    for (const NodeEvictionCandidate &node : vEvictionCandidates) {
  ------------------
  |  Branch (223:44): [True: 442k, False: 4.36k]
  ------------------
  224|   442k|        std::vector<NodeEvictionCandidate> &group = mapNetGroupNodes[node.nKeyedNetGroup];
  225|   442k|        group.push_back(node);
  226|   442k|        const auto grouptime{group[0].m_connected};
  227|       |
  228|   442k|        if (group.size() > nMostConnections || (group.size() == nMostConnections && grouptime > nMostConnectionsTime)) {
  ------------------
  |  Branch (228:13): [True: 168k, False: 274k]
  |  Branch (228:49): [True: 17.5k, False: 257k]
  |  Branch (228:85): [True: 526, False: 17.0k]
  ------------------
  229|   168k|            nMostConnections = group.size();
  230|   168k|            nMostConnectionsTime = grouptime;
  231|   168k|            naMostConnections = node.nKeyedNetGroup;
  232|   168k|        }
  233|   442k|    }
  234|       |
  235|       |    // Reduce to the network group with the most connections
  236|  4.36k|    vEvictionCandidates = std::move(mapNetGroupNodes[naMostConnections]);
  237|       |
  238|       |    // Disconnect from the network group with the most connections
  239|  4.36k|    return vEvictionCandidates.front().id;
  240|  5.20k|}
eviction.cpp:_ZZ23ProtectNoBanConnectionsRNSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEEENK3$_0clERKS1_:
   90|  1.54M|                                             [](NodeEvictionCandidate const& n) {
   91|  1.54M|                                                 return n.m_noban;
   92|  1.54M|                                             }),
eviction.cpp:_ZZ26ProtectOutboundConnectionsRNSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEEENK3$_0clERKS1_:
   99|  1.40M|                                             [](NodeEvictionCandidate const& n) {
  100|  1.40M|                                                 return n.m_conn_type != ConnectionType::INBOUND;
  101|  1.40M|                                             }),
eviction.cpp:_ZZ32ProtectEvictionCandidatesByRatioRNSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEEENK3$_0clERKS1_:
  125|  5.20M|                                [&n](const NodeEvictionCandidate& c) {
  126|  5.20M|                                    return n.is_local ? c.m_is_local : c.m_network == n.id;
  ------------------
  |  Branch (126:44): [True: 1.30M, False: 3.90M]
  ------------------
  127|  5.20M|                                });
eviction.cpp:_ZZ32ProtectEvictionCandidatesByRatioRNSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEEENK3$_1clERKZ32ProtectEvictionCandidatesByRatioS5_E3Net:
  139|  44.0k|        auto num_networks = std::count_if(networks.begin(), networks.end(), [](const Net& n) { return n.count; });
_ZN22CompareNodeNetworkTimeC2Eb7Network:
   67|  25.8k|    CompareNodeNetworkTime(bool is_local, Network network) : m_is_local(is_local), m_network(network) {}
eviction.cpp:_ZL31ReverseCompareNodeTimeConnectedRK21NodeEvictionCandidateS1_:
   22|  21.4M|{
   23|  21.4M|    return a.m_connected > b.m_connected;
   24|  21.4M|}
eviction.cpp:_ZL20CompareNetGroupKeyedRK21NodeEvictionCandidateS1_:
   26|  38.6M|static bool CompareNetGroupKeyed(const NodeEvictionCandidate &a, const NodeEvictionCandidate &b) {
   27|  38.6M|    return a.nKeyedNetGroup < b.nKeyedNetGroup;
   28|  38.6M|}
eviction.cpp:_ZL29ReverseCompareNodeMinPingTimeRK21NodeEvictionCandidateS1_:
   17|  31.1M|{
   18|  31.1M|    return a.m_min_ping_time > b.m_min_ping_time;
   19|  31.1M|}
eviction.cpp:_ZL17CompareNodeTXTimeRK21NodeEvictionCandidateS1_:
   39|  30.0M|{
   40|       |    // There is a fall-through here because it is common for a node to have more than a few peers that have not yet relayed txn.
   41|  30.0M|    if (a.m_last_tx_time != b.m_last_tx_time) return a.m_last_tx_time < b.m_last_tx_time;
  ------------------
  |  Branch (41:9): [True: 17.2M, False: 12.7M]
  ------------------
   42|  12.7M|    if (a.m_relay_txs != b.m_relay_txs) return b.m_relay_txs;
  ------------------
  |  Branch (42:9): [True: 78.6k, False: 12.6M]
  ------------------
   43|  12.6M|    if (a.fBloomFilter != b.fBloomFilter) return a.fBloomFilter;
  ------------------
  |  Branch (43:9): [True: 104k, False: 12.5M]
  ------------------
   44|  12.5M|    return a.m_connected > b.m_connected;
   45|  12.6M|}
eviction.cpp:_ZL29CompareNodeBlockRelayOnlyTimeRK21NodeEvictionCandidateS1_:
   49|  30.1M|{
   50|  30.1M|    if (a.m_relay_txs != b.m_relay_txs) return a.m_relay_txs;
  ------------------
  |  Branch (50:9): [True: 669k, False: 29.4M]
  ------------------
   51|  29.4M|    if (a.m_last_block_time != b.m_last_block_time) return a.m_last_block_time < b.m_last_block_time;
  ------------------
  |  Branch (51:9): [True: 18.1M, False: 11.2M]
  ------------------
   52|  11.2M|    if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices;
  ------------------
  |  Branch (52:9): [True: 138k, False: 11.1M]
  ------------------
   53|  11.1M|    return a.m_connected > b.m_connected;
   54|  11.2M|}
eviction.cpp:_ZL20CompareNodeBlockTimeRK21NodeEvictionCandidateS1_:
   31|  26.3M|{
   32|       |    // There is a fall-through here because it is common for a node to have many peers which have not yet relayed a block.
   33|  26.3M|    if (a.m_last_block_time != b.m_last_block_time) return a.m_last_block_time < b.m_last_block_time;
  ------------------
  |  Branch (33:9): [True: 17.2M, False: 9.11M]
  ------------------
   34|  9.11M|    if (a.fRelevantServices != b.fRelevantServices) return b.fRelevantServices;
  ------------------
  |  Branch (34:9): [True: 109k, False: 9.00M]
  ------------------
   35|  9.00M|    return a.m_connected > b.m_connected;
   36|  9.11M|}
eviction.cpp:_ZZ17SelectNodeToEvictONSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEEENK3$_1clERKS1_:
  212|   498k|    if (std::any_of(vEvictionCandidates.begin(),vEvictionCandidates.end(),[](NodeEvictionCandidate const &n){return n.prefer_evict;})) {
eviction.cpp:_ZZ17SelectNodeToEvictONSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEEENK3$_2clERKS1_:
  214|   215k|                                  [](NodeEvictionCandidate const &n){return !n.prefer_evict;}),vEvictionCandidates.end());
eviction.cpp:_ZZ32ProtectEvictionCandidatesByRatioRNSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEEENK3$_3clEZ32ProtectEvictionCandidatesByRatioS5_E3NetS7_:
  131|   169k|    std::stable_sort(networks.begin(), networks.end(), [](Net a, Net b) { return a.count < b.count; });
eviction.cpp:_ZL18EraseLastKElementsI21NodeEvictionCandidate22CompareNodeNetworkTimeEvRNSt3__16vectorIT_NS2_9allocatorIS4_EEEET0_mNS2_8functionIFbRKS0_EEE:
   81|  25.8k|{
   82|  25.8k|    std::sort(elements.begin(), elements.end(), comparator);
   83|  25.8k|    size_t eraseSize = std::min(k, elements.size());
   84|  25.8k|    elements.erase(std::remove_if(elements.end() - eraseSize, elements.end(), predicate), elements.end());
   85|  25.8k|}
_ZNK22CompareNodeNetworkTimeclERK21NodeEvictionCandidateS2_:
   69|   281M|    {
   70|   281M|        if (m_is_local && a.m_is_local != b.m_is_local) return b.m_is_local;
  ------------------
  |  Branch (70:13): [True: 56.1M, False: 225M]
  |  Branch (70:27): [True: 994k, False: 55.1M]
  ------------------
   71|   280M|        if ((a.m_network == m_network) != (b.m_network == m_network)) return b.m_network == m_network;
  ------------------
  |  Branch (71:13): [True: 9.22M, False: 271M]
  ------------------
   72|   271M|        return a.m_connected > b.m_connected;
   73|   280M|    };
eviction.cpp:_ZZ32ProtectEvictionCandidatesByRatioRNSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEEENK3$_2clERKS1_:
  152|   425k|                               protect_per_network, [&n](const NodeEvictionCandidate& c) {
  153|   425k|                                   return n.is_local ? c.m_is_local : c.m_network == n.id;
  ------------------
  |  Branch (153:43): [True: 112k, False: 313k]
  ------------------
  154|   425k|                               });
eviction.cpp:_ZL18EraseLastKElementsI21NodeEvictionCandidatePFbRKS0_S2_EEvRNSt3__16vectorIT_NS5_9allocatorIS7_EEEET0_mNS5_8functionIFbS2_EEE:
   81|  31.2k|{
   82|  31.2k|    std::sort(elements.begin(), elements.end(), comparator);
   83|  31.2k|    size_t eraseSize = std::min(k, elements.size());
   84|  31.2k|    elements.erase(std::remove_if(elements.end() - eraseSize, elements.end(), predicate), elements.end());
   85|  31.2k|}
eviction.cpp:_ZZL18EraseLastKElementsI21NodeEvictionCandidatePFbRKS0_S2_EEvRNSt3__16vectorIT_NS5_9allocatorIS7_EEEET0_mNS5_8functionIFbS2_EEEENK3$_0clES2_:
   80|   466k|    std::function<bool(const NodeEvictionCandidate&)> predicate = [](const NodeEvictionCandidate& n) { return true; })
eviction.cpp:_ZZ17SelectNodeToEvictONSt3__16vectorI21NodeEvictionCandidateNS_9allocatorIS1_EEEEENK3$_0clERKS1_:
  197|  34.7k|                       [](const NodeEvictionCandidate& n) { return !n.m_relay_txs && n.fRelevantServices; });
  ------------------
  |  Branch (197:68): [True: 6.96k, False: 27.7k]
  |  Branch (197:86): [True: 921, False: 6.04k]
  ------------------

_ZNK9prevectorILj16EhjiE9is_directEv:
  126|     16|    bool is_direct() const { return _size <= N; }
_ZN9prevectorILj16EhjiED2Ev:
  422|     16|    ~prevector() {
  423|     16|        if (!is_direct()) {
  ------------------
  |  Branch (423:13): [True: 0, False: 16]
  ------------------
  424|      0|            free(_union.indirect_contents.indirect);
  425|      0|            _union.indirect_contents.indirect = nullptr;
  426|      0|        }
  427|     16|    }
_ZNK9prevectorILj36EhjiE9is_directEv:
  126|     14|    bool is_direct() const { return _size <= N; }
_ZN9prevectorILj36EhjiED2Ev:
  422|     14|    ~prevector() {
  423|     14|        if (!is_direct()) {
  ------------------
  |  Branch (423:13): [True: 0, False: 14]
  ------------------
  424|      0|            free(_union.indirect_contents.indirect);
  425|      0|            _union.indirect_contents.indirect = nullptr;
  426|      0|        }
  427|     14|    }

random.cpp:_ZN12_GLOBAL__N_18RNGStateD2Ev:
  367|      2|    ~RNGState() = default;

_ZN20BaseSignatureCheckerD2Ev:
  298|      2|    virtual ~BaseSignatureChecker() = default;

_ZN20BaseSignatureCreatorD2Ev:
   41|      4|    virtual ~BaseSignatureCreator() = default;

_ZN15SigningProviderD2Ev:
  170|      2|    virtual ~SigningProvider() = default;

random.cpp:_ZN16secure_allocatorIN12_GLOBAL__N_18RNGStateEE10deallocateEPS1_m:
   37|      2|    {
   38|      2|        if (p != nullptr) {
  ------------------
  |  Branch (38:13): [True: 2, False: 0]
  ------------------
   39|      2|            memory_cleanse(p, sizeof(T) * n);
   40|      2|        }
   41|      2|        LockedPoolManager::Instance().free(p);
   42|      2|    }

_Z14memory_cleansePvm:
   15|     14|{
   16|       |#if defined(WIN32)
   17|       |    /* SecureZeroMemory is guaranteed not to be optimized out. */
   18|       |    SecureZeroMemory(ptr, len);
   19|       |#else
   20|     14|    std::memset(ptr, 0, len);
   21|       |
   22|       |    /* Memory barrier that scares the compiler away from optimizing out the memset.
   23|       |     *
   24|       |     * Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
   25|       |     * in BoringSSL (ISC License):
   26|       |     *    As best as we can tell, this is sufficient to break any optimisations that
   27|       |     *    might try to eliminate "superfluous" memsets.
   28|       |     * This method is used in memzero_explicit() the Linux kernel, too. Its advantage is that it
   29|       |     * is pretty efficient because the compiler can still implement the memset() efficiently,
   30|       |     * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
   31|       |     * Yang et al. (USENIX Security 2017) for more background.
   32|       |     */
   33|     14|    __asm__ __volatile__("" : : "r"(ptr) : "memory");
   34|     14|#endif
   35|     14|}

_ZN5ArenaD2Ev:
   48|      2|Arena::~Arena() = default;
_ZN5Arena4freeEPv:
   87|      2|{
   88|       |    // Freeing the nullptr pointer is OK.
   89|      2|    if (ptr == nullptr) {
  ------------------
  |  Branch (89:9): [True: 0, False: 2]
  ------------------
   90|      0|        return;
   91|      0|    }
   92|       |
   93|       |    // Remove chunk from used map
   94|      2|    auto i = chunks_used.find(ptr);
   95|      2|    if (i == chunks_used.end()) {
  ------------------
  |  Branch (95:9): [True: 0, False: 2]
  ------------------
   96|      0|        throw std::runtime_error("Arena: invalid or double free");
   97|      0|    }
   98|      2|    auto freed = std::make_pair(static_cast<char*>(i->first), i->second);
   99|      2|    chunks_used.erase(i);
  100|       |
  101|       |    // coalesce freed with previous chunk
  102|      2|    auto prev = chunks_free_end.find(freed.first);
  103|      2|    if (prev != chunks_free_end.end()) {
  ------------------
  |  Branch (103:9): [True: 2, False: 0]
  ------------------
  104|      2|        freed.first -= prev->second->first;
  105|      2|        freed.second += prev->second->first;
  106|      2|        size_to_free_chunk.erase(prev->second);
  107|      2|        chunks_free_end.erase(prev);
  108|      2|    }
  109|       |
  110|       |    // coalesce freed with chunk after freed
  111|      2|    auto next = chunks_free.find(freed.first + freed.second);
  112|      2|    if (next != chunks_free.end()) {
  ------------------
  |  Branch (112:9): [True: 0, False: 2]
  ------------------
  113|      0|        freed.second += next->second->first;
  114|      0|        size_to_free_chunk.erase(next->second);
  115|      0|        chunks_free.erase(next);
  116|      0|    }
  117|       |
  118|       |    // Add/set space with coalesced free chunk
  119|      2|    auto it = size_to_free_chunk.emplace(freed.second, freed.first);
  120|      2|    chunks_free[freed.first] = it;
  121|      2|    chunks_free_end[freed.first + freed.second] = it;
  122|      2|}
_ZN24PosixLockedPageAllocator10FreeLockedEPvm:
  254|      2|{
  255|      2|    len = align_up(len, page_size);
  256|      2|    memory_cleanse(addr, len);
  257|      2|    munlock(addr, len);
  258|      2|    munmap(addr, len);
  259|      2|}
_ZN10LockedPoolD2Ev:
  283|      2|LockedPool::~LockedPool() = default;
_ZN10LockedPool4freeEPv:
  308|      2|{
  309|      2|    std::lock_guard<std::mutex> lock(mutex);
  310|       |    // TODO we can do better than this linear search by keeping a map of arena
  311|       |    // extents to arena, and looking up the address.
  312|      2|    for (auto &arena: arenas) {
  ------------------
  |  Branch (312:21): [True: 2, False: 0]
  ------------------
  313|      2|        if (arena.addressInArena(ptr)) {
  ------------------
  |  Branch (313:13): [True: 2, False: 0]
  ------------------
  314|      2|            arena.free(ptr);
  315|      2|            return;
  316|      2|        }
  317|      2|    }
  318|      0|    throw std::runtime_error("LockedPool: invalid address not pointing to any arena");
  319|      2|}
_ZN10LockedPool15LockedPageArenaD2Ev:
  370|      2|{
  371|      2|    allocator->FreeLocked(base, size);
  372|      2|}
_ZN17LockedPoolManager8InstanceEv:
  405|      2|{
  406|      2|    static std::once_flag init_flag;
  407|      2|    std::call_once(init_flag, LockedPoolManager::CreateInstance);
  408|      2|    return *LockedPoolManager::_instance;
  409|      2|}
lockedpool.cpp:_ZL8align_upmm:
   32|      2|{
   33|      2|    return (x + align - 1) & ~(align - 1);
   34|      2|}

_ZNK5Arena14addressInArenaEPv:
   90|      2|    bool addressInArena(void *ptr) const { return ptr >= base && ptr < end; }
  ------------------
  |  Branch (90:51): [True: 2, False: 0]
  |  Branch (90:66): [True: 2, False: 0]
  ------------------
_ZN19LockedPageAllocatorD2Ev:
   22|      2|    virtual ~LockedPageAllocator() = default;

_ZN14AnnotatedMixinINSt3__115recursive_mutexEED2Ev:
   96|      2|    ~AnnotatedMixin() {
   97|      2|        DeleteLock((void*)this);
   98|      2|    }
_ZN14AnnotatedMixinINSt3__15mutexEED2Ev:
   96|     64|    ~AnnotatedMixin() {
   97|     64|        DeleteLock((void*)this);
   98|     64|    }
_Z10DeleteLockPv:
   74|     66|inline void DeleteLock(void* cs) {}
_Z17MaybeCheckNotHeldR14AnnotatedMixinINSt3__15mutexEE:
  258|     30|inline Mutex& MaybeCheckNotHeld(Mutex& cs) EXCLUSIVE_LOCKS_REQUIRED(!cs) LOCK_RETURNED(cs) { return cs; }
_ZN10UniqueLockI14AnnotatedMixinINSt3__15mutexEEEC2ERS3_PKcS7_ib:
  181|     30|    UniqueLock(MutexType& mutexIn, const char* pszName, const char* pszFile, int nLine, bool fTry = false) EXCLUSIVE_LOCK_FUNCTION(mutexIn) : Base(mutexIn, std::defer_lock)
  182|     30|    {
  183|     30|        if (fTry)
  ------------------
  |  Branch (183:13): [True: 0, False: 30]
  ------------------
  184|      0|            TryEnter(pszName, pszFile, nLine);
  185|     30|        else
  186|     30|            Enter(pszName, pszFile, nLine);
  187|     30|    }
_Z13EnterCriticalINSt3__15mutexEEvPKcS3_iPT_b:
   67|     30|inline void EnterCritical(const char* pszName, const char* pszFile, int nLine, MutexType* cs, bool fTry = false) {}
_Z13LeaveCriticalv:
   68|     30|inline void LeaveCritical() {}
_ZN10UniqueLockI14AnnotatedMixinINSt3__15mutexEEE5EnterEPKcS6_i:
  159|     30|    {
  160|     30|        EnterCritical(pszName, pszFile, nLine, Base::mutex());
  161|       |#ifdef DEBUG_LOCKCONTENTION
  162|       |        if (!Base::try_lock()) {
  163|       |            ContendedLock(pszName, pszFile, nLine, static_cast<Base&>(*this));
  164|       |        }
  165|       |#else
  166|     30|        Base::lock();
  167|     30|#endif
  168|     30|    }
_ZN10UniqueLockI14AnnotatedMixinINSt3__15mutexEEED2Ev:
  201|     30|    {
  202|     30|        if (Base::owns_lock())
  ------------------
  |  Branch (202:13): [True: 30, False: 0]
  ------------------
  203|     30|            LeaveCritical();
  204|     30|    }

_ZN18FuzzedDataProvider16PickValueInArrayI7NetworkLm7EEET_RKNSt3__15arrayIS2_XT0_EEE:
  310|  1.54M|T FuzzedDataProvider::PickValueInArray(const std::array<T, size> &array) {
  311|  1.54M|  static_assert(size > 0, "The array must be non empty.");
  312|  1.54M|  return array[ConsumeIntegralInRange<size_t>(0, size - 1)];
  313|  1.54M|}
_ZN18FuzzedDataProvider16PickValueInArrayI14ConnectionTypeLm7EEET_RAT0__KS2_:
  304|  1.54M|T FuzzedDataProvider::PickValueInArray(const T (&array)[size]) {
  305|  1.54M|  static_assert(size > 0, "The array must be non empty.");
  306|  1.54M|  return array[ConsumeIntegralInRange<size_t>(0, size - 1)];
  307|  1.54M|}
_ZN18FuzzedDataProvider15ConsumeIntegralImEET_v:
  195|  1.54M|template <typename T> T FuzzedDataProvider::ConsumeIntegral() {
  196|  1.54M|  return ConsumeIntegralInRange(std::numeric_limits<T>::min(),
  197|  1.54M|                                std::numeric_limits<T>::max());
  198|  1.54M|}
_ZN18FuzzedDataProviderC2EPKhm:
   37|  5.20k|      : data_ptr_(data), remaining_bytes_(size) {}
_ZN18FuzzedDataProvider11ConsumeBoolEv:
  289|  10.8M|inline bool FuzzedDataProvider::ConsumeBool() {
  290|  10.8M|  return 1 & ConsumeIntegral<uint8_t>();
  291|  10.8M|}
_ZN18FuzzedDataProvider15ConsumeIntegralIhEET_v:
  195|  10.8M|template <typename T> T FuzzedDataProvider::ConsumeIntegral() {
  196|  10.8M|  return ConsumeIntegralInRange(std::numeric_limits<T>::min(),
  197|  10.8M|                                std::numeric_limits<T>::max());
  198|  10.8M|}
_ZN18FuzzedDataProvider22ConsumeIntegralInRangeIhEET_S1_S1_:
  205|  10.8M|T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) {
  206|  10.8M|  static_assert(std::is_integral_v<T>, "An integral type is required.");
  207|  10.8M|  static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
  208|       |
  209|  10.8M|  if (min > max)
  ------------------
  |  Branch (209:7): [True: 0, False: 10.8M]
  ------------------
  210|      0|    abort();
  211|       |
  212|       |  // Use the biggest type possible to hold the range and the result.
  213|  10.8M|  uint64_t range = static_cast<uint64_t>(max) - static_cast<uint64_t>(min);
  214|  10.8M|  uint64_t result = 0;
  215|  10.8M|  size_t offset = 0;
  216|       |
  217|  21.6M|  while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
  ------------------
  |  Branch (217:10): [True: 10.8M, False: 10.7M]
  |  Branch (217:43): [True: 10.8M, False: 0]
  ------------------
  218|  10.8M|         remaining_bytes_ != 0) {
  ------------------
  |  Branch (218:10): [True: 10.7M, False: 25.7k]
  ------------------
  219|       |    // Pull bytes off the end of the seed data. Experimentally, this seems to
  220|       |    // allow the fuzzer to more easily explore the input space. This makes
  221|       |    // sense, since it works by modifying inputs that caused new code to run,
  222|       |    // and this data is often used to encode length of data read by
  223|       |    // |ConsumeBytes|. Separating out read lengths makes it easier modify the
  224|       |    // contents of the data that is actually read.
  225|  10.7M|    --remaining_bytes_;
  226|  10.7M|    result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
  227|  10.7M|    offset += CHAR_BIT;
  228|  10.7M|  }
  229|       |
  230|       |  // Avoid division by 0, in case |range + 1| results in overflow.
  231|  10.8M|  if (range != std::numeric_limits<decltype(range)>::max())
  ------------------
  |  Branch (231:7): [True: 10.8M, False: 0]
  ------------------
  232|  10.8M|    result = result % (range + 1);
  233|       |
  234|  10.8M|  return static_cast<T>(static_cast<uint64_t>(min) + result);
  235|  10.8M|}
_ZN18FuzzedDataProvider22ConsumeIntegralInRangeImEET_S1_S1_:
  205|  4.63M|T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) {
  206|  4.63M|  static_assert(std::is_integral_v<T>, "An integral type is required.");
  207|  4.63M|  static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
  208|       |
  209|  4.63M|  if (min > max)
  ------------------
  |  Branch (209:7): [True: 0, False: 4.63M]
  ------------------
  210|      0|    abort();
  211|       |
  212|       |  // Use the biggest type possible to hold the range and the result.
  213|  4.63M|  uint64_t range = static_cast<uint64_t>(max) - static_cast<uint64_t>(min);
  214|  4.63M|  uint64_t result = 0;
  215|  4.63M|  size_t offset = 0;
  216|       |
  217|  20.0M|  while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
  ------------------
  |  Branch (217:10): [True: 18.5M, False: 1.54M]
  |  Branch (217:43): [True: 15.4M, False: 3.08M]
  ------------------
  218|  15.4M|         remaining_bytes_ != 0) {
  ------------------
  |  Branch (218:10): [True: 15.4M, False: 11.6k]
  ------------------
  219|       |    // Pull bytes off the end of the seed data. Experimentally, this seems to
  220|       |    // allow the fuzzer to more easily explore the input space. This makes
  221|       |    // sense, since it works by modifying inputs that caused new code to run,
  222|       |    // and this data is often used to encode length of data read by
  223|       |    // |ConsumeBytes|. Separating out read lengths makes it easier modify the
  224|       |    // contents of the data that is actually read.
  225|  15.4M|    --remaining_bytes_;
  226|  15.4M|    result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
  227|  15.4M|    offset += CHAR_BIT;
  228|  15.4M|  }
  229|       |
  230|       |  // Avoid division by 0, in case |range + 1| results in overflow.
  231|  4.63M|  if (range != std::numeric_limits<decltype(range)>::max())
  ------------------
  |  Branch (231:7): [True: 3.09M, False: 1.54M]
  ------------------
  232|  3.09M|    result = result % (range + 1);
  233|       |
  234|  4.63M|  return static_cast<T>(static_cast<uint64_t>(min) + result);
  235|  4.63M|}
_ZN18FuzzedDataProvider15ConsumeIntegralIlEET_v:
  195|  1.54M|template <typename T> T FuzzedDataProvider::ConsumeIntegral() {
  196|  1.54M|  return ConsumeIntegralInRange(std::numeric_limits<T>::min(),
  197|  1.54M|                                std::numeric_limits<T>::max());
  198|  1.54M|}
_ZN18FuzzedDataProvider22ConsumeIntegralInRangeIlEET_S1_S1_:
  205|  1.54M|T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) {
  206|  1.54M|  static_assert(std::is_integral_v<T>, "An integral type is required.");
  207|  1.54M|  static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
  208|       |
  209|  1.54M|  if (min > max)
  ------------------
  |  Branch (209:7): [True: 0, False: 1.54M]
  ------------------
  210|      0|    abort();
  211|       |
  212|       |  // Use the biggest type possible to hold the range and the result.
  213|  1.54M|  uint64_t range = static_cast<uint64_t>(max) - static_cast<uint64_t>(min);
  214|  1.54M|  uint64_t result = 0;
  215|  1.54M|  size_t offset = 0;
  216|       |
  217|  13.9M|  while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
  ------------------
  |  Branch (217:10): [True: 12.3M, False: 1.54M]
  |  Branch (217:43): [True: 12.3M, False: 0]
  ------------------
  218|  12.3M|         remaining_bytes_ != 0) {
  ------------------
  |  Branch (218:10): [True: 12.3M, False: 1.71k]
  ------------------
  219|       |    // Pull bytes off the end of the seed data. Experimentally, this seems to
  220|       |    // allow the fuzzer to more easily explore the input space. This makes
  221|       |    // sense, since it works by modifying inputs that caused new code to run,
  222|       |    // and this data is often used to encode length of data read by
  223|       |    // |ConsumeBytes|. Separating out read lengths makes it easier modify the
  224|       |    // contents of the data that is actually read.
  225|  12.3M|    --remaining_bytes_;
  226|  12.3M|    result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
  227|  12.3M|    offset += CHAR_BIT;
  228|  12.3M|  }
  229|       |
  230|       |  // Avoid division by 0, in case |range + 1| results in overflow.
  231|  1.54M|  if (range != std::numeric_limits<decltype(range)>::max())
  ------------------
  |  Branch (231:7): [True: 0, False: 1.54M]
  ------------------
  232|      0|    result = result % (range + 1);
  233|       |
  234|  1.54M|  return static_cast<T>(static_cast<uint64_t>(min) + result);
  235|  1.54M|}
_ZN18FuzzedDataProvider22ConsumeIntegralInRangeIxEET_S1_S1_:
  205|  6.18M|T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) {
  206|  6.18M|  static_assert(std::is_integral_v<T>, "An integral type is required.");
  207|  6.18M|  static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
  208|       |
  209|  6.18M|  if (min > max)
  ------------------
  |  Branch (209:7): [True: 0, False: 6.18M]
  ------------------
  210|      0|    abort();
  211|       |
  212|       |  // Use the biggest type possible to hold the range and the result.
  213|  6.18M|  uint64_t range = static_cast<uint64_t>(max) - static_cast<uint64_t>(min);
  214|  6.18M|  uint64_t result = 0;
  215|  6.18M|  size_t offset = 0;
  216|       |
  217|  37.0M|  while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
  ------------------
  |  Branch (217:10): [True: 35.4M, False: 1.54M]
  |  Branch (217:43): [True: 30.8M, False: 4.62M]
  ------------------
  218|  30.8M|         remaining_bytes_ != 0) {
  ------------------
  |  Branch (218:10): [True: 30.8M, False: 11.1k]
  ------------------
  219|       |    // Pull bytes off the end of the seed data. Experimentally, this seems to
  220|       |    // allow the fuzzer to more easily explore the input space. This makes
  221|       |    // sense, since it works by modifying inputs that caused new code to run,
  222|       |    // and this data is often used to encode length of data read by
  223|       |    // |ConsumeBytes|. Separating out read lengths makes it easier modify the
  224|       |    // contents of the data that is actually read.
  225|  30.8M|    --remaining_bytes_;
  226|  30.8M|    result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
  227|  30.8M|    offset += CHAR_BIT;
  228|  30.8M|  }
  229|       |
  230|       |  // Avoid division by 0, in case |range + 1| results in overflow.
  231|  6.18M|  if (range != std::numeric_limits<decltype(range)>::max())
  ------------------
  |  Branch (231:7): [True: 6.18M, False: 0]
  ------------------
  232|  6.18M|    result = result % (range + 1);
  233|       |
  234|  6.18M|  return static_cast<T>(static_cast<uint64_t>(min) + result);
  235|  6.18M|}

LLVMFuzzerTestOneInput:
  213|  5.20k|{
  214|  5.20k|    test_one_input({data, size});
  215|  5.20k|    return 0;
  216|  5.20k|}
fuzz.cpp:_ZL14test_one_inputNSt3__14spanIKhLm18446744073709551615EEE:
   84|  5.20k|{
   85|  5.20k|    CheckGlobals check{};
   86|  5.20k|    (*Assert(g_test_one_input))(buffer);
  ------------------
  |  |  116|  5.20k|#define Assert(val) inline_assertion_check<true>(val, std::source_location::current(), #val)
  ------------------
   87|  5.20k|}

_Z25node_eviction_fuzz_targetNSt3__14spanIKhLm18446744073709551615EEE:
   19|  5.20k|{
   20|  5.20k|    FuzzedDataProvider fuzzed_data_provider{buffer.data(), buffer.size()};
   21|  5.20k|    std::vector<NodeEvictionCandidate> eviction_candidates;
   22|  1.54M|    LIMITED_WHILE (fuzzed_data_provider.ConsumeBool(), 10000) {
  ------------------
  |  |   23|  1.55M|    for (unsigned _count{limit}; (condition) && _count; --_count)
  |  |  ------------------
  |  |  |  Branch (23:34): [True: 1.54M, False: 5.20k]
  |  |  |  Branch (23:49): [True: 1.54M, False: 9]
  |  |  ------------------
  ------------------
   23|  1.54M|        eviction_candidates.push_back({
   24|  1.54M|            /*id=*/fuzzed_data_provider.ConsumeIntegral<NodeId>(),
   25|  1.54M|            /*m_connected=*/ConsumeTime(fuzzed_data_provider),
   26|  1.54M|            /*m_min_ping_time=*/ConsumeDuration<decltype(NodeEvictionCandidate::m_min_ping_time)>(fuzzed_data_provider, /*min=*/std::chrono::years{-1}, /*max=*/decltype(CNode::m_min_ping_time.load())::max()),
   27|  1.54M|            /*m_last_block_time=*/ConsumeTime(fuzzed_data_provider).time_since_epoch(),
   28|  1.54M|            /*m_last_tx_time=*/ConsumeTime(fuzzed_data_provider).time_since_epoch(),
   29|  1.54M|            /*fRelevantServices=*/fuzzed_data_provider.ConsumeBool(),
   30|  1.54M|            /*m_relay_txs=*/fuzzed_data_provider.ConsumeBool(),
   31|  1.54M|            /*fBloomFilter=*/fuzzed_data_provider.ConsumeBool(),
   32|  1.54M|            /*nKeyedNetGroup=*/fuzzed_data_provider.ConsumeIntegral<uint64_t>(),
   33|  1.54M|            /*prefer_evict=*/fuzzed_data_provider.ConsumeBool(),
   34|  1.54M|            /*m_is_local=*/fuzzed_data_provider.ConsumeBool(),
   35|  1.54M|            /*m_network=*/fuzzed_data_provider.PickValueInArray(ALL_NETWORKS),
   36|  1.54M|            /*m_noban=*/fuzzed_data_provider.ConsumeBool(),
   37|  1.54M|            /*m_conn_type=*/fuzzed_data_provider.PickValueInArray(ALL_CONNECTION_TYPES),
   38|  1.54M|        });
   39|  1.54M|    }
   40|       |    // Make a copy since eviction_candidates may be in some valid but otherwise
   41|       |    // indeterminate state after the SelectNodeToEvict(&&) call.
   42|  5.20k|    const std::vector<NodeEvictionCandidate> eviction_candidates_copy = eviction_candidates;
   43|  5.20k|    const std::optional<NodeId> node_to_evict = SelectNodeToEvict(std::move(eviction_candidates));
   44|  5.20k|    if (node_to_evict) {
  ------------------
  |  Branch (44:9): [True: 4.36k, False: 841]
  ------------------
   45|       |        assert(std::any_of(eviction_candidates_copy.begin(), eviction_candidates_copy.end(), [&node_to_evict](const NodeEvictionCandidate& eviction_candidate) { return *node_to_evict == eviction_candidate.id; }));
  ------------------
  |  Branch (45:9): [True: 4.36k, False: 0]
  ------------------
   46|  4.36k|    }
   47|  5.20k|}

_Z11ConsumeTimeR18FuzzedDataProviderRKNSt3__18optionalIlEES5_:
   35|  4.63M|{
   36|       |    // Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) disables mocktime.
   37|  4.63M|    static const int64_t time_min{ParseISO8601DateTime("2000-01-01T00:00:01Z").value()};
   38|  4.63M|    static const int64_t time_max{ParseISO8601DateTime("2100-12-31T23:59:59Z").value()};
   39|  4.63M|    return NodeSeconds{ConsumeDuration<std::chrono::seconds>(fuzzed_data_provider, min.value_or(time_min) * 1s, max.value_or(time_max) * 1s)};
   40|  4.63M|}

_Z15ConsumeDurationINSt3__16chrono8durationIxNS0_5ratioILl1ELl1000000EEEEEET_R18FuzzedDataProviderNS0_11common_typeIJS6_EE4typeESB_:
  169|  1.54M|{
  170|  1.54M|    return Dur{fuzzed_data_provider.ConsumeIntegralInRange(min.count(), max.count())};
  171|  1.54M|}
_Z15ConsumeDurationINSt3__16chrono8durationIxNS0_5ratioILl1ELl1EEEEEET_R18FuzzedDataProviderNS0_11common_typeIJS6_EE4typeESB_:
  169|  4.63M|{
  170|  4.63M|    return Dur{fuzzed_data_provider.ConsumeIntegralInRange(min.count(), max.count())};
  171|  4.63M|}

_ZN12CheckGlobalsC2Ev:
   59|  5.20k|CheckGlobals::CheckGlobals() : m_impl(std::make_unique<CheckGlobalsImpl>()) {}
_ZN12CheckGlobalsD2Ev:
   60|  5.21k|CheckGlobals::~CheckGlobals() = default;
_ZN16CheckGlobalsImplC2Ev:
   17|  5.20k|    {
   18|  5.20k|        g_used_g_prng = false;
   19|  5.20k|        g_seeded_g_prng_zero = false;
   20|  5.20k|        g_used_system_time = false;
   21|  5.20k|        SetMockTime(0s);
   22|  5.20k|        MockableSteadyClock::ClearMockTime();
   23|  5.20k|    }
_ZN16CheckGlobalsImplD2Ev:
   25|  5.21k|    {
   26|  5.21k|        if (g_used_g_prng && !g_seeded_g_prng_zero) {
  ------------------
  |  Branch (26:13): [True: 0, False: 5.21k]
  |  Branch (26:30): [True: 0, False: 0]
  ------------------
   27|      0|            std::cerr << "\n\n"
   28|      0|                         "The current fuzz target used the global random state.\n\n"
   29|       |
   30|      0|                         "This is acceptable, but requires the fuzz target to call \n"
   31|      0|                         "SeedRandomStateForTest(SeedRand::ZEROS) in the first line \n"
   32|      0|                         "of the FUZZ_TARGET function.\n\n"
   33|       |
   34|      0|                         "An alternative solution would be to avoid any use of globals.\n\n"
   35|       |
   36|      0|                         "Without a solution, fuzz instability and non-determinism can lead \n"
   37|      0|                         "to non-reproducible bugs or inefficient fuzzing.\n\n"
   38|      0|                      << std::endl;
   39|      0|            std::abort(); // Abort, because AFL may try to recover from a std::exit
   40|      0|        }
   41|       |
   42|  5.21k|        if (g_used_system_time) {
  ------------------
  |  Branch (42:13): [True: 0, False: 5.21k]
  ------------------
   43|      0|            std::cerr << "\n\n"
   44|      0|                         "The current fuzz target accessed system time.\n\n"
   45|       |
   46|      0|                         "This is acceptable, but requires the fuzz target to use \n"
   47|      0|                         "a FakeNodeClock, FakeSteadyClock or call \n"
   48|      0|                         "SetMockTime() at the \n" "beginning of processing the \n"
   49|      0|                         "fuzz input.\n\n"
   50|       |
   51|      0|                         "Without setting mock time, time-dependent behavior can lead \n"
   52|      0|                         "to non-reproducible bugs or inefficient fuzzing.\n\n"
   53|      0|                      << std::endl;
   54|      0|            std::abort();
   55|      0|        }
   56|  5.21k|    }

__gcov_reset:
   13|      2|extern "C" __attribute__((weak)) void __gcov_reset(void) {}

_ZN9base_blobILj256EE4dataEv:
   99|      2|    constexpr unsigned char* data() { return m_data.data(); }
_ZN9base_blobILj256EE4sizeEv:
  107|      2|    static constexpr unsigned int size() { return WIDTH; }

_ZN10btcsignals6signalIFvvENS_10null_valueEED2Ev:
  175|      6|    ~signal() = default;
_ZN10btcsignals6signalIFv20SynchronizationStatellbENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFv20SynchronizationStateRK11CBlockIndexdENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFvRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEibENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFvbENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFviENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFvRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFbRK13bilingual_strRKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEjENS_6any_ofEED2Ev:
  175|      2|    ~signal() = default;
_ZN10btcsignals6signalIFvRK13bilingual_strjENS_10null_valueEED2Ev:
  175|      2|    ~signal() = default;

_Z22inline_assertion_checkILb1ERPKNSt3__18functionIFvNS0_4spanIKhLm18446744073709551615EEEEEEEOT0_SB_RKNS0_15source_locationENS0_17basic_string_viewIcNS0_11char_traitsIcEEEE:
   90|  5.20k|{
   91|  5.20k|    if (IS_ASSERT || std::is_constant_evaluated() || G_ABORT_ON_FAILED_ASSUME) {
  ------------------
  |  Branch (91:9): [True: 5.20k, Folded]
  |  Branch (91:22): [Folded, False: 0]
  |  Branch (91:54): [True: 0, Folded]
  ------------------
   92|  5.20k|        if (!val) {
  ------------------
  |  Branch (92:13): [True: 0, False: 5.20k]
  ------------------
   93|      0|            assertion_fail(loc, assertion);
   94|      0|        }
   95|  5.20k|    }
   96|  5.20k|    return std::forward<T>(val);
   97|  5.20k|}
_Z22inline_assertion_checkILb1EbEOT0_S1_RKNSt3__115source_locationENS2_17basic_string_viewIcNS2_11char_traitsIcEEEE:
   90|  5.20k|{
   91|  5.20k|    if (IS_ASSERT || std::is_constant_evaluated() || G_ABORT_ON_FAILED_ASSUME) {
  ------------------
  |  Branch (91:9): [True: 5.20k, Folded]
  |  Branch (91:22): [Folded, False: 0]
  |  Branch (91:54): [True: 0, Folded]
  ------------------
   92|  5.20k|        if (!val) {
  ------------------
  |  Branch (92:13): [True: 0, False: 5.20k]
  ------------------
   93|      0|            assertion_fail(loc, assertion);
   94|      0|        }
   95|  5.20k|    }
   96|  5.20k|    return std::forward<T>(val);
   97|  5.20k|}
_Z22inline_assertion_checkILb0EbEOT0_S1_RKNSt3__115source_locationENS2_17basic_string_viewIcNS2_11char_traitsIcEEEE:
   90|     10|{
   91|     10|    if (IS_ASSERT || std::is_constant_evaluated() || G_ABORT_ON_FAILED_ASSUME) {
  ------------------
  |  Branch (91:9): [Folded, False: 0]
  |  Branch (91:22): [Folded, False: 0]
  |  Branch (91:54): [True: 0, Folded]
  ------------------
   92|     10|        if (!val) {
  ------------------
  |  Branch (92:13): [True: 0, False: 10]
  ------------------
   93|      0|            assertion_fail(loc, assertion);
   94|      0|        }
   95|     10|    }
   96|     10|    return std::forward<T>(val);
   97|     10|}

_Z10ToIntegralIhENSt3__18optionalIT_EENS0_17basic_string_viewIcNS0_11char_traitsIcEEEEm:
  181|     10|{
  182|     10|    static_assert(std::is_integral_v<T>);
  183|     10|    T result;
  184|     10|    const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result, base);
  185|     10|    if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) {
  ------------------
  |  Branch (185:9): [True: 0, False: 10]
  |  Branch (185:57): [True: 0, False: 10]
  ------------------
  186|      0|        return std::nullopt;
  187|      0|    }
  188|     10|    return result;
  189|     10|}
_Z10ToIntegralItENSt3__18optionalIT_EENS0_17basic_string_viewIcNS0_11char_traitsIcEEEEm:
  181|      2|{
  182|      2|    static_assert(std::is_integral_v<T>);
  183|      2|    T result;
  184|      2|    const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result, base);
  185|      2|    if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) {
  ------------------
  |  Branch (185:9): [True: 0, False: 2]
  |  Branch (185:57): [True: 0, False: 2]
  ------------------
  186|      0|        return std::nullopt;
  187|      0|    }
  188|      2|    return result;
  189|      2|}

_ZN16CThreadInterruptD2Ev:
   32|      4|    virtual ~CThreadInterrupt() = default;

_ZN10ThreadPoolD2Ev:
   93|     10|    {
   94|     10|        Stop(); // In case it hasn't been stopped.
   95|     10|    }
_ZN10ThreadPool4StopEv:
  129|     10|    {
  130|       |        // Notify workers and join them
  131|     10|        std::vector<std::thread> threads_to_join;
  132|     10|        {
  133|     10|            LOCK(m_mutex);
  ------------------
  |  |  268|     10|#define LOCK(cs) UniqueLock BITCOIN_UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
  |  |  ------------------
  |  |  |  |   11|     10|#define BITCOIN_UNIQUE_NAME(name) PASTE2(name, __COUNTER__)
  |  |  |  |  ------------------
  |  |  |  |  |  |    9|     10|#define PASTE2(x, y) PASTE(x, y)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |    8|     10|#define PASTE(x, y) x ## y
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  134|       |            // Ensure Stop() is not called from a worker thread while workers are still registered,
  135|       |            // otherwise a self-join deadlock would occur.
  136|     10|            auto id = std::this_thread::get_id();
  137|     10|            for (const auto& worker : m_workers) assert(worker.get_id() != id);
  ------------------
  |  Branch (137:37): [True: 0, False: 10]
  |  Branch (137:50): [True: 0, False: 0]
  ------------------
  138|       |            // Early shutdown to return right away on any concurrent Submit() call
  139|     10|            m_interrupt = true;
  140|     10|            threads_to_join.swap(m_workers);
  141|     10|        }
  142|      0|        m_cv.notify_all();
  143|       |        // Help draining queue
  144|     10|        while (ProcessTask()) {}
  ------------------
  |  Branch (144:16): [True: 0, False: 10]
  ------------------
  145|       |        // Free resources
  146|     10|        for (auto& worker : threads_to_join) worker.join();
  ------------------
  |  Branch (146:27): [True: 0, False: 10]
  ------------------
  147|       |
  148|       |        // Since we currently wait for tasks completion, sanity-check empty queue
  149|     10|        LOCK(m_mutex);
  ------------------
  |  |  268|     10|#define LOCK(cs) UniqueLock BITCOIN_UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
  |  |  ------------------
  |  |  |  |   11|     10|#define BITCOIN_UNIQUE_NAME(name) PASTE2(name, __COUNTER__)
  |  |  |  |  ------------------
  |  |  |  |  |  |    9|     10|#define PASTE2(x, y) PASTE(x, y)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |    8|     10|#define PASTE(x, y) x ## y
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  150|     10|        Assume(m_work_queue.empty());
  ------------------
  |  |  128|     10|#define Assume(val) inline_assertion_check<false>(val, std::source_location::current(), #val)
  ------------------
  151|       |        // Re-allow Start() now that all workers have exited
  152|     10|        m_interrupt = false;
  153|     10|    }
_ZN10ThreadPool11ProcessTaskEv:
  244|     10|    {
  245|     10|        std::packaged_task<void()> task;
  246|     10|        {
  247|     10|            LOCK(m_mutex);
  ------------------
  |  |  268|     10|#define LOCK(cs) UniqueLock BITCOIN_UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__)
  |  |  ------------------
  |  |  |  |   11|     10|#define BITCOIN_UNIQUE_NAME(name) PASTE2(name, __COUNTER__)
  |  |  |  |  ------------------
  |  |  |  |  |  |    9|     10|#define PASTE2(x, y) PASTE(x, y)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |    8|     10|#define PASTE(x, y) x ## y
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  248|     10|            if (m_work_queue.empty()) return false;
  ------------------
  |  Branch (248:17): [True: 10, False: 0]
  ------------------
  249|       |
  250|       |            // Pop the task
  251|      0|            task = std::move(m_work_queue.front());
  252|      0|            m_work_queue.pop();
  253|      0|        }
  254|      0|        task();
  255|      0|        return true;
  256|     10|    }

_Z11SetMockTimeNSt3__16chrono8durationIxNS_5ratioILl1ELl1EEEEE:
   54|  5.20k|{
   55|  5.20k|    Assert(mock_time_in >= 0s);
  ------------------
  |  |  116|  5.20k|#define Assert(val) inline_assertion_check<true>(val, std::source_location::current(), #val)
  ------------------
   56|  5.20k|    g_mock_time.store(mock_time_in, std::memory_order_relaxed);
   57|  5.20k|}
_ZN19MockableSteadyClock13ClearMockTimeEv:
   84|  5.20k|{
   85|  5.20k|    g_mock_steady_time.store(0ms, std::memory_order_relaxed);
   86|  5.20k|}
_Z20ParseISO8601DateTimeNSt3__117basic_string_viewIcNS_11char_traitsIcEEEE:
  108|      2|{
  109|      2|    constexpr auto FMT_SIZE{std::string_view{"2000-01-01T01:01:01Z"}.size()};
  110|      2|    if (str.size() != FMT_SIZE || str[4] != '-' || str[7] != '-' || str[10] != 'T' || str[13] != ':' || str[16] != ':' || str[19] != 'Z') {
  ------------------
  |  Branch (110:9): [True: 0, False: 2]
  |  Branch (110:35): [True: 0, False: 2]
  |  Branch (110:52): [True: 0, False: 2]
  |  Branch (110:69): [True: 0, False: 2]
  |  Branch (110:87): [True: 0, False: 2]
  |  Branch (110:105): [True: 0, False: 2]
  |  Branch (110:123): [True: 0, False: 2]
  ------------------
  111|      0|        return {};
  112|      0|    }
  113|      2|    const auto year{ToIntegral<uint16_t>(str.substr(0, 4))};
  114|      2|    const auto month{ToIntegral<uint8_t>(str.substr(5, 2))};
  115|      2|    const auto day{ToIntegral<uint8_t>(str.substr(8, 2))};
  116|      2|    const auto hour{ToIntegral<uint8_t>(str.substr(11, 2))};
  117|      2|    const auto min{ToIntegral<uint8_t>(str.substr(14, 2))};
  118|      2|    const auto sec{ToIntegral<uint8_t>(str.substr(17, 2))};
  119|      2|    if (!year || !month || !day || !hour || !min || !sec) {
  ------------------
  |  Branch (119:9): [True: 0, False: 2]
  |  Branch (119:18): [True: 0, False: 2]
  |  Branch (119:28): [True: 0, False: 2]
  |  Branch (119:36): [True: 0, False: 2]
  |  Branch (119:45): [True: 0, False: 2]
  |  Branch (119:53): [True: 0, False: 2]
  ------------------
  120|      0|        return {};
  121|      0|    }
  122|      2|    const std::chrono::year_month_day ymd{std::chrono::year{*year}, std::chrono::month{*month}, std::chrono::day{*day}};
  123|      2|    if (!ymd.ok()) {
  ------------------
  |  Branch (123:9): [True: 0, False: 2]
  ------------------
  124|      0|        return {};
  125|      0|    }
  126|      2|    const auto time{std::chrono::hours{*hour} + std::chrono::minutes{*min} + std::chrono::seconds{*sec}};
  127|      2|    const auto tp{std::chrono::sys_days{ymd} + time};
  128|      2|    return int64_t{TicksSinceEpoch<std::chrono::seconds>(tp)};
  129|      2|}

_Z5TicksINSt3__16chrono8durationIxNS0_5ratioILl1ELl1EEEEES5_EDaT0_:
   83|      2|{
   84|      2|    return std::chrono::duration_cast<Dur1>(d).count();
   85|      2|}
_Z15TicksSinceEpochINSt3__16chrono8durationIxNS0_5ratioILl1ELl1EEEEENS1_10time_pointINS1_12system_clockES5_EEEDaT0_:
   94|      2|{
   95|      2|    return Ticks<Duration>(t.time_since_epoch());
   96|      2|}

_ZN19WalletInitInterfaceD2Ev:
   25|      2|    virtual ~WalletInitInterface() = default;

