Skip to content

Commit aa81564

Browse files
committed
Track peers' available blocks
1 parent a11f648 commit aa81564

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

src/main.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,10 @@ struct CNodeState {
207207
std::string name;
208208
// List of asynchronously-determined block rejections to notify this peer about.
209209
std::vector<CBlockReject> rejects;
210+
// The best known block we know this peer has announced.
211+
CBlockIndex *pindexBestKnownBlock;
212+
// The hash of the last unknown block this peer has announced.
213+
uint256 hashLastUnknownBlock;
210214
list<QueuedBlock> vBlocksInFlight;
211215
int nBlocksInFlight;
212216
list<uint256> vBlocksToDownload;
@@ -217,6 +221,8 @@ struct CNodeState {
217221
CNodeState() {
218222
nMisbehavior = 0;
219223
fShouldBan = false;
224+
pindexBestKnownBlock = NULL;
225+
hashLastUnknownBlock = uint256(0);
220226
nBlocksToDownload = 0;
221227
nBlocksInFlight = 0;
222228
nLastBlockReceive = 0;
@@ -313,6 +319,39 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256 &hash) {
313319
mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
314320
}
315321

322+
/** Check whether the last unknown block a peer advertized is not yet known. */
323+
void ProcessBlockAvailability(NodeId nodeid) {
324+
CNodeState *state = State(nodeid);
325+
assert(state != NULL);
326+
327+
if (state->hashLastUnknownBlock != 0) {
328+
map<uint256, CBlockIndex*>::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock);
329+
if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) {
330+
if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
331+
state->pindexBestKnownBlock = itOld->second;
332+
state->hashLastUnknownBlock = uint256(0);
333+
}
334+
}
335+
}
336+
337+
/** Update tracking information about which blocks a peer is assumed to have. */
338+
void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) {
339+
CNodeState *state = State(nodeid);
340+
assert(state != NULL);
341+
342+
ProcessBlockAvailability(nodeid);
343+
344+
map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(hash);
345+
if (it != mapBlockIndex.end() && it->second->nChainWork > 0) {
346+
// An actually better block was announced.
347+
if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork)
348+
state->pindexBestKnownBlock = it->second;
349+
} else {
350+
// An unknown block was announced; just assume that the latest one is the best one.
351+
state->hashLastUnknownBlock = hash;
352+
}
353+
}
354+
316355
} // anon namespace
317356

318357
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
@@ -321,6 +360,7 @@ bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats) {
321360
if (state == NULL)
322361
return false;
323362
stats.nMisbehavior = state->nMisbehavior;
363+
stats.nSyncHeight = state->pindexBestKnownBlock ? state->pindexBestKnownBlock->nHeight : -1;
324364
return true;
325365
}
326366

@@ -3613,6 +3653,9 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
36133653
PushGetBlocks(pfrom, chainActive.Tip(), GetOrphanRoot(inv.hash));
36143654
}
36153655

3656+
if (inv.type == MSG_BLOCK)
3657+
UpdateBlockAvailability(pfrom->GetId(), inv.hash);
3658+
36163659
// Track requests for our stuff
36173660
g_signals.Inventory(inv.hash);
36183661
}
@@ -4359,6 +4402,9 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
43594402
pto->fDisconnect = true;
43604403
}
43614404

4405+
// Update knowledge of peer's block availability.
4406+
ProcessBlockAvailability(pto->GetId());
4407+
43624408
//
43634409
// Message: getdata (blocks)
43644410
//

src/main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
185185

186186
struct CNodeStateStats {
187187
int nMisbehavior;
188+
int nSyncHeight;
188189
};
189190

190191
struct CDiskBlockPos

src/rpcnet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ Value getpeerinfo(const Array& params, bool fHelp)
134134
obj.push_back(Pair("startingheight", stats.nStartingHeight));
135135
if (fStateStats) {
136136
obj.push_back(Pair("banscore", statestats.nMisbehavior));
137+
obj.push_back(Pair("syncheight", statestats.nSyncHeight));
137138
}
138139
obj.push_back(Pair("syncnode", stats.fSyncNode));
139140

0 commit comments

Comments
 (0)