* Given receipt of headers from a peer ending in last_header, along with * whether that header was new and whether the headers message was full, * update the state we keep for the peer. */
| 2936 | * update the state we keep for the peer. |
| 2937 | */ |
| 2938 | void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom, Peer& peer, |
| 2939 | const CBlockIndex& last_header, bool received_new_header, bool may_have_more_headers) |
| 2940 | { |
| 2941 | LOCK(cs_main); |
| 2942 | CNodeState *nodestate = State(pfrom.GetId()); |
| 2943 | |
| 2944 | UpdateBlockAvailability(pfrom.GetId(), last_header.GetBlockHash()); |
| 2945 | |
| 2946 | // From here, pindexBestKnownBlock should be guaranteed to be non-null, |
| 2947 | // because it is set in UpdateBlockAvailability. Some nullptr checks |
| 2948 | // are still present, however, as belt-and-suspenders. |
| 2949 | |
| 2950 | if (received_new_header && last_header.nChainWork > m_chainman.ActiveChain().Tip()->nChainWork) { |
| 2951 | nodestate->m_last_block_announcement = GetTime(); |
| 2952 | } |
| 2953 | |
| 2954 | // If we're in IBD, we want outbound peers that will serve us a useful |
| 2955 | // chain. Disconnect peers that are on chains with insufficient work. |
| 2956 | if (m_chainman.IsInitialBlockDownload() && !may_have_more_headers) { |
| 2957 | // If the peer has no more headers to give us, then we know we have |
| 2958 | // their tip. |
| 2959 | if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < m_chainman.MinimumChainWork()) { |
| 2960 | // This peer has too little work on their headers chain to help |
| 2961 | // us sync -- disconnect if it is an outbound disconnection |
| 2962 | // candidate. |
| 2963 | // Note: We compare their tip to the minimum chain work (rather than |
| 2964 | // m_chainman.ActiveChain().Tip()) because we won't start block download |
| 2965 | // until we have a headers chain that has at least |
| 2966 | // the minimum chain work, even if a peer has a chain past our tip, |
| 2967 | // as an anti-DoS measure. |
| 2968 | if (pfrom.IsOutboundOrBlockRelayConn()) { |
| 2969 | LogInfo("outbound peer headers chain has insufficient work, %s", pfrom.DisconnectMsg()); |
| 2970 | pfrom.fDisconnect = true; |
| 2971 | } |
| 2972 | } |
| 2973 | } |
| 2974 | |
| 2975 | // If this is an outbound full-relay peer, check to see if we should protect |
| 2976 | // it from the bad/lagging chain logic. |
| 2977 | // Note that outbound block-relay peers are excluded from this protection, and |
| 2978 | // thus always subject to eviction under the bad/lagging chain logic. |
| 2979 | // See ChainSyncTimeoutState. |
| 2980 | if (!pfrom.fDisconnect && pfrom.IsFullOutboundConn() && nodestate->pindexBestKnownBlock != nullptr) { |
| 2981 | if (m_outbound_peers_with_protect_from_disconnect < MAX_OUTBOUND_PEERS_TO_PROTECT_FROM_DISCONNECT && nodestate->pindexBestKnownBlock->nChainWork >= m_chainman.ActiveChain().Tip()->nChainWork && !nodestate->m_chain_sync.m_protect) { |
| 2982 | LogDebug(BCLog::NET, "Protecting outbound peer=%d from eviction\n", pfrom.GetId()); |
| 2983 | nodestate->m_chain_sync.m_protect = true; |
| 2984 | ++m_outbound_peers_with_protect_from_disconnect; |
| 2985 | } |
| 2986 | } |
| 2987 | } |
| 2988 | |
| 2989 | void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer, |
| 2990 | std::vector<CBlockHeader>&& headers, |
nothing calls this directly
no test coverage detected