| 1232 | } |
| 1233 | |
| 1234 | void PeerManagerImpl::FinalizeNode(const CNode& node) |
| 1235 | { |
| 1236 | NodeId nodeid = node.GetId(); |
| 1237 | int misbehavior{0}; |
| 1238 | { |
| 1239 | LOCK(cs_main); |
| 1240 | { |
| 1241 | // We remove the PeerRef from g_peer_map here, but we don't always |
| 1242 | // destruct the Peer. Sometimes another thread is still holding a |
| 1243 | // PeerRef, so the refcount is >= 1. Be careful not to do any |
| 1244 | // processing here that assumes Peer won't be changed before it's |
| 1245 | // destructed. |
| 1246 | PeerRef peer = RemovePeer(nodeid); |
| 1247 | assert(peer != nullptr); |
| 1248 | misbehavior = WITH_LOCK(peer->m_misbehavior_mutex, return peer->m_misbehavior_score); |
| 1249 | } |
| 1250 | CNodeState *state = State(nodeid); |
| 1251 | assert(state != nullptr); |
| 1252 | |
| 1253 | if (state->fSyncStarted) |
| 1254 | nSyncStarted--; |
| 1255 | |
| 1256 | for (const QueuedBlock& entry : state->vBlocksInFlight) { |
| 1257 | mapBlocksInFlight.erase(entry.pindex->GetBlockHash()); |
| 1258 | } |
| 1259 | WITH_LOCK(g_cs_orphans, m_orphanage.EraseForPeer(nodeid)); |
| 1260 | m_txrequest.DisconnectedPeer(nodeid); |
| 1261 | nPreferredDownload -= state->fPreferredDownload; |
| 1262 | m_peers_downloading_from -= (state->nBlocksInFlight != 0); |
| 1263 | assert(m_peers_downloading_from >= 0); |
| 1264 | m_outbound_peers_with_protect_from_disconnect -= state->m_chain_sync.m_protect; |
| 1265 | assert(m_outbound_peers_with_protect_from_disconnect >= 0); |
| 1266 | m_wtxid_relay_peers -= state->m_wtxid_relay; |
| 1267 | assert(m_wtxid_relay_peers >= 0); |
| 1268 | |
| 1269 | mapNodeState.erase(nodeid); |
| 1270 | |
| 1271 | if (mapNodeState.empty()) { |
| 1272 | // Do a consistency check after the last peer is removed. |
| 1273 | assert(mapBlocksInFlight.empty()); |
| 1274 | assert(nPreferredDownload == 0); |
| 1275 | assert(m_peers_downloading_from == 0); |
| 1276 | assert(m_outbound_peers_with_protect_from_disconnect == 0); |
| 1277 | assert(m_wtxid_relay_peers == 0); |
| 1278 | assert(m_txrequest.Size() == 0); |
| 1279 | assert(m_orphanage.Size() == 0); |
| 1280 | } |
| 1281 | } // cs_main |
| 1282 | if (node.fSuccessfullyConnected && misbehavior == 0 && |
| 1283 | !node.IsBlockOnlyConn() && !node.IsInboundConn()) { |
| 1284 | // Only change visible addrman state for full outbound peers. We don't |
| 1285 | // call Connected() for feeler connections since they don't have |
| 1286 | // fSuccessfullyConnected set. |
| 1287 | m_addrman.Connected(node.addr); |
| 1288 | } |
| 1289 | LogPrint(BCLog::NET, "Cleared nodestate for peer=%d\n", nodeid); |
| 1290 | } |
| 1291 | |