Dash Core  0.12.2.1
P2P Digital Currency
masternode-sync.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2017 The Dash Core developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "activemasternode.h"
6 #include "checkpoints.h"
7 #include "governance.h"
8 #include "validation.h"
9 #include "masternode.h"
10 #include "masternode-payments.h"
11 #include "masternode-sync.h"
12 #include "masternodeman.h"
13 #include "netfulfilledman.h"
14 #include "spork.h"
15 #include "util.h"
16 
19 
21 {
24 }
25 
27 {
32  nTimeLastFailure = 0;
33 }
34 
35 void CMasternodeSync::BumpAssetLastTime(std::string strFuncName)
36 {
37  if(IsSynced() || IsFailed()) return;
39  LogPrint("mnsync", "CMasternodeSync::BumpAssetLastTime -- %s\n", strFuncName);
40 }
41 
43 {
45  {
46  case(MASTERNODE_SYNC_INITIAL): return "MASTERNODE_SYNC_INITIAL";
47  case(MASTERNODE_SYNC_WAITING): return "MASTERNODE_SYNC_WAITING";
48  case(MASTERNODE_SYNC_LIST): return "MASTERNODE_SYNC_LIST";
49  case(MASTERNODE_SYNC_MNW): return "MASTERNODE_SYNC_MNW";
50  case(MASTERNODE_SYNC_GOVERNANCE): return "MASTERNODE_SYNC_GOVERNANCE";
51  case(MASTERNODE_SYNC_FAILED): return "MASTERNODE_SYNC_FAILED";
52  case MASTERNODE_SYNC_FINISHED: return "MASTERNODE_SYNC_FINISHED";
53  default: return "UNKNOWN";
54  }
55 }
56 
58 {
60  {
62  throw std::runtime_error("Can't switch to next asset from failed, should use Reset() first!");
63  break;
65  ClearFulfilledRequests(connman);
67  LogPrintf("CMasternodeSync::SwitchToNextAsset -- Starting %s\n", GetAssetName());
68  break;
70  ClearFulfilledRequests(connman);
71  LogPrintf("CMasternodeSync::SwitchToNextAsset -- Completed %s in %llds\n", GetAssetName(), GetTime() - nTimeAssetSyncStarted);
73  LogPrintf("CMasternodeSync::SwitchToNextAsset -- Starting %s\n", GetAssetName());
74  break;
76  LogPrintf("CMasternodeSync::SwitchToNextAsset -- Completed %s in %llds\n", GetAssetName(), GetTime() - nTimeAssetSyncStarted);
78  LogPrintf("CMasternodeSync::SwitchToNextAsset -- Starting %s\n", GetAssetName());
79  break;
80  case(MASTERNODE_SYNC_MNW):
81  LogPrintf("CMasternodeSync::SwitchToNextAsset -- Completed %s in %llds\n", GetAssetName(), GetTime() - nTimeAssetSyncStarted);
83  LogPrintf("CMasternodeSync::SwitchToNextAsset -- Starting %s\n", GetAssetName());
84  break;
86  LogPrintf("CMasternodeSync::SwitchToNextAsset -- Completed %s in %llds\n", GetAssetName(), GetTime() - nTimeAssetSyncStarted);
89  //try to activate our masternode if possible
91 
92  // TODO: Find out whether we can just use LOCK instead of:
93  // TRY_LOCK(cs_vNodes, lockRecv);
94  // if(lockRecv) { ... }
95 
96  connman.ForEachNode(CConnman::AllNodes, [](CNode* pnode) {
97  netfulfilledman.AddFulfilledRequest(pnode->addr, "full-sync");
98  });
99  LogPrintf("CMasternodeSync::SwitchToNextAsset -- Sync has finished\n");
100 
101  break;
102  }
105  BumpAssetLastTime("CMasternodeSync::SwitchToNextAsset");
106 }
107 
109 {
111  case MASTERNODE_SYNC_INITIAL: return _("Synchroning blockchain...");
112  case MASTERNODE_SYNC_WAITING: return _("Synchronization pending...");
113  case MASTERNODE_SYNC_LIST: return _("Synchronizing masternodes...");
114  case MASTERNODE_SYNC_MNW: return _("Synchronizing masternode payments...");
115  case MASTERNODE_SYNC_GOVERNANCE: return _("Synchronizing governance objects...");
116  case MASTERNODE_SYNC_FAILED: return _("Synchronization failed");
117  case MASTERNODE_SYNC_FINISHED: return _("Synchronization finished");
118  default: return "";
119  }
120 }
121 
122 void CMasternodeSync::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
123 {
124  if (strCommand == NetMsgType::SYNCSTATUSCOUNT) { //Sync status count
125 
126  //do not care about stats if sync process finished or failed
127  if(IsSynced() || IsFailed()) return;
128 
129  int nItemID;
130  int nCount;
131  vRecv >> nItemID >> nCount;
132 
133  LogPrintf("SYNCSTATUSCOUNT -- got inventory count: nItemID=%d nCount=%d peer=%d\n", nItemID, nCount, pfrom->id);
134  }
135 }
136 
138 {
139  // TODO: Find out whether we can just use LOCK instead of:
140  // TRY_LOCK(cs_vNodes, lockRecv);
141  // if(!lockRecv) return;
142 
143  connman.ForEachNode(CConnman::AllNodes, [](CNode* pnode) {
144  netfulfilledman.RemoveFulfilledRequest(pnode->addr, "spork-sync");
145  netfulfilledman.RemoveFulfilledRequest(pnode->addr, "masternode-list-sync");
146  netfulfilledman.RemoveFulfilledRequest(pnode->addr, "masternode-payment-sync");
147  netfulfilledman.RemoveFulfilledRequest(pnode->addr, "governance-sync");
148  netfulfilledman.RemoveFulfilledRequest(pnode->addr, "full-sync");
149  });
150 }
151 
153 {
154  static int nTick = 0;
155  if(nTick++ % MASTERNODE_SYNC_TICK_SECONDS != 0) return;
156 
157  // reset the sync process if the last call to this function was more than 60 minutes ago (client was in sleep mode)
158  static int64_t nTimeLastProcess = GetTime();
159  if(GetTime() - nTimeLastProcess > 60*60) {
160  LogPrintf("CMasternodeSync::HasSyncFailures -- WARNING: no actions for too long, restarting sync...\n");
161  Reset();
162  SwitchToNextAsset(connman);
163  nTimeLastProcess = GetTime();
164  return;
165  }
166  nTimeLastProcess = GetTime();
167 
168  // reset sync status in case of any other sync failure
169  if(IsFailed()) {
170  if(nTimeLastFailure + (1*60) < GetTime()) { // 1 minute cooldown after failed sync
171  LogPrintf("CMasternodeSync::HasSyncFailures -- WARNING: failed to sync, trying again...\n");
172  Reset();
173  SwitchToNextAsset(connman);
174  }
175  return;
176  }
177 
178  // gradually request the rest of the votes after sync finished
179  if(IsSynced()) {
180  std::vector<CNode*> vNodesCopy = connman.CopyNodeVector();
181  governance.RequestGovernanceObjectVotes(vNodesCopy, connman);
182  connman.ReleaseNodeVector(vNodesCopy);
183  return;
184  }
185 
186  // Calculate "progress" for LOG reporting / GUI notification
187  double nSyncProgress = double(nRequestedMasternodeAttempt + (nRequestedMasternodeAssets - 1) * 8) / (8*4);
188  LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nRequestedMasternodeAttempt %d nSyncProgress %f\n", nTick, nRequestedMasternodeAssets, nRequestedMasternodeAttempt, nSyncProgress);
190 
191  std::vector<CNode*> vNodesCopy = connman.CopyNodeVector();
192 
193  BOOST_FOREACH(CNode* pnode, vNodesCopy)
194  {
195  // Don't try to sync any data from outbound "masternode" connections -
196  // they are temporary and should be considered unreliable for a sync process.
197  // Inbound connection this early is most likely a "masternode" connection
198  // initiated from another node, so skip it too.
199  if(pnode->fMasternode || (fMasterNode && pnode->fInbound)) continue;
200 
201  // QUICK MODE (REGTEST ONLY!)
202  if(Params().NetworkIDString() == CBaseChainParams::REGTEST)
203  {
204  if(nRequestedMasternodeAttempt <= 2) {
205  connman.PushMessageWithVersion(pnode, INIT_PROTO_VERSION, NetMsgType::GETSPORKS); //get current network sporks
206  } else if(nRequestedMasternodeAttempt < 4) {
207  mnodeman.DsegUpdate(pnode, connman);
208  } else if(nRequestedMasternodeAttempt < 6) {
209  int nMnCount = mnodeman.CountMasternodes();
210  connman.PushMessage(pnode, NetMsgType::MASTERNODEPAYMENTSYNC, nMnCount); //sync payment votes
211  SendGovernanceSyncRequest(pnode, connman);
212  } else {
214  }
216  connman.ReleaseNodeVector(vNodesCopy);
217  return;
218  }
219 
220  // NORMAL NETWORK MODE - TESTNET/MAINNET
221  {
222  if(netfulfilledman.HasFulfilledRequest(pnode->addr, "full-sync")) {
223  // We already fully synced from this node recently,
224  // disconnect to free this connection slot for another peer.
225  pnode->fDisconnect = true;
226  LogPrintf("CMasternodeSync::ProcessTick -- disconnecting from recently synced peer %d\n", pnode->id);
227  continue;
228  }
229 
230  // SPORK : ALWAYS ASK FOR SPORKS AS WE SYNC
231 
232  if(!netfulfilledman.HasFulfilledRequest(pnode->addr, "spork-sync")) {
233  // always get sporks first, only request once from each peer
234  netfulfilledman.AddFulfilledRequest(pnode->addr, "spork-sync");
235  // get current network sporks
237  LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- requesting sporks from peer %d\n", nTick, nRequestedMasternodeAssets, pnode->id);
238  }
239 
240  // INITIAL TIMEOUT
241 
244  // At this point we know that:
245  // a) there are peers (because we are looping on at least one of them);
246  // b) we waited for at least MASTERNODE_SYNC_TIMEOUT_SECONDS since we reached
247  // the headers tip the last time (i.e. since we switched from
248  // MASTERNODE_SYNC_INITIAL to MASTERNODE_SYNC_WAITING and bumped time);
249  // c) there were no blocks (UpdatedBlockTip, NotifyHeaderTip) or headers (AcceptedBlockHeader)
250  // for at least MASTERNODE_SYNC_TIMEOUT_SECONDS.
251  // We must be at the tip already, let's move to the next asset.
252  SwitchToNextAsset(connman);
253  }
254  }
255 
256  // MNLIST : SYNC MASTERNODE LIST FROM OTHER CONNECTED CLIENTS
257 
259  LogPrint("masternode", "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastBumped %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastBumped, GetTime(), GetTime() - nTimeLastBumped);
260  // check for timeout first
262  LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
263  if (nRequestedMasternodeAttempt == 0) {
264  LogPrintf("CMasternodeSync::ProcessTick -- ERROR: failed to sync %s\n", GetAssetName());
265  // there is no way we can continue without masternode list, fail here and try later
266  Fail();
267  connman.ReleaseNodeVector(vNodesCopy);
268  return;
269  }
270  SwitchToNextAsset(connman);
271  connman.ReleaseNodeVector(vNodesCopy);
272  return;
273  }
274 
275  // only request once from each peer
276  if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-list-sync")) continue;
277  netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-list-sync");
278 
279  if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
281 
282  mnodeman.DsegUpdate(pnode, connman);
283 
284  connman.ReleaseNodeVector(vNodesCopy);
285  return; //this will cause each peer to get one request each six seconds for the various assets we need
286  }
287 
288  // MNW : SYNC MASTERNODE PAYMENT VOTES FROM OTHER CONNECTED CLIENTS
289 
291  LogPrint("mnpayments", "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastBumped %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastBumped, GetTime(), GetTime() - nTimeLastBumped);
292  // check for timeout first
293  // This might take a lot longer than MASTERNODE_SYNC_TIMEOUT_SECONDS due to new blocks,
294  // but that should be OK and it should timeout eventually.
296  LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
297  if (nRequestedMasternodeAttempt == 0) {
298  LogPrintf("CMasternodeSync::ProcessTick -- ERROR: failed to sync %s\n", GetAssetName());
299  // probably not a good idea to proceed without winner list
300  Fail();
301  connman.ReleaseNodeVector(vNodesCopy);
302  return;
303  }
304  SwitchToNextAsset(connman);
305  connman.ReleaseNodeVector(vNodesCopy);
306  return;
307  }
308 
309  // check for data
310  // if mnpayments already has enough blocks and votes, switch to the next asset
311  // try to fetch data from at least two peers though
313  LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- found enough data\n", nTick, nRequestedMasternodeAssets);
314  SwitchToNextAsset(connman);
315  connman.ReleaseNodeVector(vNodesCopy);
316  return;
317  }
318 
319  // only request once from each peer
320  if(netfulfilledman.HasFulfilledRequest(pnode->addr, "masternode-payment-sync")) continue;
321  netfulfilledman.AddFulfilledRequest(pnode->addr, "masternode-payment-sync");
322 
323  if(pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
325 
326  // ask node for all payment votes it has (new nodes will only return votes for future payments)
328  // ask node for missing pieces only (old nodes will not be asked)
329  mnpayments.RequestLowDataPaymentBlocks(pnode, connman);
330 
331  connman.ReleaseNodeVector(vNodesCopy);
332  return; //this will cause each peer to get one request each six seconds for the various assets we need
333  }
334 
335  // GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS
336 
338  LogPrint("gobject", "CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastBumped %lld GetTime() %lld diff %lld\n", nTick, nRequestedMasternodeAssets, nTimeLastBumped, GetTime(), GetTime() - nTimeLastBumped);
339 
340  // check for timeout first
342  LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout\n", nTick, nRequestedMasternodeAssets);
343  if(nRequestedMasternodeAttempt == 0) {
344  LogPrintf("CMasternodeSync::ProcessTick -- WARNING: failed to sync %s\n", GetAssetName());
345  // it's kind of ok to skip this for now, hopefully we'll catch up later?
346  }
347  SwitchToNextAsset(connman);
348  connman.ReleaseNodeVector(vNodesCopy);
349  return;
350  }
351 
352  // only request obj sync once from each peer, then request votes on per-obj basis
353  if(netfulfilledman.HasFulfilledRequest(pnode->addr, "governance-sync")) {
354  int nObjsLeftToAsk = governance.RequestGovernanceObjectVotes(pnode, connman);
355  static int64_t nTimeNoObjectsLeft = 0;
356  // check for data
357  if(nObjsLeftToAsk == 0) {
358  static int nLastTick = 0;
359  static int nLastVotes = 0;
360  if(nTimeNoObjectsLeft == 0) {
361  // asked all objects for votes for the first time
362  nTimeNoObjectsLeft = GetTime();
363  }
364  // make sure the condition below is checked only once per tick
365  if(nLastTick == nTick) continue;
366  if(GetTime() - nTimeNoObjectsLeft > MASTERNODE_SYNC_TIMEOUT_SECONDS &&
367  governance.GetVoteCount() - nLastVotes < std::max(int(0.0001 * nLastVotes), MASTERNODE_SYNC_TICK_SECONDS)
368  ) {
369  // We already asked for all objects, waited for MASTERNODE_SYNC_TIMEOUT_SECONDS
370  // after that and less then 0.01% or MASTERNODE_SYNC_TICK_SECONDS
371  // (i.e. 1 per second) votes were recieved during the last tick.
372  // We can be pretty sure that we are done syncing.
373  LogPrintf("CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- asked for all objects, nothing to do\n", nTick, nRequestedMasternodeAssets);
374  // reset nTimeNoObjectsLeft to be able to use the same condition on resync
375  nTimeNoObjectsLeft = 0;
376  SwitchToNextAsset(connman);
377  connman.ReleaseNodeVector(vNodesCopy);
378  return;
379  }
380  nLastTick = nTick;
381  nLastVotes = governance.GetVoteCount();
382  }
383  continue;
384  }
385  netfulfilledman.AddFulfilledRequest(pnode->addr, "governance-sync");
386 
387  if (pnode->nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION) continue;
389 
390  SendGovernanceSyncRequest(pnode, connman);
391 
392  connman.ReleaseNodeVector(vNodesCopy);
393  return; //this will cause each peer to get one request each six seconds for the various assets we need
394  }
395  }
396  }
397  // looped through all nodes, release them
398  connman.ReleaseNodeVector(vNodesCopy);
399 }
400 
402 {
404  CBloomFilter filter;
405  filter.clear();
406 
407  connman.PushMessage(pnode, NetMsgType::MNGOVERNANCESYNC, uint256(), filter);
408  }
409  else {
411  }
412 }
413 
415 {
416  LogPrint("mnsync", "CMasternodeSync::AcceptedBlockHeader -- pindexNew->nHeight: %d\n", pindexNew->nHeight);
417 
418  if (!IsBlockchainSynced()) {
419  // Postpone timeout each time new block header arrives while we are still syncing blockchain
420  BumpAssetLastTime("CMasternodeSync::AcceptedBlockHeader");
421  }
422 }
423 
424 void CMasternodeSync::NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload, CConnman& connman)
425 {
426  LogPrint("mnsync", "CMasternodeSync::NotifyHeaderTip -- pindexNew->nHeight: %d fInitialDownload=%d\n", pindexNew->nHeight, fInitialDownload);
427 
428  if (IsFailed() || IsSynced() || !pindexBestHeader)
429  return;
430 
431  if (!IsBlockchainSynced()) {
432  // Postpone timeout each time new block arrives while we are still syncing blockchain
433  BumpAssetLastTime("CMasternodeSync::NotifyHeaderTip");
434  }
435 }
436 
437 void CMasternodeSync::UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitialDownload, CConnman& connman)
438 {
439  LogPrint("mnsync", "CMasternodeSync::UpdatedBlockTip -- pindexNew->nHeight: %d fInitialDownload=%d\n", pindexNew->nHeight, fInitialDownload);
440 
441  if (IsFailed() || IsSynced() || !pindexBestHeader)
442  return;
443 
444  if (!IsBlockchainSynced()) {
445  // Postpone timeout each time new block arrives while we are still syncing blockchain
446  BumpAssetLastTime("CMasternodeSync::UpdatedBlockTip");
447  }
448 
449  if (fInitialDownload) {
450  // switched too early
451  if (IsBlockchainSynced()) {
452  Reset();
453  }
454 
455  // no need to check any further while still in IBD mode
456  return;
457  }
458 
459  // Note: since we sync headers first, it should be ok to use this
460  static bool fReachedBestHeader = false;
461  bool fReachedBestHeaderNew = pindexNew->GetBlockHash() == pindexBestHeader->GetBlockHash();
462 
463  if (fReachedBestHeader && !fReachedBestHeaderNew) {
464  // Switching from true to false means that we previousely stuck syncing headers for some reason,
465  // probably initial timeout was not enough,
466  // because there is no way we can update tip not having best header
467  Reset();
468  fReachedBestHeader = false;
469  return;
470  }
471 
472  fReachedBestHeader = fReachedBestHeaderNew;
473 
474  LogPrint("mnsync", "CMasternodeSync::UpdatedBlockTip -- pindexNew->nHeight: %d pindexBestHeader->nHeight: %d fInitialDownload=%d fReachedBestHeader=%d\n",
475  pindexNew->nHeight, pindexBestHeader->nHeight, fInitialDownload, fReachedBestHeader);
476 
477  if (!IsBlockchainSynced() && fReachedBestHeader) {
478  // Reached best header while being in initial mode.
479  // We must be at the tip already, let's move to the next asset.
480  SwitchToNextAsset(connman);
481  }
482 }
int RequestGovernanceObjectVotes(CNode *pnode, CConnman &connman)
CMasternodeMan mnodeman
CMasternodeSync masternodeSync
void AcceptedBlockHeader(const CBlockIndex *pindexNew)
void PushMessageWithVersion(CNode *pnode, int nVersion, const std::string &sCommand, Args &&... args)
Definition: net.h:193
CActiveMasternode activeMasternode
bool fDisconnect
Definition: net.h:705
void AddFulfilledRequest(CAddress addr, std::string strRequest)
static const int MIN_GOVERNANCE_PEER_PROTO_VERSION
void ProcessTick(CConnman &connman)
int GetVoteCount() const
Definition: governance.cpp:77
CAddress addr
Definition: net.h:688
Definition: net.h:108
NodeId id
Definition: net.h:718
const char * SYNCSTATUSCOUNT
Definition: protocol.cpp:63
int nRequestedMasternodeAssets
int64_t nTimeAssetSyncStarted
static const int MASTERNODE_SYNC_FINISHED
void RequestLowDataPaymentBlocks(CNode *pnode, CConnman &connman)
static const int MASTERNODE_SYNC_GOVERNANCE
bool HasFulfilledRequest(CAddress addr, std::string strRequest)
void UpdatedBlockTip(const CBlockIndex *pindexNew, bool fInitialDownload, CConnman &connman)
static const int MASTERNODE_SYNC_MNW
void SendGovernanceSyncRequest(CNode *pnode, CConnman &connman)
bool fMasterNode
Definition: util.cpp:108
const char * MNGOVERNANCESYNC
Definition: protocol.cpp:64
int nRequestedMasternodeAttempt
void ReleaseNodeVector(const std::vector< CNode *> &vecNodes)
Definition: net.cpp:2908
#define LogPrintf(...)
Definition: util.h:98
Definition: net.h:661
CMasternodePayments mnpayments
static const int MASTERNODE_SYNC_INITIAL
static int LogPrint(const char *category, const char *format)
Definition: util.h:126
CBlockIndex * pindexBestHeader
Definition: validation.cpp:66
std::string GetSyncStatus()
static const int MASTERNODE_SYNC_TIMEOUT_SECONDS
std::string GetAssetName()
static const int INIT_PROTO_VERSION
initial proto version, to be increased after version/verack negotiation
Definition: version.h:16
const char * GETSPORKS
Definition: protocol.cpp:42
bool fInbound
Definition: net.h:702
CClientUIInterface uiInterface
Definition: init.cpp:130
static const int MASTERNODE_SYNC_LIST
int64_t nTimeLastFailure
int CountMasternodes(int nProtocolVersion=-1)
bool fMasternode
Definition: net.h:712
std::vector< CNode * > CopyNodeVector()
Definition: net.cpp:2896
static const int GOVERNANCE_FILTER_PROTO_VERSION
static const int MASTERNODE_SYNC_WAITING
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv)
void ManageState(CConnman &connman)
Manage state of active Masternode.
static const int MASTERNODE_SYNC_TICK_SECONDS
void NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload, CConnman &connman)
void SwitchToNextAsset(CConnman &connman)
const CChainParams & Params()
int64_t nTimeLastBumped
void RemoveFulfilledRequest(CAddress addr, std::string strRequest)
bool IsBlockchainSynced()
uint256 GetBlockHash() const
Definition: chain.h:218
CNetFulfilledRequestManager netfulfilledman
void ClearFulfilledRequests(CConnman &connman)
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:20
const char * MASTERNODEPAYMENTSYNC
Definition: protocol.cpp:45
CGovernanceManager governance
Definition: governance.cpp:17
void BumpAssetLastTime(std::string strFuncName)
boost::signals2::signal< void(double nSyncProgress)> NotifyAdditionalDataSyncProgressChanged
Definition: ui_interface.h:113
void clear()
Definition: bloom.cpp:118
static constexpr const CAllNodes AllNodes
Definition: net.h:160
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:113
void DsegUpdate(CNode *pnode, CConnman &connman)
Count Masternodes by network type - NET_IPV4, NET_IPV6, NET_TOR.
void ForEachNode(const Condition &cond, Callable &&func)
Definition: net.h:239
static const int MASTERNODE_SYNC_FAILED
void PushMessage(CNode *pnode, const std::string &sCommand, Args &&... args)
Definition: net.h:199
std::atomic< int > nVersion
Definition: net.h:692
std::string _(const char *psz)
Definition: util.h:84
static const std::string REGTEST