Track tip update time and last new block announcement from each peer

Github-Pull: #11560
Rebased-From: db32a65897
This commit is contained in:
Suhas Daftuar 2017-10-23 13:59:07 -04:00 committed by MarcoFalke
parent 49bf090185
commit 459f2db425
1 changed files with 35 additions and 2 deletions

View File

@ -119,6 +119,10 @@ namespace {
/** Number of outbound peers with m_chain_sync.m_protect. */ /** Number of outbound peers with m_chain_sync.m_protect. */
int g_outbound_peers_with_protect_from_disconnect = 0; int g_outbound_peers_with_protect_from_disconnect = 0;
/** When our tip was last updated. */
int64_t g_last_tip_update = 0;
/** Relay map, protected by cs_main. */ /** Relay map, protected by cs_main. */
typedef std::map<uint256, CTransactionRef> MapRelay; typedef std::map<uint256, CTransactionRef> MapRelay;
MapRelay mapRelay; MapRelay mapRelay;
@ -223,6 +227,9 @@ struct CNodeState {
ChainSyncTimeoutState m_chain_sync; ChainSyncTimeoutState m_chain_sync;
//! Time of last new block announcement
int64_t m_last_block_announcement;
CNodeState(CAddress addrIn, std::string addrNameIn) : address(addrIn), name(addrNameIn) { CNodeState(CAddress addrIn, std::string addrNameIn) : address(addrIn), name(addrNameIn) {
fCurrentlyConnected = false; fCurrentlyConnected = false;
nMisbehavior = 0; nMisbehavior = 0;
@ -246,6 +253,7 @@ struct CNodeState {
fWantsCmpctWitness = false; fWantsCmpctWitness = false;
fSupportsDesiredCmpctVersion = false; fSupportsDesiredCmpctVersion = false;
m_chain_sync = { 0, nullptr, false, false }; m_chain_sync = { 0, nullptr, false, false };
m_last_block_announcement = 0;
} }
}; };
@ -779,6 +787,8 @@ void PeerLogicValidation::BlockConnected(const std::shared_ptr<const CBlock>& pb
} }
LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx included or conflicted by block\n", nErased); LogPrint(BCLog::MEMPOOL, "Erased %d orphan tx included or conflicted by block\n", nErased);
} }
g_last_tip_update = GetTime();
} }
// All of the following cache a recent block, and are protected by cs_most_recent_block // All of the following cache a recent block, and are protected by cs_most_recent_block
@ -1203,6 +1213,7 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
return true; return true;
} }
bool received_new_header = false;
const CBlockIndex *pindexLast = nullptr; const CBlockIndex *pindexLast = nullptr;
{ {
LOCK(cs_main); LOCK(cs_main);
@ -1243,6 +1254,12 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
} }
hashLastBlock = header.GetHash(); hashLastBlock = header.GetHash();
} }
// If we don't have the last header, then they'll have given us
// something new (if these headers are valid).
if (mapBlockIndex.find(hashLastBlock) == mapBlockIndex.end()) {
received_new_header = true;
}
} }
CValidationState state; CValidationState state;
@ -1307,6 +1324,10 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
// because it is set in UpdateBlockAvailability. Some nullptr checks // because it is set in UpdateBlockAvailability. Some nullptr checks
// are still present, however, as belt-and-suspenders. // are still present, however, as belt-and-suspenders.
if (received_new_header && pindexLast->nChainWork > chainActive.Tip()->nChainWork) {
nodestate->m_last_block_announcement = GetTime();
}
if (nCount == MAX_HEADERS_RESULTS) { if (nCount == MAX_HEADERS_RESULTS) {
// Headers message had its maximum size; the peer may have more headers. // Headers message had its maximum size; the peer may have more headers.
// TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue // TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
@ -2197,6 +2218,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
CBlockHeaderAndShortTxIDs cmpctblock; CBlockHeaderAndShortTxIDs cmpctblock;
vRecv >> cmpctblock; vRecv >> cmpctblock;
bool received_new_header = false;
{ {
LOCK(cs_main); LOCK(cs_main);
@ -2206,6 +2229,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256())); connman->PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256()));
return true; return true;
} }
if (mapBlockIndex.find(cmpctblock.header.GetHash()) == mapBlockIndex.end()) {
received_new_header = true;
}
} }
const CBlockIndex *pindex = nullptr; const CBlockIndex *pindex = nullptr;
@ -2244,6 +2271,14 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
assert(pindex); assert(pindex);
UpdateBlockAvailability(pfrom->GetId(), pindex->GetBlockHash()); UpdateBlockAvailability(pfrom->GetId(), pindex->GetBlockHash());
CNodeState *nodestate = State(pfrom->GetId());
// If this was a new header with more work than our tip, update the
// peer's last block announcement time
if (received_new_header && pindex->nChainWork > chainActive.Tip()->nChainWork) {
nodestate->m_last_block_announcement = GetTime();
}
std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->GetBlockHash()); std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->GetBlockHash());
bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end(); bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();
@ -2266,8 +2301,6 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
if (!fAlreadyInFlight && !CanDirectFetch(chainparams.GetConsensus())) if (!fAlreadyInFlight && !CanDirectFetch(chainparams.GetConsensus()))
return true; return true;
CNodeState *nodestate = State(pfrom->GetId());
if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) { if (IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus()) && !nodestate->fSupportsDesiredCmpctVersion) {
// Don't bother trying to process compact blocks from v1 peers // Don't bother trying to process compact blocks from v1 peers
// after segwit activates. // after segwit activates.