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

Code before:
    // Schedule next run for 10-15 minutes in the future.
    // We add randomness on every cycle to avoid the possibility of P2P fingerprinting.
    const auto delta = 10min + FastRandomContext().randrange<std::chrono::milliseconds>(5min);
    scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta);
}

void PeerManagerImpl::ReattemptPrivateBroadcast(CScheduler& scheduler)
{
    // Remove stale transactions that are no longer relevant (e.g. already in
    // the mempool or mined) and count the remaining ones.
    size_t num_for_rebroadcast{0};
    const auto stale_txs = m_tx_for_private_broadcast.GetStale();
    if (!stale_txs.empty()) {
        LOCK(cs_main);
        for (const auto& stale_tx : stale_txs) {
            auto mempool_acceptable = m_chainman.ProcessTransaction(stale_tx, /*test_accept=*/true);
            if (mempool_acceptable.m_result_type == MempoolAcceptResult::ResultType::VALID) {
                LogDebug(BCLog::PRIVBROADCAST,
                         "Reattempting broadcast of stale txid=%s wtxid=%s",
                         stale_tx->GetHash().ToString(), stale_tx->GetWitnessHash().ToString());
                ++num_for_rebroadcast;
            } else {
                LogDebug(BCLog::PRIVBROADCAST, "Giving up broadcast attempts for txid=%s wtxid=%s: %s",
                         stale_tx->GetHash().ToString(), stale_tx->GetWitnessHash().ToString(),
                         mempool_acceptable.m_state.ToString());
                m_tx_for_private_broadcast.StopBroadcasting(stale_tx, mempool_acceptable.m_state.ToString());
            }
        }

        // This could overshoot, but that is ok - we will open some private connections in vain.
        m_connman.m_private_broadcast.NumToOpenAdd(num_for_rebroadcast);
    }

    const auto delta{2min + FastRandomContext().randrange<std::chrono::milliseconds>(1min)};
    scheduler.scheduleFromNow([&] { ReattemptPrivateBroadcast(scheduler); }, delta);
}

void PeerManagerImpl::FinalizeNode(const CNode& node)
{
    NodeId nodeid = node.GetId();
    {
    LOCK(cs_main);
    {
        // We remove the PeerRef from g_peer_map here, but we don't always
        // destruct the Peer. Sometimes another thread is still holding a
        // PeerRef, so the refcount is >= 1. Be careful not to do any
        // processing here that assumes Peer won't be changed before it's
        // destructed.
        PeerRef peer = RemovePeer(nodeid);
        assert(peer != nullptr);
        m_wtxid_relay_peers -= peer->m_wtxid_relay;

Review comment (bug):
`m_state.ToString()` could be quite short, e.g. "tx-size", "transaction failed" or "bad-txns-inputs-missingorspent", etc. Maybe prefix this with "Not acceptable to our mempool: %s".

Code after:
        }
    }

    // Schedule next run for 10-15 minutes in the future.
    // We add randomness on every cycle to avoid the possibility of P2P fingerprinting.
    const auto delta = 10min + FastRandomContext().randrange<std::chrono::milliseconds>(5min);
    scheduler.scheduleFromNow([&] { ReattemptInitialBroadcast(scheduler); }, delta);
}

void PeerManagerImpl::ReattemptPrivateBroadcast(CScheduler& scheduler)
{
    // Remove stale transactions that are no longer relevant (e.g. already in
    // the mempool or mined) and count the remaining ones.
    size_t num_for_rebroadcast{0};
    const auto stale_txs = m_tx_for_private_broadcast.GetStale();
    if (!stale_txs.empty()) {
        LOCK(cs_main);
        for (const auto& stale_tx : stale_txs) {
            auto mempool_acceptable = m_chainman.ProcessTransaction(stale_tx, /*test_accept=*/true);
            if (mempool_acceptable.m_result_type == MempoolAcceptResult::ResultType::VALID) {
                LogDebug(BCLog::PRIVBROADCAST,
                         "Reattempting broadcast of stale txid=%s wtxid=%s",
                         stale_tx->GetHash().ToString(), stale_tx->GetWitnessHash().ToString());
                ++num_for_rebroadcast;
            } else {
                LogDebug(BCLog::PRIVBROADCAST, "Giving up broadcast attempts for txid=%s wtxid=%s: %s",
                         stale_tx->GetHash().ToString(), stale_tx->GetWitnessHash().ToString(),
                         mempool_acceptable.m_state.ToString());
                m_tx_for_private_broadcast.Remove(stale_tx);
            }
        }

        // This could overshoot, but that is ok - we will open some private connections in vain.
        m_connman.m_private_broadcast.NumToOpenAdd(num_for_rebroadcast);
    }

    const auto delta{2min + FastRandomContext().randrange<std::chrono::milliseconds>(1min)};
    scheduler.scheduleFromNow([&] { ReattemptPrivateBroadcast(scheduler); }, delta);
}

void PeerManagerImpl::FinalizeNode(const CNode& node)
{
    NodeId nodeid = node.GetId();
    {
    LOCK(cs_main);
    {
        // We remove the PeerRef from g_peer_map here, but we don't always
        // destruct the Peer. Sometimes another thread is still holding a
        // PeerRef, so the refcount is >= 1. Be careful not to do any
        // processing here that assumes Peer won't be changed before it's
        // destructed.