PRCYCoin  2.0.0.7rc1
P2P Digital Currency
masternode-sync.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2015 The Dash developers
2 // Copyright (c) 2015-2018 The PIVX developers
3 // Copyright (c) 2018-2020 The DAPS Project developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 // clang-format off
8 #include "main.h"
9 #include "activemasternode.h"
10 #include "masternode-sync.h"
11 #include "masternode-payments.h"
12 #include "masternode-budget.h"
13 #include "masternode.h"
14 #include "masternodeman.h"
15 #include "util.h"
16 #include "addrman.h"
17 // clang-format on
18 
21 
23 {
24  Reset();
25 }
26 
28 {
30 }
31 
33 {
34  int64_t now = GetTime();
35 
36  // if the last call to this function was more than 60 minutes ago (client was in sleep mode) reset the sync process
37  if (now > lastProcess + 60 * 60) {
38  Reset();
39  fBlockchainSynced = false;
40  }
41  lastProcess = now;
42 
43  if (fBlockchainSynced) return true;
44 
45  if (fImporting || fReindex) return false;
46 
47  int64_t blockTime = 0;
48  {
49  TRY_LOCK(cs_main, lockMain);
50  if (!lockMain) return false;
51  CBlockIndex *pindex = chainActive.Tip();
52  if (pindex == nullptr) return false;
53  blockTime = pindex->nTime;
54  }
55 
56  if (blockTime + 60 * 60 < lastProcess)
57  return false;
58 
59  fBlockchainSynced = true;
60 
61  return true;
62 }
63 
65 {
66  fBlockchainSynced = false;
67  lastProcess = 0;
70  lastBudgetItem = 0;
71  mapSeenSyncMNB.clear();
72  mapSeenSyncMNW.clear();
73  mapSeenSyncBudget.clear();
74  lastFailure = 0;
75  nCountFailures = 0;
79  sumBudgetItemFin = 0;
87 }
88 
90 {
91  if (mnodeman.mapSeenMasternodeBroadcast.count(hash)) {
94  mapSeenSyncMNB[hash]++;
95  }
96  } else {
98  mapSeenSyncMNB.insert(std::make_pair(hash, 1));
99  }
100 }
101 
103 {
107  mapSeenSyncMNW[hash]++;
108  }
109  } else {
111  mapSeenSyncMNW.insert(std::make_pair(hash, 1));
112  }
113 }
114 
116 {
121  mapSeenSyncBudget[hash]++;
122  }
123  } else {
125  mapSeenSyncBudget.insert(std::make_pair(hash, 1));
126  }
127 }
128 
130 {
131  return sumBudgetItemProp == 0 && countBudgetItemProp > 0;
132 }
133 
135 {
136  return sumBudgetItemFin == 0 && countBudgetItemFin > 0;
137 }
138 
140 {
141  switch (RequestedMasternodeAssets) {
143  case (MASTERNODE_SYNC_FAILED): // should never be used here actually, use Reset() instead
146  break;
147  case (MASTERNODE_SYNC_LIST):
149  break;
150  case (MASTERNODE_SYNC_MNW):
152  break;
153  case (MASTERNODE_SYNC_BUDGET):
155  break;
156  }
159 }
160 
162 {
165  return _("Synchronization pending...");
167  return _("Synchronizing masternodes...");
168  case MASTERNODE_SYNC_MNW:
169  return _("Synchronizing masternode winners...");
171  return _("Synchronizing budgets...");
173  return _("Synchronization failed");
175  return _("Synchronization finished");
176  }
177  return "";
178 }
179 
180 void CMasternodeSync::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
181 {
182  if (strCommand == NetMsgType::SYNCSTATUSCOUNT) { //Sync status count
183  int nItemID;
184  int nCount;
185  vRecv >> nItemID >> nCount;
186 
188 
189  //this means we will receive no further communication
190  switch (nItemID) {
191  case (MASTERNODE_SYNC_LIST):
192  if (nItemID != RequestedMasternodeAssets) return;
193  sumMasternodeList += nCount;
195  break;
196  case (MASTERNODE_SYNC_MNW):
197  if (nItemID != RequestedMasternodeAssets) return;
198  sumMasternodeWinner += nCount;
200  break;
203  sumBudgetItemProp += nCount;
205  break;
208  sumBudgetItemFin += nCount;
210  break;
211  }
212 
213  LogPrint(BCLog::MASTERNODE, "CMasternodeSync:ProcessMessage - ssc - got inventory count %d %d\n", nItemID, nCount);
214  }
215 }
216 
218 {
219  TRY_LOCK(cs_vNodes, lockRecv);
220  if (!lockRecv) return;
221 
222  for (CNode* pnode : vNodes) {
223  pnode->ClearFulfilledRequest("mnsync");
224  pnode->ClearFulfilledRequest("mnwsync");
225  pnode->ClearFulfilledRequest("busync");
226  }
227 }
228 
230 {
231  static int tick = 0;
232  const bool isRegTestNet = Params().IsRegTestNet();
233 
234  if (tick++ % MASTERNODE_SYNC_TIMEOUT != 0) return;
235 
236  if (IsSynced()) {
237  /*
238  Resync if we lose all masternodes from sleep/wake or failure to sync originally
239  */
240  if (mnodeman.CountEnabled() == 0) {
241  Reset();
242  } else
243  return;
244  }
245 
246  //try syncing again
248  Reset();
250  return;
251  }
252 
253  LogPrint(BCLog::MASTERNODE, "CMasternodeSync::Process() - tick %d RequestedMasternodeAssets %d\n", tick, RequestedMasternodeAssets);
254 
256 
257  if (!isRegTestNet && !IsBlockchainSynced()) return;
258 
259  TRY_LOCK(cs_vNodes, lockRecv);
260  if (!lockRecv) return;
261 
262  for (CNode* pnode : vNodes) {
263  if (isRegTestNet) {
264  if (RequestedMasternodeAttempt < 4) {
265  mnodeman.DsegUpdate(pnode);
266  } else if (RequestedMasternodeAttempt < 6) {
267  int nMnCount = mnodeman.CountEnabled();
268  pnode->PushMessage(NetMsgType::GETMNWINNERS, nMnCount); //sync payees
269  uint256 n;
270  pnode->PushMessage(NetMsgType::BUDGETVOTESYNC, n); //sync masternode votes
271  } else {
273  }
275  return;
276  }
277 
278  if (pnode->nVersion >= masternodePayments.GetMinMasternodePaymentsProto()) {
280  LogPrint(BCLog::MASTERNODE, "CMasternodeSync::Process() - lastMasternodeList %lld (GetTime() - MASTERNODE_SYNC_TIMEOUT) %lld\n", lastMasternodeList, GetTime() - MASTERNODE_SYNC_TIMEOUT);
281  if (lastMasternodeList > 0 && lastMasternodeList < 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
282  GetNextAsset();
283  return;
284  }
285 
286  if (pnode->HasFulfilledRequest("mnsync")) continue;
287  pnode->FulfilledRequest("mnsync");
288 
289  // timeout
290  if (lastMasternodeList == 0 &&
292  GetNextAsset();
293  return;
294  }
295 
297 
298  mnodeman.DsegUpdate(pnode);
300  return;
301  }
302 
304  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
305  GetNextAsset();
306  return;
307  }
308 
309  if (pnode->HasFulfilledRequest("mnwsync")) continue;
310  pnode->FulfilledRequest("mnwsync");
311 
312  // timeout
313  if (lastMasternodeWinner == 0 &&
315  GetNextAsset();
316  return;
317  }
318 
320 
321  int nMnCount = mnodeman.CountEnabled();
322  pnode->PushMessage(NetMsgType::GETMNWINNERS, nMnCount); //sync payees
324 
325  return;
326  }
327  }
328 
329  if (pnode->nVersion >= ActiveProtocol()) {
331 
332  // We'll start rejecting votes if we accidentally get set as synced too soon
334 
335  // Hasn't received a new item in the last five seconds, so we'll move to the
336  GetNextAsset();
337 
338  // Try to activate our masternode if possible
340 
341  return;
342  }
343 
344  // timeout
345  if (lastBudgetItem == 0 &&
347  // maybe there is no budgets at all, so just finish syncing
348  GetNextAsset();
350  return;
351  }
352 
353  if (pnode->HasFulfilledRequest("busync")) continue;
354  pnode->FulfilledRequest("busync");
355 
357 
358  uint256 n;
359  pnode->PushMessage(NetMsgType::BUDGETVOTESYNC, n); //sync masternode votes
361 
362  return;
363  }
364  }
365  }
366 }
CMasternodeSync::sumMasternodeList
int sumMasternodeList
Definition: masternode-sync.h:46
CMasternodeSync::Reset
void Reset()
Definition: masternode-sync.cpp:64
fImporting
std::atomic< bool > fImporting
Definition: main.cpp:80
CBudgetManager::mapSeenMasternodeBudgetProposals
std::map< uint256, CBudgetProposalBroadcast > mapSeenMasternodeBudgetProposals
Definition: masternode-budget.h:187
vNodes
std::vector< CNode * > vNodes
Definition: net.cpp:85
CMasternodeSync::IsBudgetFinEmpty
bool IsBudgetFinEmpty()
Definition: masternode-sync.cpp:134
MASTERNODE_SYNC_BUDGET
#define MASTERNODE_SYNC_BUDGET
Definition: masternode-sync.h:13
CMasternodeMan::CountEnabled
int CountEnabled(int protocolVersion=-1)
Definition: masternodeman.cpp:379
CMasternodeSync::countBudgetItemProp
int countBudgetItemProp
Definition: masternode-sync.h:53
GetTime
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:19
CMasternodeSync::mapSeenSyncBudget
std::map< uint256, int > mapSeenSyncBudget
Definition: masternode-sync.h:34
activeMasternode
CActiveMasternode activeMasternode
Keep track of the active Masternode.
Definition: masternodeman.cpp:24
CMasternodePayments::GetMinMasternodePaymentsProto
int GetMinMasternodePaymentsProto()
Definition: masternode-payments.cpp:293
CMasternodeSync::RequestedMasternodeAssets
int RequestedMasternodeAssets
Definition: masternode-sync.h:57
CBudgetManager::mapSeenFinalizedBudgets
std::map< uint256, CFinalizedBudgetBroadcast > mapSeenFinalizedBudgets
Definition: masternode-budget.h:190
chainActive
CChain chainActive
The currently-connected chain of blocks.
Definition: main.cpp:70
CBudgetManager::mapSeenMasternodeBudgetVotes
std::map< uint256, CBudgetVote > mapSeenMasternodeBudgetVotes
Definition: masternode-budget.h:188
CMasternodeSync::lastFailure
int64_t lastFailure
Definition: masternode-sync.h:39
CMasternodeSync::IsBlockchainSynced
bool IsBlockchainSynced()
Definition: masternode-sync.cpp:32
CNode
Information about a peer.
Definition: net.h:306
CMasternodeSync::lastMasternodeWinner
int64_t lastMasternodeWinner
Definition: masternode-sync.h:37
CMasternodeSync::AddedMasternodeList
void AddedMasternodeList(uint256 hash)
Definition: masternode-sync.cpp:89
CMasternodeSync::countMasternodeWinner
int countMasternodeWinner
Definition: masternode-sync.h:52
CMasternodeSync::countBudgetItemFin
int countBudgetItemFin
Definition: masternode-sync.h:54
masternode-sync.h
CMasternodePayments::mapMasternodePayeeVotes
std::map< uint256, CMasternodePaymentWinner > mapMasternodePayeeVotes
Definition: masternode-payments.h:238
CMasternodeSync::RequestedMasternodeAttempt
int RequestedMasternodeAttempt
Definition: masternode-sync.h:58
MASTERNODE_SYNC_TIMEOUT
#define MASTERNODE_SYNC_TIMEOUT
Definition: masternode-sync.h:19
cs_vNodes
RecursiveMutex cs_vNodes
Definition: net.cpp:86
TRY_LOCK
#define TRY_LOCK(cs, name)
Definition: sync.h:186
masternodeman.h
CChainParams::IsRegTestNet
bool IsRegTestNet() const
Definition: chainparams.h:104
MASTERNODE_SYNC_THRESHOLD
#define MASTERNODE_SYNC_THRESHOLD
Definition: masternode-sync.h:20
CMasternodeSync::ClearFulfilledRequest
void ClearFulfilledRequest()
Definition: masternode-sync.cpp:217
CMasternodeSync::sumBudgetItemFin
int sumBudgetItemFin
Definition: masternode-sync.h:49
masternodeSync
CMasternodeSync masternodeSync
Definition: masternode-sync.cpp:19
NetMsgType::BUDGETVOTESYNC
const char * BUDGETVOTESYNC
The budgetvotesync message is used to request budget vote data from connected peers.
Definition: protocol.cpp:56
CBlockIndex::nTime
unsigned int nTime
Definition: chain.h:228
CMasternodeSync::countMasternodeList
int countMasternodeList
Definition: masternode-sync.h:51
CMasternodeSync::IsBudgetPropEmpty
bool IsBudgetPropEmpty()
Definition: masternode-sync.cpp:129
cs_main
RecursiveMutex cs_main
Global state.
Definition: main.cpp:65
ActiveProtocol
int ActiveProtocol()
See whether the protocol update is enforced for connected nodes.
Definition: main.cpp:6844
CMasternodeSync::lastBudgetItem
int64_t lastBudgetItem
Definition: masternode-sync.h:38
mnodeman
CMasternodeMan mnodeman
Masternode manager.
Definition: masternodeman.cpp:22
CMasternodeSync::nAssetSyncStarted
int64_t nAssetSyncStarted
Definition: masternode-sync.h:61
CMasternodeSync::fBlockchainSynced
std::atomic< bool > fBlockchainSynced
Definition: masternode-sync.h:43
CActiveMasternode::ManageStatus
void ManageStatus()
Manage status of main Masternode.
Definition: activemasternode.cpp:21
_
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result.
Definition: guiinterface.h:119
MASTERNODE_SYNC_BUDGET_PROP
#define MASTERNODE_SYNC_BUDGET_PROP
Definition: masternode-sync.h:14
MASTERNODE_SYNC_INITIAL
#define MASTERNODE_SYNC_INITIAL
Definition: masternode-sync.h:10
CMasternodeSync::sumMasternodeWinner
int sumMasternodeWinner
Definition: masternode-sync.h:47
NetMsgType::GETMNWINNERS
const char * GETMNWINNERS
The getmnwinners message is used to request winning masternode data from connected peers.
Definition: protocol.cpp:53
masternodePayments
CMasternodePayments masternodePayments
Object for who's going to get paid on which blocks.
Definition: masternode-payments.cpp:19
CMasternodeSync::lastProcess
std::atomic< int64_t > lastProcess
Definition: masternode-sync.h:42
CMasternodeSync::AddedMasternodeWinner
void AddedMasternodeWinner(uint256 hash)
Definition: masternode-sync.cpp:102
CMasternodeMan::mapSeenMasternodeBroadcast
std::map< uint256, CMasternodeBroadcast > mapSeenMasternodeBroadcast
Definition: masternodeman.h:76
masternode-payments.h
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
MASTERNODE_SYNC_FINISHED
#define MASTERNODE_SYNC_FINISHED
Definition: masternode-sync.h:17
CMasternodeSync::GetSyncStatus
std::string GetSyncStatus()
Definition: masternode-sync.cpp:161
MASTERNODE_SYNC_FAILED
#define MASTERNODE_SYNC_FAILED
Definition: masternode-sync.h:16
LogPrint
#define LogPrint(category,...)
Definition: logging.h:162
CMasternodeSync::AddedBudgetItem
void AddedBudgetItem(uint256 hash)
Definition: masternode-sync.cpp:115
CMasternodeSync::IsSynced
bool IsSynced()
Definition: masternode-sync.cpp:27
MASTERNODE_SYNC_MNW
#define MASTERNODE_SYNC_MNW
Definition: masternode-sync.h:12
CMasternodeSync::GetNextAsset
void GetNextAsset()
Definition: masternode-sync.cpp:139
CMasternodeSync::lastMasternodeList
int64_t lastMasternodeList
Definition: masternode-sync.h:36
CMasternodeSync::nCountFailures
int nCountFailures
Definition: masternode-sync.h:40
activemasternode.h
MASTERNODE_SYNC_BUDGET_FIN
#define MASTERNODE_SYNC_BUDGET_FIN
Definition: masternode-sync.h:15
BCLog::MASTERNODE
@ MASTERNODE
Definition: logging.h:62
fReindex
std::atomic< bool > fReindex
Definition: main.cpp:81
main.h
CMasternodeSync::mapSeenSyncMNB
std::map< uint256, int > mapSeenSyncMNB
Definition: masternode-sync.h:32
CMasternodeMan::DsegUpdate
void DsegUpdate(CNode *pnode)
Definition: masternodeman.cpp:419
CMasternodeSync
Definition: masternode-sync.h:29
CMasternodeSync::ProcessMessage
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv)
Definition: masternode-sync.cpp:180
masternode.h
Params
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:463
masternode-budget.h
NetMsgType::SYNCSTATUSCOUNT
const char * SYNCSTATUSCOUNT
The syncstatuscount message is used to track the layer 2 syncing process.
Definition: protocol.cpp:59
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:34
addrman.h
CMasternodeSync::CMasternodeSync
CMasternodeSync()
Definition: masternode-sync.cpp:22
CChain::Tip
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or NULL if none.
Definition: chain.h:596
budget
CBudgetManager budget
Definition: masternode-budget.cpp:19
CBudgetManager::mapSeenFinalizedBudgetVotes
std::map< uint256, CFinalizedBudgetVote > mapSeenFinalizedBudgetVotes
Definition: masternode-budget.h:191
CBlockIndex
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:162
CMasternodeSync::sumBudgetItemProp
int sumBudgetItemProp
Definition: masternode-sync.h:48
MASTERNODE_SYNC_LIST
#define MASTERNODE_SYNC_LIST
Definition: masternode-sync.h:11
util.h
CMasternodeSync::Process
void Process()
Definition: masternode-sync.cpp:229
CMasternodeSync::mapSeenSyncMNW
std::map< uint256, int > mapSeenSyncMNW
Definition: masternode-sync.h:33