Introduce 10 minute block download timeout
This will disconnect peers that do not transfer a block in 10 minutes, plus 5 minutes for every previously queued block with validated headers (accomodating downstream bandwidth down to a few kilobytes per second - below that the node would have trouble staying synchronized anyway).
This commit is contained in:
parent
8e4578af0f
commit
916130348c
1 changed files with 17 additions and 1 deletions
18
src/main.cpp
18
src/main.cpp
|
@ -139,9 +139,14 @@ namespace {
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
CBlockIndex *pindex; //! Optional.
|
CBlockIndex *pindex; //! Optional.
|
||||||
int64_t nTime; //! Time of "getdata" request in microseconds.
|
int64_t nTime; //! Time of "getdata" request in microseconds.
|
||||||
|
int nValidatedQueuedBefore; //! Number of blocks queued with validated headers (globally) at the time this one is requested.
|
||||||
|
bool fValidatedHeaders; //! Whether this block has validated headers at the time of request.
|
||||||
};
|
};
|
||||||
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
|
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight;
|
||||||
|
|
||||||
|
/** Number of blocks in flight with validated headers. */
|
||||||
|
int nQueuedValidatedHeaders = 0;
|
||||||
|
|
||||||
/** Number of preferable block download peers. */
|
/** Number of preferable block download peers. */
|
||||||
int nPreferredDownload = 0;
|
int nPreferredDownload = 0;
|
||||||
|
|
||||||
|
@ -323,6 +328,7 @@ void MarkBlockAsReceived(const uint256& hash) {
|
||||||
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
|
map<uint256, pair<NodeId, list<QueuedBlock>::iterator> >::iterator itInFlight = mapBlocksInFlight.find(hash);
|
||||||
if (itInFlight != mapBlocksInFlight.end()) {
|
if (itInFlight != mapBlocksInFlight.end()) {
|
||||||
CNodeState *state = State(itInFlight->second.first);
|
CNodeState *state = State(itInFlight->second.first);
|
||||||
|
nQueuedValidatedHeaders -= itInFlight->second.second->fValidatedHeaders;
|
||||||
state->vBlocksInFlight.erase(itInFlight->second.second);
|
state->vBlocksInFlight.erase(itInFlight->second.second);
|
||||||
state->nBlocksInFlight--;
|
state->nBlocksInFlight--;
|
||||||
state->nStallingSince = 0;
|
state->nStallingSince = 0;
|
||||||
|
@ -338,7 +344,8 @@ void MarkBlockAsInFlight(NodeId nodeid, const uint256& hash, CBlockIndex *pindex
|
||||||
// Make sure it's not listed somewhere already.
|
// Make sure it's not listed somewhere already.
|
||||||
MarkBlockAsReceived(hash);
|
MarkBlockAsReceived(hash);
|
||||||
|
|
||||||
QueuedBlock newentry = {hash, pindex, GetTimeMicros()};
|
QueuedBlock newentry = {hash, pindex, GetTimeMicros(), nQueuedValidatedHeaders, pindex != NULL};
|
||||||
|
nQueuedValidatedHeaders += newentry.fValidatedHeaders;
|
||||||
list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
|
list<QueuedBlock>::iterator it = state->vBlocksInFlight.insert(state->vBlocksInFlight.end(), newentry);
|
||||||
state->nBlocksInFlight++;
|
state->nBlocksInFlight++;
|
||||||
mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
|
mapBlocksInFlight[hash] = std::make_pair(nodeid, it);
|
||||||
|
@ -4527,6 +4534,15 @@ bool SendMessages(CNode* pto, bool fSendTrickle)
|
||||||
LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
|
LogPrintf("Peer=%d is stalling block download, disconnecting\n", pto->id);
|
||||||
pto->fDisconnect = true;
|
pto->fDisconnect = true;
|
||||||
}
|
}
|
||||||
|
// In case there is a block that has been in flight from this peer for (1 + 0.5 * N) times the block interval
|
||||||
|
// (with N the number of validated blocks that were in flight at the time it was requested), disconnect due to
|
||||||
|
// timeout. We compensate for in-flight blocks to prevent killing off peers due to our own downstream link
|
||||||
|
// being saturated. We only count validated in-flight blocks so peers can't advertize nonexisting block hashes
|
||||||
|
// to unreasonably increase our timeout.
|
||||||
|
if (!pto->fDisconnect && state.vBlocksInFlight.size() > 0 && state.vBlocksInFlight.front().nTime < nNow - 500000 * Params().TargetSpacing() * (2 + state.vBlocksInFlight.front().nValidatedQueuedBefore)) {
|
||||||
|
LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", state.vBlocksInFlight.front().hash.ToString(), pto->id);
|
||||||
|
pto->fDisconnect = true;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Message: getdata (blocks)
|
// Message: getdata (blocks)
|
||||||
|
|
Loading…
Reference in a new issue