| 1685 | } |
| 1686 | |
| 1687 | void PeerManagerImpl::FinalizeNode(const CNode& node) |
| 1688 | { |
| 1689 | NodeId nodeid = node.GetId(); |
| 1690 | { |
| 1691 | LOCK(cs_main); |
| 1692 | { |
| 1693 | // We remove the PeerRef from g_peer_map here, but we don't always |
| 1694 | // destruct the Peer. Sometimes another thread is still holding a |
| 1695 | // PeerRef, so the refcount is >= 1. Be careful not to do any |
| 1696 | // processing here that assumes Peer won't be changed before it's |
| 1697 | // destructed. |
| 1698 | PeerRef peer = RemovePeer(nodeid); |
| 1699 | assert(peer != nullptr); |
| 1700 | m_wtxid_relay_peers -= peer->m_wtxid_relay; |
| 1701 | assert(m_wtxid_relay_peers >= 0); |
| 1702 | } |
| 1703 | CNodeState *state = State(nodeid); |
| 1704 | assert(state != nullptr); |
| 1705 | |
| 1706 | if (state->fSyncStarted) |
| 1707 | nSyncStarted--; |
| 1708 | |
| 1709 | for (const QueuedBlock& entry : state->vBlocksInFlight) { |
| 1710 | auto range = mapBlocksInFlight.equal_range(entry.pindex->GetBlockHash()); |
| 1711 | while (range.first != range.second) { |
| 1712 | auto [node_id, list_it] = range.first->second; |
| 1713 | if (node_id != nodeid) { |
| 1714 | range.first++; |
| 1715 | } else { |
| 1716 | range.first = mapBlocksInFlight.erase(range.first); |
| 1717 | } |
| 1718 | } |
| 1719 | } |
| 1720 | { |
| 1721 | LOCK(m_tx_download_mutex); |
| 1722 | m_txdownloadman.DisconnectedPeer(nodeid); |
| 1723 | } |
| 1724 | if (m_txreconciliation) m_txreconciliation->ForgetPeer(nodeid); |
| 1725 | m_num_preferred_download_peers -= state->fPreferredDownload; |
| 1726 | m_peers_downloading_from -= (!state->vBlocksInFlight.empty()); |
| 1727 | assert(m_peers_downloading_from >= 0); |
| 1728 | m_outbound_peers_with_protect_from_disconnect -= state->m_chain_sync.m_protect; |
| 1729 | assert(m_outbound_peers_with_protect_from_disconnect >= 0); |
| 1730 | |
| 1731 | m_node_states.erase(nodeid); |
| 1732 | |
| 1733 | if (m_node_states.empty()) { |
| 1734 | // Do a consistency check after the last peer is removed. |
| 1735 | assert(mapBlocksInFlight.empty()); |
| 1736 | assert(m_num_preferred_download_peers == 0); |
| 1737 | assert(m_peers_downloading_from == 0); |
| 1738 | assert(m_outbound_peers_with_protect_from_disconnect == 0); |
| 1739 | assert(m_wtxid_relay_peers == 0); |
| 1740 | WITH_LOCK(m_tx_download_mutex, m_txdownloadman.CheckIsEmpty()); |
| 1741 | } |
| 1742 | } // cs_main |
| 1743 | if (node.fSuccessfullyConnected && |
| 1744 | !node.IsBlockOnlyConn() && !node.IsPrivateBroadcastConn() && !node.IsInboundConn()) { |
no test coverage detected