Assuming that we synced blockchain already if we have at least MASTERNODE_SYNC_ENOUGH_PEERS (6 currently) peers at the same height as we are (#1257)

This commit is contained in:
UdjinM6 2017-01-11 03:33:14 +04:00 committed by GitHub
parent 621f9ebeca
commit 5cb6486616
2 changed files with 69 additions and 29 deletions

View File

@ -17,6 +17,42 @@
class CMasternodeSync; class CMasternodeSync;
CMasternodeSync masternodeSync; CMasternodeSync masternodeSync;
void ReleaseNodes(const std::vector<CNode*> &vNodesCopy)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodesCopy)
pnode->Release();
}
bool CMasternodeSync::CheckNodeHeight(CNode* pnode, bool fDisconnectStuckNodes)
{
CNodeStateStats stats;
if(!GetNodeStateStats(pnode->id, stats) || stats.nCommonHeight == -1 || stats.nSyncHeight == -1) return false; // not enough info about this peer
// Check blocks and headers, allow a small error margin of 1 block
if(pCurrentBlockIndex->nHeight - 1 > stats.nCommonHeight) {
// This peer probably stuck, don't sync any additional data from it
if(fDisconnectStuckNodes) {
// Disconnect to free this connection slot for another peer.
pnode->fDisconnect = true;
LogPrintf("CMasternodeSync::CheckNodeHeight -- disconnecting from stuck peer, nHeight=%d, nCommonHeight=%d, peer=%d\n",
pCurrentBlockIndex->nHeight, stats.nCommonHeight, pnode->id);
} else {
LogPrintf("CMasternodeSync::CheckNodeHeight -- skipping stuck peer, nHeight=%d, nCommonHeight=%d, peer=%d\n",
pCurrentBlockIndex->nHeight, stats.nCommonHeight, pnode->id);
}
return false;
}
else if(pCurrentBlockIndex->nHeight < stats.nSyncHeight - 1) {
// This peer announced more headers than we have blocks currently
LogPrintf("CMasternodeSync::CheckNodeHeight -- skipping peer, who announced more headers than we have blocks currently, nHeight=%d, nSyncHeight=%d, peer=%d\n",
pCurrentBlockIndex->nHeight, stats.nSyncHeight, pnode->id);
return false;
}
return true;
}
bool CMasternodeSync::IsBlockchainSynced(bool fBlockAccepted) bool CMasternodeSync::IsBlockchainSynced(bool fBlockAccepted)
{ {
static bool fBlockchainSynced = false; static bool fBlockchainSynced = false;
@ -60,6 +96,34 @@ bool CMasternodeSync::IsBlockchainSynced(bool fBlockAccepted)
if(fCheckpointsEnabled && pCurrentBlockIndex->nHeight < Checkpoints::GetTotalBlocksEstimate(Params().Checkpoints())) if(fCheckpointsEnabled && pCurrentBlockIndex->nHeight < Checkpoints::GetTotalBlocksEstimate(Params().Checkpoints()))
return false; return false;
std::vector<CNode*> vNodesCopy;
{
LOCK(cs_vNodes);
vNodesCopy = vNodes;
BOOST_FOREACH(CNode* pnode, vNodesCopy)
pnode->AddRef();
}
// We have enough peers and assume most of them are synced
if(vNodes.size() >= MASTERNODE_SYNC_ENOUGH_PEERS) {
// Check to see how many of our peers are (almost) at the same height as we are
int nNodesAtSameHeight = 0;
BOOST_FOREACH(CNode* pnode, vNodesCopy)
{
// Make sure this peer is presumably at the same height
if(!CheckNodeHeight(pnode)) continue;
nNodesAtSameHeight++;
// if we have decent number of such peers, most likely we are synced now
if(nNodesAtSameHeight >= MASTERNODE_SYNC_ENOUGH_PEERS) {
LogPrintf("CMasternodeSync::IsBlockchainSynced -- found enough peers on the same height as we are, done\n");
fBlockchainSynced = true;
ReleaseNodes(vNodesCopy);
return true;
}
}
}
ReleaseNodes(vNodesCopy);
// wait for at least one new block to be accepted // wait for at least one new block to be accepted
if(!fFirstBlockAccepted) return false; if(!fFirstBlockAccepted) return false;
@ -191,13 +255,6 @@ void CMasternodeSync::ClearFulfilledRequests()
} }
} }
void ReleaseNodes(const std::vector<CNode*> &vNodesCopy)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodesCopy)
pnode->Release();
}
void CMasternodeSync::ProcessTick() void CMasternodeSync::ProcessTick()
{ {
static int nTick = 0; static int nTick = 0;
@ -295,28 +352,8 @@ void CMasternodeSync::ProcessTick()
continue; continue;
} }
CNodeStateStats stats; // Make sure this peer is presumably at the same height
if(!GetNodeStateStats(pnode->id, stats) || stats.nCommonHeight == -1 || stats.nSyncHeight == -1) continue; // not enough info about this peer if(!CheckNodeHeight(pnode, true)) continue;
// Check blocks and headers, allow a small error margin of 1 block
if(pCurrentBlockIndex->nHeight - 1 > stats.nCommonHeight) {
// This peer probably stuck, don't sync any additional data,
// disconnect to free this connection slot for another peer.
pnode->fDisconnect = true;
LogPrintf("CMasternodeSync::ProcessTick -- disconnecting from stuck peer, nHeight=%d, nCommonHeight=%d, peer=%d\n",
pCurrentBlockIndex->nHeight, stats.nCommonHeight, pnode->id);
continue;
}
else if(pCurrentBlockIndex->nHeight < stats.nSyncHeight - 1) {
// This peer announced more headers than we have blocks currently,
// we probably need to wait a bit or this peer is on another (longer??) chain,
// so our data could be incompatible, skip it anyway for now but do not disconnect,
// maybe that chain is the right one.
LogPrintf("CMasternodeSync::ProcessTick -- skipping peer, who announced more headers than we have blocks currently, nHeight=%d, nSyncHeight=%d, peer=%d\n",
pCurrentBlockIndex->nHeight, stats.nSyncHeight, pnode->id);
continue;
}
// If we got here, we should have enough info about this peer and it should be ok to continue further.
// SPORK : ALWAYS ASK FOR SPORKS AS WE SYNC (we skip this mode now) // SPORK : ALWAYS ASK FOR SPORKS AS WE SYNC (we skip this mode now)

View File

@ -24,6 +24,8 @@ static const int MASTERNODE_SYNC_FINISHED = 999;
static const int MASTERNODE_SYNC_TICK_SECONDS = 6; static const int MASTERNODE_SYNC_TICK_SECONDS = 6;
static const int MASTERNODE_SYNC_TIMEOUT_SECONDS = 30; // our blocks are 2.5 minutes so 30 seconds should be fine static const int MASTERNODE_SYNC_TIMEOUT_SECONDS = 30; // our blocks are 2.5 minutes so 30 seconds should be fine
static const int MASTERNODE_SYNC_ENOUGH_PEERS = 6;
extern CMasternodeSync masternodeSync; extern CMasternodeSync masternodeSync;
// //
@ -54,6 +56,7 @@ private:
// Keep track of current block index // Keep track of current block index
const CBlockIndex *pCurrentBlockIndex; const CBlockIndex *pCurrentBlockIndex;
bool CheckNodeHeight(CNode* pnode, bool fDisconnectStuckNodes = false);
void Fail(); void Fail();
void ClearFulfilledRequests(); void ClearFulfilledRequests();