mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
Move peer state updates from headers message into separate function
This commit is contained in:
parent
2b341db731
commit
6d95cd3e74
1 changed files with 64 additions and 53 deletions
|
@ -571,6 +571,8 @@ private:
|
|||
void FetchMoreHeaders(CNode& pfrom, const CBlockIndex *pindexLast, const Peer& peer);
|
||||
/** Potentially fetch blocks from this peer upon receipt of new headers tip */
|
||||
void HeadersDirectFetchBlocks(CNode& pfrom, const CBlockIndex* pindexLast);
|
||||
/** Update peer state based on received headers message */
|
||||
void UpdatePeerStateForReceivedHeaders(CNode& pfrom, const CBlockIndex *pindexLast, bool received_new_header, bool may_have_more_headers);
|
||||
|
||||
void SendBlockTransactions(CNode& pfrom, Peer& peer, const CBlock& block, const BlockTransactionsRequest& req);
|
||||
|
||||
|
@ -2345,6 +2347,67 @@ void PeerManagerImpl::HeadersDirectFetchBlocks(CNode& pfrom, const CBlockIndex*
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given receipt of headers from a peer ending in pindexLast, along with
|
||||
* whether that header was new and whether the headers message was full,
|
||||
* update the state we keep for the peer.
|
||||
*/
|
||||
void PeerManagerImpl::UpdatePeerStateForReceivedHeaders(CNode& pfrom,
|
||||
const CBlockIndex *pindexLast, bool received_new_header, bool may_have_more_headers)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
CNodeState *nodestate = State(pfrom.GetId());
|
||||
if (nodestate->nUnconnectingHeaders > 0) {
|
||||
LogPrint(BCLog::NET, "peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom.GetId(), nodestate->nUnconnectingHeaders);
|
||||
}
|
||||
nodestate->nUnconnectingHeaders = 0;
|
||||
|
||||
assert(pindexLast);
|
||||
UpdateBlockAvailability(pfrom.GetId(), pindexLast->GetBlockHash());
|
||||
|
||||
// From here, pindexBestKnownBlock should be guaranteed to be non-null,
|
||||
// because it is set in UpdateBlockAvailability. Some nullptr checks
|
||||
// are still present, however, as belt-and-suspenders.
|
||||
|
||||
if (received_new_header && pindexLast->nChainWork > m_chainman.ActiveChain().Tip()->nChainWork) {
|
||||
nodestate->m_last_block_announcement = GetTime();
|
||||
}
|
||||
|
||||
// If we're in IBD, we want outbound peers that will serve us a useful
|
||||
// chain. Disconnect peers that are on chains with insufficient work.
|
||||
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && !may_have_more_headers) {
|
||||
// If the peer has no more headers to give us, then we know we have
|
||||
// their tip.
|
||||
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
|
||||
// This peer has too little work on their headers chain to help
|
||||
// us sync -- disconnect if it is an outbound disconnection
|
||||
// candidate.
|
||||
// Note: We compare their tip to nMinimumChainWork (rather than
|
||||
// m_chainman.ActiveChain().Tip()) because we won't start block download
|
||||
// until we have a headers chain that has at least
|
||||
// nMinimumChainWork, even if a peer has a chain past our tip,
|
||||
// as an anti-DoS measure.
|
||||
if (pfrom.IsOutboundOrBlockRelayConn()) {
|
||||
LogPrintf("Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.GetId());
|
||||
pfrom.fDisconnect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is an outbound full-relay peer, check to see if we should protect
|
||||
// it from the bad/lagging chain logic.
|
||||
// Note that outbound block-relay peers are excluded from this protection, and
|
||||
// thus always subject to eviction under the bad/lagging chain logic.
|
||||
// See ChainSyncTimeoutState.
|
||||
if (!pfrom.fDisconnect && pfrom.IsFullOutboundConn() && nodestate->pindexBestKnownBlock != nullptr) {
|
||||
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) {
|
||||
LogPrint(BCLog::NET, "Protecting outbound peer=%d from eviction\n", pfrom.GetId());
|
||||
nodestate->m_chain_sync.m_protect = true;
|
||||
++m_outbound_peers_with_protect_from_disconnect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
|
||||
const std::vector<CBlockHeader>& headers,
|
||||
bool via_compact_block)
|
||||
|
@ -2405,59 +2468,7 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer,
|
|||
FetchMoreHeaders(pfrom, pindexLast, peer);
|
||||
}
|
||||
|
||||
{
|
||||
LOCK(cs_main);
|
||||
CNodeState *nodestate = State(pfrom.GetId());
|
||||
if (nodestate->nUnconnectingHeaders > 0) {
|
||||
LogPrint(BCLog::NET, "peer=%d: resetting nUnconnectingHeaders (%d -> 0)\n", pfrom.GetId(), nodestate->nUnconnectingHeaders);
|
||||
}
|
||||
nodestate->nUnconnectingHeaders = 0;
|
||||
|
||||
assert(pindexLast);
|
||||
UpdateBlockAvailability(pfrom.GetId(), pindexLast->GetBlockHash());
|
||||
|
||||
// From here, pindexBestKnownBlock should be guaranteed to be non-null,
|
||||
// because it is set in UpdateBlockAvailability. Some nullptr checks
|
||||
// are still present, however, as belt-and-suspenders.
|
||||
|
||||
if (received_new_header && pindexLast->nChainWork > m_chainman.ActiveChain().Tip()->nChainWork) {
|
||||
nodestate->m_last_block_announcement = GetTime();
|
||||
}
|
||||
|
||||
// If we're in IBD, we want outbound peers that will serve us a useful
|
||||
// chain. Disconnect peers that are on chains with insufficient work.
|
||||
if (m_chainman.ActiveChainstate().IsInitialBlockDownload() && nCount != MAX_HEADERS_RESULTS) {
|
||||
// When nCount < MAX_HEADERS_RESULTS, we know we have no more
|
||||
// headers to fetch from this peer.
|
||||
if (nodestate->pindexBestKnownBlock && nodestate->pindexBestKnownBlock->nChainWork < nMinimumChainWork) {
|
||||
// This peer has too little work on their headers chain to help
|
||||
// us sync -- disconnect if it is an outbound disconnection
|
||||
// candidate.
|
||||
// Note: We compare their tip to nMinimumChainWork (rather than
|
||||
// m_chainman.ActiveChain().Tip()) because we won't start block download
|
||||
// until we have a headers chain that has at least
|
||||
// nMinimumChainWork, even if a peer has a chain past our tip,
|
||||
// as an anti-DoS measure.
|
||||
if (pfrom.IsOutboundOrBlockRelayConn()) {
|
||||
LogPrintf("Disconnecting outbound peer %d -- headers chain has insufficient work\n", pfrom.GetId());
|
||||
pfrom.fDisconnect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is an outbound full-relay peer, check to see if we should protect
|
||||
// it from the bad/lagging chain logic.
|
||||
// Note that outbound block-relay peers are excluded from this protection, and
|
||||
// thus always subject to eviction under the bad/lagging chain logic.
|
||||
// See ChainSyncTimeoutState.
|
||||
if (!pfrom.fDisconnect && pfrom.IsFullOutboundConn() && nodestate->pindexBestKnownBlock != nullptr) {
|
||||
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) {
|
||||
LogPrint(BCLog::NET, "Protecting outbound peer=%d from eviction\n", pfrom.GetId());
|
||||
nodestate->m_chain_sync.m_protect = true;
|
||||
++m_outbound_peers_with_protect_from_disconnect;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdatePeerStateForReceivedHeaders(pfrom, pindexLast, received_new_header, nCount == MAX_HEADERS_RESULTS);
|
||||
|
||||
// Consider immediately downloading blocks.
|
||||
HeadersDirectFetchBlocks(pfrom, pindexLast);
|
||||
|
|
Loading…
Reference in a new issue