@@ -127,6 +127,10 @@ namespace {
127
127
/* * Number of outbound peers with m_chain_sync.m_protect. */
128
128
int g_outbound_peers_with_protect_from_disconnect = 0 ;
129
129
130
+
131
+ /* * When our tip was last updated. */
132
+ int64_t g_last_tip_update = 0 ;
133
+
130
134
/* * Relay map, protected by cs_main. */
131
135
typedef std::map<uint256, CTransactionRef> MapRelay;
132
136
MapRelay mapRelay;
@@ -231,6 +235,9 @@ struct CNodeState {
231
235
232
236
ChainSyncTimeoutState m_chain_sync;
233
237
238
+ // ! Time of last new block announcement
239
+ int64_t m_last_block_announcement;
240
+
234
241
CNodeState (CAddress addrIn, std::string addrNameIn) : address(addrIn), name(addrNameIn) {
235
242
fCurrentlyConnected = false ;
236
243
nMisbehavior = 0 ;
@@ -254,6 +261,7 @@ struct CNodeState {
254
261
fWantsCmpctWitness = false ;
255
262
fSupportsDesiredCmpctVersion = false ;
256
263
m_chain_sync = { 0 , nullptr , false , false };
264
+ m_last_block_announcement = 0 ;
257
265
}
258
266
};
259
267
@@ -797,6 +805,8 @@ void PeerLogicValidation::BlockConnected(const std::shared_ptr<const CBlock>& pb
797
805
}
798
806
LogPrint (BCLog::MEMPOOL, " Erased %d orphan tx included or conflicted by block\n " , nErased);
799
807
}
808
+
809
+ g_last_tip_update = GetTime ();
800
810
}
801
811
802
812
// All of the following cache a recent block, and are protected by cs_most_recent_block
@@ -1215,6 +1225,7 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
1215
1225
return true ;
1216
1226
}
1217
1227
1228
+ bool received_new_header = false ;
1218
1229
const CBlockIndex *pindexLast = nullptr ;
1219
1230
{
1220
1231
LOCK (cs_main);
@@ -1255,6 +1266,12 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
1255
1266
}
1256
1267
hashLastBlock = header.GetHash ();
1257
1268
}
1269
+
1270
+ // If we don't have the last header, then they'll have given us
1271
+ // something new (if these headers are valid).
1272
+ if (mapBlockIndex.find (hashLastBlock) == mapBlockIndex.end ()) {
1273
+ received_new_header = true ;
1274
+ }
1258
1275
}
1259
1276
1260
1277
CValidationState state;
@@ -1319,6 +1336,10 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
1319
1336
// because it is set in UpdateBlockAvailability. Some nullptr checks
1320
1337
// are still present, however, as belt-and-suspenders.
1321
1338
1339
+ if (received_new_header && pindexLast->nChainWork > chainActive.Tip ()->nChainWork ) {
1340
+ nodestate->m_last_block_announcement = GetTime ();
1341
+ }
1342
+
1322
1343
if (nCount == MAX_HEADERS_RESULTS) {
1323
1344
// Headers message had its maximum size; the peer may have more headers.
1324
1345
// TODO: optimize: if pindexLast is an ancestor of chainActive.Tip or pindexBestHeader, continue
@@ -2219,6 +2240,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2219
2240
CBlockHeaderAndShortTxIDs cmpctblock;
2220
2241
vRecv >> cmpctblock;
2221
2242
2243
+ bool received_new_header = false ;
2244
+
2222
2245
{
2223
2246
LOCK (cs_main);
2224
2247
@@ -2228,6 +2251,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2228
2251
connman->PushMessage (pfrom, msgMaker.Make (NetMsgType::GETHEADERS, chainActive.GetLocator (pindexBestHeader), uint256 ()));
2229
2252
return true ;
2230
2253
}
2254
+
2255
+ if (mapBlockIndex.find (cmpctblock.header .GetHash ()) == mapBlockIndex.end ()) {
2256
+ received_new_header = true ;
2257
+ }
2231
2258
}
2232
2259
2233
2260
const CBlockIndex *pindex = nullptr ;
@@ -2266,6 +2293,14 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2266
2293
assert (pindex);
2267
2294
UpdateBlockAvailability (pfrom->GetId (), pindex->GetBlockHash ());
2268
2295
2296
+ CNodeState *nodestate = State (pfrom->GetId ());
2297
+
2298
+ // If this was a new header with more work than our tip, update the
2299
+ // peer's last block announcement time
2300
+ if (received_new_header && pindex->nChainWork > chainActive.Tip ()->nChainWork ) {
2301
+ nodestate->m_last_block_announcement = GetTime ();
2302
+ }
2303
+
2269
2304
std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find (pindex->GetBlockHash ());
2270
2305
bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end ();
2271
2306
@@ -2288,8 +2323,6 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2288
2323
if (!fAlreadyInFlight && !CanDirectFetch (chainparams.GetConsensus ()))
2289
2324
return true ;
2290
2325
2291
- CNodeState *nodestate = State (pfrom->GetId ());
2292
-
2293
2326
if (IsWitnessEnabled (pindex->pprev , chainparams.GetConsensus ()) && !nodestate->fSupportsDesiredCmpctVersion ) {
2294
2327
// Don't bother trying to process compact blocks from v1 peers
2295
2328
// after segwit activates.
0 commit comments