Skip to content

Commit

Permalink
Merge #2659: [TierTwo] Fix and improve several synchronization problems
Browse files Browse the repository at this point in the history
6f79df3 [Refactor] Add ReloadMapSeen function to reload "seen" votes (random-zebra)
d60a105 test: add coverage for the incremental budget sync flow. (furszy)
34e9c23 Budget incremental sync: do not clear seen maps when relay status is reset. (furszy)
fa2ab10 [Refactor] Budget: check mn-enabled/vote-time before adding to mapSeen (random-zebra)
51e85ff Budget: limit orphan votes maps to 10k entries max. (furszy)
d04f5be [Refactor] Simplify CBudgetManager::CheckOrphanVotes() (random-zebra)
62ae606 Budget: Decouple the all-in-one `Budget::Sync()` into two functions: (1) single items sync requests and (2) full budget sync requests. (furszy)
62e9f5e tiertwo sync: fix orphans votes maps linking single prop/bud hash to a single vote, discarding the previous stored item every time that a new orphan arrives. Blocking any follow-up reception of the orphan votes that were discarded, prohibiting its connection forever. (furszy)
32196b1 test: add coverage for single proposal sync based on an orphan proposal vote reception and single finalization sync based on an orphan finalization vote. (furszy)
4864739 budget: generalize budget full sync items relay. (furszy)
31e40a4 Budget sync: Remove useless extra item sync p2p msgs roundtrip (no need to broadcast an inv if the peer is asking for the item directly..) and stop walking through the two maps (budgets and proposals), locking their mutexes, when the peer is requesting a single proposal/budfin. (furszy)
5f596b8 Tiertwo: do not block peers if they requested a single proposal or single budget finalization. (furszy)
ae28000 masternodesync: connect the not-connected ProcessSyncStatusMsg. (furszy)
2c3b0e8 masternodesync: fix extra `RequestedMNAttempt` increment in the sporks flow. (furszy)
7020310 masternodesync: decrease mnw sync threshold to 4 peers. (furszy)
7349750 masternodesync: reset last budget item time before start syncing it. (furszy)
fd7d569 masternodesync: re-format peer version check. (furszy)

Pull request description:

  A never ending story, more improvements and corrections for the tier two initial synchronization.

  This time, the following points are tackled:

  1) Fix a bad workflow that causes the budget data initial synchronization to be skipped.
  if we received for example a proposal +50 seconds ago, while we are synchronizing another asset, then once the budget sync starts, it will look like the sync is finished when it's not. Not waiting to receive any budget data, declaring the sync completed.

  2) Decrease `mnw` sync threshold to 4 peers to "minimize" the insane amount of network flood and initial tier two sync delay.
  MNW initial sync is mostly for historical reasons, getting +20k items per peer (+120k items total for the previous threshold of 6) is a high amount of duplicated data relayed over the wire. 80k is still very high but.. it's something that we have to live with until v6.0 (which removes entirely the need of `mnw` messages..).

  3) Fix extra sync attempt for the mnlist asset badly incremented in the sporks sync flow.

  4) Connect the not-connected `ProcessSyncStatusMsg` (ex `masternodesync.ProcessMessage()`). Thus why the tier two sync stats counters are always in 0, this function was being skipped.

  5) The node, after triggering the internal budget data relay process (relaying budget data to every known peer), is invalidly blocking every remote peer, for an hour, for follow-up budget sync requests.

  6) The orphans votes maps are linking a single prop/bud parent hash to a single vote, discarding the previous stored item every time that a new orphan arrives. Blocking any follow-up reception of the orphan votes that were discarded, prohibiting its connection.
 (edge case scenario: splitting risk)

  7) Added test coverage for:
     1) Single proposal sync based on an orphan proposal vote reception.
     2) Single budget finalization sync based on an orphan finalization vote reception.
     3) Orphan proposal votes and orphan budget fin votes connection when parent is received.


  8) Removed unneeded extra items network sync roundtrip: No need to trigger an inv-based sync when the peer sent us a single proposal sync request. And stop walking through the budgets and proposals maps, locking their mutexes, on every single peer unique proposal/bud_fin item request.


  9) Generalized the budget full sync items relay process.

  Let's aim to include this work on the coming v5.4.0.

ACKs for top commit:
  random-zebra:
    ACK 6f79df3
  Fuzzbawls:
    ACK 6f79df3

Tree-SHA512: d9225fe587becb378f50374c2805825e2636520f9abcb3697ee1ccedb1182636499006320043ef2c736a45ffc7891499044b4a06c2d30f7da142922442a27e4e
  • Loading branch information
random-zebra committed Dec 14, 2021
2 parents 4b8b541 + 6f79df3 commit fd19260
Show file tree
Hide file tree
Showing 10 changed files with 413 additions and 212 deletions.
293 changes: 220 additions & 73 deletions src/budget/budgetmanager.cpp

Large diffs are not rendered by default.

24 changes: 14 additions & 10 deletions src/budget/budgetmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

class CValidationState;

#define ORPHAN_VOTES_CACHE_LIMIT 10000

//
// Budget Manager : Contains all proposals for the budget
//
Expand All @@ -31,9 +33,11 @@ class CBudgetManager : public CValidationInterface
std::map<uint256, CFinalizedBudget> mapFinalizedBudgets; // guarded by cs_budgets

std::map<uint256, CBudgetVote> mapSeenProposalVotes; // guarded by cs_votes
std::map<uint256, CBudgetVote> mapOrphanProposalVotes; // guarded by cs_votes
typedef std::pair<std::vector<CBudgetVote>, int64_t> PropVotesAndLastVoteReceivedTime;
std::map<uint256, PropVotesAndLastVoteReceivedTime> mapOrphanProposalVotes; // guarded by cs_votes
std::map<uint256, CFinalizedBudgetVote> mapSeenFinalizedBudgetVotes; // guarded by cs_finalizedvotes
std::map<uint256, CFinalizedBudgetVote> mapOrphanFinalizedBudgetVotes; // guarded by cs_finalizedvotes
typedef std::pair<std::vector<CFinalizedBudgetVote>, int64_t> BudVotesAndLastVoteReceivedTime;
std::map<uint256, BudVotesAndLastVoteReceivedTime> mapOrphanFinalizedBudgetVotes; // guarded by cs_finalizedvotes

// Memory Only. Updated in NewBlock (blocks arrive in order)
std::atomic<int> nBestHeight;
Expand Down Expand Up @@ -62,19 +66,16 @@ class CBudgetManager : public CValidationInterface

CBudgetManager() {}

void ClearSeen()
{
WITH_LOCK(cs_votes, mapSeenProposalVotes.clear(); );
WITH_LOCK(cs_finalizedvotes, mapSeenFinalizedBudgetVotes.clear(); );
}

void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;

bool HaveProposal(const uint256& propHash) const { LOCK(cs_proposals); return mapProposals.count(propHash); }
bool HaveSeenProposalVote(const uint256& voteHash) const { LOCK(cs_votes); return mapSeenProposalVotes.count(voteHash); }
bool HaveFinalizedBudget(const uint256& budgetHash) const { LOCK(cs_budgets); return mapFinalizedBudgets.count(budgetHash); }
bool HaveSeenFinalizedBudgetVote(const uint256& voteHash) const { LOCK(cs_finalizedvotes); return mapSeenFinalizedBudgetVotes.count(voteHash); }

// Clears and reloads seen votes in the maps, and clears orphan votes
void ReloadMapSeen();

void AddSeenProposalVote(const CBudgetVote& vote);
void AddSeenFinalizedBudgetVote(const CFinalizedBudgetVote& vote);

Expand All @@ -98,7 +99,10 @@ class CBudgetManager : public CValidationInterface

void ResetSync() { SetSynced(false); }
void MarkSynced() { SetSynced(true); }
void Sync(CNode* node, const uint256& nProp, bool fPartial = false);
// Respond to full budget sync requests and internally triggered partial budget items relay
void Sync(CNode* node, bool fPartial);
// Respond to single budget item requests (proposals / budget finalization)
void SyncSingleItem(CNode* pfrom, const uint256& nProp);
void SetBestHeight(int height) { nBestHeight.store(height, std::memory_order_release); };
int GetBestHeight() const { return nBestHeight.load(std::memory_order_acquire); }

Expand Down Expand Up @@ -140,7 +144,7 @@ class CBudgetManager : public CValidationInterface
uint256 SubmitFinalBudget();

bool UpdateProposal(const CBudgetVote& vote, CNode* pfrom, std::string& strError);
bool UpdateFinalizedBudget(CFinalizedBudgetVote& vote, CNode* pfrom, std::string& strError);
bool UpdateFinalizedBudget(const CFinalizedBudgetVote& vote, CNode* pfrom, std::string& strError);
TrxValidationStatus IsTransactionValid(const CTransaction& txNew, const uint256& nBlockHash, int nBlockHeight) const;
std::string GetRequiredPaymentsString(int nBlockHeight);
bool FillBlockPayee(CMutableTransaction& txCoinbase, CMutableTransaction& txCoinstake, const int nHeight, bool fProofOfStake) const;
Expand Down
6 changes: 0 additions & 6 deletions src/budget/budgetproposal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,6 @@ bool CBudgetProposal::AddOrUpdateVote(const CBudgetVote& vote, std::string& strE
strAction = "Existing vote updated:";
}

if (voteTime > GetTime() + (60 * 60)) {
strError = strprintf("new vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", vote.GetHash().ToString(), voteTime, GetTime() + (60 * 60));
LogPrint(BCLog::MNBUDGET, "%s: %s\n", __func__, strError);
return false;
}

mapVotes[mnId] = vote;
LogPrint(BCLog::MNBUDGET, "%s: %s %s\n", __func__, strAction.c_str(), vote.GetHash().ToString().c_str());

Expand Down
7 changes: 0 additions & 7 deletions src/budget/finalizedbudget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,6 @@ bool CFinalizedBudget::AddOrUpdateVote(const CFinalizedBudgetVote& vote, std::st
strAction = "Existing vote updated:";
}

if (voteTime > GetTime() + (60 * 60)) {
strError = strprintf("new vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n",
vote.GetHash().ToString(), voteTime, GetTime() + (60 * 60));
LogPrint(BCLog::MNBUDGET, "%s: %s\n", __func__, strError);
return false;
}

mapVotes[mnId] = vote;
LogPrint(BCLog::MNBUDGET, "%s: %s %s\n", __func__, strAction.c_str(), vote.GetHash().ToString().c_str());
return true;
Expand Down
2 changes: 1 addition & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1762,7 +1762,7 @@ bool AppInitMain()

//flag our cached items so we send them to our peers
g_budgetman.ResetSync();
g_budgetman.ClearSeen();
g_budgetman.ReloadMapSeen();

RegisterValidationInterface(&g_budgetman);

Expand Down
230 changes: 122 additions & 108 deletions src/masternode-sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,17 +220,12 @@ std::string CMasternodeSync::GetSyncStatus()
return "";
}

void CMasternodeSync::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
void CMasternodeSync::ProcessSyncStatusMsg(int nItemID, int nCount)
{
if (strCommand == NetMsgType::SYNCSTATUSCOUNT) { //Sync status count
int nItemID;
int nCount;
vRecv >> nItemID >> nCount;
if (RequestedMasternodeAssets >= MASTERNODE_SYNC_FINISHED) return;

if (RequestedMasternodeAssets >= MASTERNODE_SYNC_FINISHED) return;

//this means we will receive no further communication
switch (nItemID) {
//this means we will receive no further communication
switch (nItemID) {
case (MASTERNODE_SYNC_LIST):
if (nItemID != RequestedMasternodeAssets) return;
sumMasternodeList += nCount;
Expand All @@ -251,10 +246,11 @@ void CMasternodeSync::ProcessMessage(CNode* pfrom, std::string& strCommand, CDat
sumBudgetItemFin += nCount;
countBudgetItemFin++;
break;
}

LogPrint(BCLog::MASTERNODE, "CMasternodeSync:ProcessMessage - ssc - got inventory count %d %d\n", nItemID, nCount);
default:
break;
}

LogPrint(BCLog::MASTERNODE, "CMasternodeSync:ProcessMessage - ssc - got inventory count %d %d\n", nItemID, nCount);
}

void CMasternodeSync::ClearFulfilledRequest()
Expand Down Expand Up @@ -337,136 +333,154 @@ bool CMasternodeSync::SyncWithNode(CNode* pnode, bool fLegacyMnObsolete)

//set to synced
if (RequestedMasternodeAssets == MASTERNODE_SYNC_SPORKS) {

// Sync sporks from at least 2 peers
if (RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD) {
SwitchToNextAsset();
return false;
}

// Request sporks sync if we haven't requested it yet.
if (pnode->HasFulfilledRequest("getspork")) return true;
pnode->FulfilledRequest("getspork");

g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::GETSPORKS)); //get current network sporks
if (RequestedMasternodeAttempt >= 2) SwitchToNextAsset();
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::GETSPORKS));
RequestedMasternodeAttempt++;
return false;
}

if (pnode->nVersion >= ActiveProtocol()) {
if (RequestedMasternodeAssets == MASTERNODE_SYNC_LIST) {
if (fLegacyMnObsolete) {
SwitchToNextAsset();
return false;
}
if (pnode->nVersion < ActiveProtocol()) {
return true; // move to next peer
}

if (RequestedMasternodeAssets == MASTERNODE_SYNC_LIST) {
if (fLegacyMnObsolete) {
SwitchToNextAsset();
return false;
}

LogPrint(BCLog::MASTERNODE, "CMasternodeSync::Process() - lastMasternodeList %lld (GetTime() - MASTERNODE_SYNC_TIMEOUT) %lld\n", lastMasternodeList, GetTime() - MASTERNODE_SYNC_TIMEOUT);
if (lastMasternodeList > 0 && lastMasternodeList < GetTime() - MASTERNODE_SYNC_TIMEOUT * 8 && RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD) {
// hasn't received a new item in the last 40 seconds AND has sent at least a minimum of MASTERNODE_SYNC_THRESHOLD GETMNLIST requests,
// so we'll move to the next asset.
SwitchToNextAsset();
return false;
}

LogPrint(BCLog::MASTERNODE, "CMasternodeSync::Process() - lastMasternodeList %lld (GetTime() - MASTERNODE_SYNC_TIMEOUT) %lld\n", lastMasternodeList, GetTime() - MASTERNODE_SYNC_TIMEOUT);
if (lastMasternodeList > 0 && lastMasternodeList < GetTime() - MASTERNODE_SYNC_TIMEOUT * 8 && RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD) {
// hasn't received a new item in the last 40 seconds AND has sent at least a minimum of MASTERNODE_SYNC_THRESHOLD GETMNLIST requests,
// so we'll move to the next asset.
// timeout
if (lastMasternodeList == 0 &&
(RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 3 || GetTime() - nAssetSyncStarted > MASTERNODE_SYNC_TIMEOUT * 5)) {
if (sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) {
syncTimeout("MASTERNODE_SYNC_LIST");
} else {
SwitchToNextAsset();
return false;
}
return false;
}

// timeout
if (lastMasternodeList == 0 &&
(RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 3 || GetTime() - nAssetSyncStarted > MASTERNODE_SYNC_TIMEOUT * 5)) {
if (sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) {
syncTimeout("MASTERNODE_SYNC_LIST");
} else {
SwitchToNextAsset();
}
return false;
}
// Don't request mnlist initial sync to more than 8 randomly ordered peers in this round
if (RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 4) return false;

// Don't request mnlist initial sync to more than 8 randomly ordered peers in this round
if (RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 4) return false;
// Request mnb sync if we haven't requested it yet.
if (pnode->HasFulfilledRequest("mnsync")) return true;

// Request mnb sync if we haven't requested it yet.
if (pnode->HasFulfilledRequest("mnsync")) return true;
// Try to request MN list sync.
if (!mnodeman.RequestMnList(pnode)) {
return true; // Failed, try next peer.
}

// Try to request MN list sync.
if (!mnodeman.RequestMnList(pnode)) {
return true; // Failed, try next peer.
}
// Mark sync requested.
pnode->FulfilledRequest("mnsync");
// Increase the sync attempt count
RequestedMasternodeAttempt++;

// Mark sync requested.
pnode->FulfilledRequest("mnsync");
// Increase the sync attempt count
RequestedMasternodeAttempt++;
return false; // sleep 1 second before do another request round.
}

return false; // sleep 1 second before do another request round.
if (RequestedMasternodeAssets == MASTERNODE_SYNC_MNW) {
if (fLegacyMnObsolete) {
SwitchToNextAsset();
return false;
}

if (RequestedMasternodeAssets == MASTERNODE_SYNC_MNW) {
if (fLegacyMnObsolete) {
SwitchToNextAsset();
return false;
}
if (lastMasternodeWinner > 0 && lastMasternodeWinner < GetTime() - MASTERNODE_SYNC_TIMEOUT * 2 && RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD) { //hasn't received a new item in the last five seconds, so we'll move to the
SwitchToNextAsset();
// in case we received a budget item while we were syncing the mnw, let's reset the last budget item received time.
// reason: if we received for example a single proposal +50 seconds ago, then once the budget sync starts (right after this call),
// it will look like the sync is finished, and will not wait to receive any budget data and declare the sync over.
lastBudgetItem = 0;
return false;
}

if (lastMasternodeWinner > 0 && lastMasternodeWinner < GetTime() - MASTERNODE_SYNC_TIMEOUT * 2 && RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD) { //hasn't received a new item in the last five seconds, so we'll move to the
// timeout
if (lastMasternodeWinner == 0 &&
(RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 2 || GetTime() - nAssetSyncStarted > MASTERNODE_SYNC_TIMEOUT * 5)) {
if (sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) {
syncTimeout("MASTERNODE_SYNC_MNW");
} else {
SwitchToNextAsset();
return false;
}

// timeout
if (lastMasternodeWinner == 0 &&
(RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 3 || GetTime() - nAssetSyncStarted > MASTERNODE_SYNC_TIMEOUT * 5)) {
if (sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) {
syncTimeout("MASTERNODE_SYNC_MNW");
} else {
SwitchToNextAsset();
}
return false;
// Same as above (future: remove all of this duplicated code in v6.0.)
// in case we received a budget item while we were syncing the mnw, let's reset the last budget item received time.
// reason: if we received for example a single proposal +50 seconds ago, then once the budget sync starts (right after this call),
// it will look like the sync is finished, and will not wait to receive any budget data and declare the sync over.
lastBudgetItem = 0;
}
return false;
}

// Don't request mnw initial sync to more than 6 randomly ordered peers in this round.
if (RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 3) return false;
// Don't request mnw initial sync to more than 4 randomly ordered peers in this round.
if (RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 2) return false;

// Request mnw sync if we haven't requested it yet.
if (pnode->HasFulfilledRequest("mnwsync")) return true;
// Request mnw sync if we haven't requested it yet.
if (pnode->HasFulfilledRequest("mnwsync")) return true;

// Mark sync requested.
pnode->FulfilledRequest("mnwsync");
// Mark sync requested.
pnode->FulfilledRequest("mnwsync");

// Sync mn winners
int nMnCount = mnodeman.CountEnabled(true /* only_legacy */);
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::GETMNWINNERS, nMnCount));
RequestedMasternodeAttempt++;
// Sync mn winners
int nMnCount = mnodeman.CountEnabled(true /* only_legacy */);
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::GETMNWINNERS, nMnCount));
RequestedMasternodeAttempt++;

return false; // sleep 1 second before do another request round.
}
return false; // sleep 1 second before do another request round.
}

if (RequestedMasternodeAssets == MASTERNODE_SYNC_BUDGET) {
// We'll start rejecting votes if we accidentally get set as synced too soon
if (lastBudgetItem > 0 && lastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT * 10 && RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD) {
// Hasn't received a new item in the last fifty seconds and more than MASTERNODE_SYNC_THRESHOLD requests were sent,
// so we'll move to the next asset
SwitchToNextAsset();
if (RequestedMasternodeAssets == MASTERNODE_SYNC_BUDGET) {
// We'll start rejecting votes if we accidentally get set as synced too soon
if (lastBudgetItem > 0 && lastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT * 10 && RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD) {
// Hasn't received a new item in the last fifty seconds and more than MASTERNODE_SYNC_THRESHOLD requests were sent,
// so we'll move to the next asset
SwitchToNextAsset();

// Try to activate our masternode if possible
activeMasternode.ManageStatus();
return false;
}
// Try to activate our masternode if possible
activeMasternode.ManageStatus();
return false;
}

// timeout
if (lastBudgetItem == 0 &&
(RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 3 || GetTime() - nAssetSyncStarted > MASTERNODE_SYNC_TIMEOUT * 5)) {
// maybe there is no budgets at all, so just finish syncing
SwitchToNextAsset();
activeMasternode.ManageStatus();
return false;
}
// timeout
if (lastBudgetItem == 0 &&
(RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 3 || GetTime() - nAssetSyncStarted > MASTERNODE_SYNC_TIMEOUT * 5)) {
// maybe there is no budgets at all, so just finish syncing
SwitchToNextAsset();
activeMasternode.ManageStatus();
return false;
}

// Don't request budget initial sync to more than 6 randomly ordered peers in this round.
if (RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 3) return false;
// Don't request budget initial sync to more than 6 randomly ordered peers in this round.
if (RequestedMasternodeAttempt >= MASTERNODE_SYNC_THRESHOLD * 3) return false;

// Request bud sync if we haven't requested it yet.
if (pnode->HasFulfilledRequest("busync")) return true;
// Request bud sync if we haven't requested it yet.
if (pnode->HasFulfilledRequest("busync")) return true;

// Mark sync requested.
pnode->FulfilledRequest("busync");
// Mark sync requested.
pnode->FulfilledRequest("busync");

// Sync proposals, finalizations and votes
uint256 n;
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::BUDGETVOTESYNC, n));
RequestedMasternodeAttempt++;
// Sync proposals, finalizations and votes
uint256 n;
g_connman->PushMessage(pnode, msgMaker.Make(NetMsgType::BUDGETVOTESYNC, n));
RequestedMasternodeAttempt++;

return false; // sleep 1 second before do another request round.
}
return false; // sleep 1 second before do another request round.
}

return true;
Expand Down
2 changes: 1 addition & 1 deletion src/masternode-sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class CMasternodeSync
void AddedBudgetItem(const uint256& hash);
void SwitchToNextAsset();
std::string GetSyncStatus();
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
void ProcessSyncStatusMsg(int nItemID, int itemCount);
bool IsBudgetFinEmpty();
bool IsBudgetPropEmpty();

Expand Down
Loading

0 comments on commit fd19260

Please sign in to comment.