2016-12-20 14:26:45 +01:00
// Copyright (c) 2014-2017 The Dash Core developers
2015-07-15 04:44:58 +02:00
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2015-07-29 05:26:08 +02:00
# include "activemasternode.h"
2016-10-10 23:11:20 +02:00
# include "checkpoints.h"
2016-04-15 04:54:11 +02:00
# include "governance.h"
2016-08-28 12:12:14 +02:00
# include "main.h"
2015-07-15 04:44:58 +02:00
# include "masternode.h"
2016-08-28 12:12:14 +02:00
# include "masternode-payments.h"
# include "masternode-sync.h"
2015-07-17 11:17:15 +02:00
# include "masternodeman.h"
2016-09-27 09:50:04 +02:00
# include "netfulfilledman.h"
2015-08-15 15:27:26 +02:00
# include "spork.h"
2015-07-15 04:44:58 +02:00
# include "util.h"
class CMasternodeSync ;
CMasternodeSync masternodeSync ;
2017-01-11 00:33:14 +01:00
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 ;
}
2016-12-26 07:44:36 +01:00
bool CMasternodeSync : : IsBlockchainSynced ( bool fBlockAccepted )
2015-07-26 21:37:01 +02:00
{
2015-08-04 01:23:36 +02:00
static bool fBlockchainSynced = false ;
2016-10-22 18:52:14 +02:00
static int64_t nTimeLastProcess = GetTime ( ) ;
2016-12-26 07:44:36 +01:00
static int nSkipped = 0 ;
static bool fFirstBlockAccepted = false ;
2015-08-04 23:15:24 +02:00
2015-08-11 23:54:42 +02:00
// if the last call to this function was more than 60 minutes ago (client was in sleep mode) reset the sync process
2016-10-22 18:52:14 +02:00
if ( GetTime ( ) - nTimeLastProcess > 60 * 60 ) {
2015-08-04 23:15:24 +02:00
Reset ( ) ;
fBlockchainSynced = false ;
}
2016-12-26 07:44:36 +01:00
if ( ! pCurrentBlockIndex | | ! pindexBestHeader | | fImporting | | fReindex ) return false ;
if ( fBlockAccepted ) {
// this should be only triggered while we are still syncing
if ( ! IsSynced ( ) ) {
// we are trying to download smth, reset blockchain sync status
if ( fDebug ) LogPrintf ( " CMasternodeSync::IsBlockchainSynced -- reset \n " ) ;
fFirstBlockAccepted = true ;
fBlockchainSynced = false ;
nTimeLastProcess = GetTime ( ) ;
return false ;
}
} else {
// skip if we already checked less than 1 tick ago
if ( GetTime ( ) - nTimeLastProcess < MASTERNODE_SYNC_TICK_SECONDS ) {
nSkipped + + ;
return fBlockchainSynced ;
}
}
if ( fDebug ) LogPrintf ( " CMasternodeSync::IsBlockchainSynced -- state before check: %ssynced, skipped %d times \n " , fBlockchainSynced ? " " : " not " , nSkipped ) ;
2016-10-22 18:52:14 +02:00
nTimeLastProcess = GetTime ( ) ;
2016-12-26 07:44:36 +01:00
nSkipped = 0 ;
2015-08-04 23:15:24 +02:00
2015-08-04 01:23:36 +02:00
if ( fBlockchainSynced ) return true ;
2016-12-26 07:44:36 +01:00
2016-10-10 23:11:20 +02:00
if ( fCheckpointsEnabled & & pCurrentBlockIndex - > nHeight < Checkpoints : : GetTotalBlocksEstimate ( Params ( ) . Checkpoints ( ) ) )
return false ;
2015-08-04 01:23:36 +02:00
2017-01-11 00:33:14 +01:00
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 ) ;
2016-12-26 07:44:36 +01:00
// wait for at least one new block to be accepted
if ( ! fFirstBlockAccepted ) return false ;
2016-09-27 10:56:10 +02:00
// same as !IsInitialBlockDownload() but no cs_main needed here
2016-12-02 13:53:28 +01:00
int64_t nMaxBlockTime = std : : max ( pCurrentBlockIndex - > GetBlockTime ( ) , pindexBestHeader - > GetBlockTime ( ) ) ;
2016-09-27 10:56:10 +02:00
fBlockchainSynced = pindexBestHeader - > nHeight - pCurrentBlockIndex - > nHeight < 24 * 6 & &
GetTime ( ) - nMaxBlockTime < Params ( ) . MaxTipAge ( ) ;
2015-08-03 22:42:18 +02:00
2016-09-27 10:56:10 +02:00
return fBlockchainSynced ;
2015-07-26 21:37:01 +02:00
}
2016-08-28 12:12:14 +02:00
void CMasternodeSync : : Fail ( )
{
nTimeLastFailure = GetTime ( ) ;
nRequestedMasternodeAssets = MASTERNODE_SYNC_FAILED ;
}
2015-08-04 20:21:27 +02:00
void CMasternodeSync : : Reset ( )
2016-08-17 09:08:25 +02:00
{
2016-08-28 12:12:14 +02:00
nRequestedMasternodeAssets = MASTERNODE_SYNC_INITIAL ;
nRequestedMasternodeAttempt = 0 ;
nTimeAssetSyncStarted = GetTime ( ) ;
nTimeLastMasternodeList = GetTime ( ) ;
2016-09-21 16:45:29 +02:00
nTimeLastPaymentVote = GetTime ( ) ;
2016-12-06 17:40:37 +01:00
nTimeLastGovernanceItem = GetTime ( ) ;
2016-08-28 12:12:14 +02:00
nTimeLastFailure = 0 ;
nCountFailures = 0 ;
2015-07-15 04:44:58 +02:00
}
2016-06-08 08:57:16 +02:00
std : : string CMasternodeSync : : GetAssetName ( )
{
2016-08-28 12:12:14 +02:00
switch ( nRequestedMasternodeAssets )
2016-06-08 08:57:16 +02:00
{
2016-08-28 12:12:14 +02:00
case ( MASTERNODE_SYNC_INITIAL ) : return " MASTERNODE_SYNC_INITIAL " ;
case ( MASTERNODE_SYNC_SPORKS ) : return " MASTERNODE_SYNC_SPORKS " ;
case ( MASTERNODE_SYNC_LIST ) : return " MASTERNODE_SYNC_LIST " ;
case ( MASTERNODE_SYNC_MNW ) : return " MASTERNODE_SYNC_MNW " ;
case ( MASTERNODE_SYNC_GOVERNANCE ) : return " MASTERNODE_SYNC_GOVERNANCE " ;
case ( MASTERNODE_SYNC_FAILED ) : return " MASTERNODE_SYNC_FAILED " ;
case MASTERNODE_SYNC_FINISHED : return " MASTERNODE_SYNC_FINISHED " ;
default : return " UNKNOWN " ;
2016-06-08 08:57:16 +02:00
}
}
2016-08-28 12:12:14 +02:00
void CMasternodeSync : : SwitchToNextAsset ( )
2015-07-15 04:44:58 +02:00
{
2016-08-28 12:12:14 +02:00
switch ( nRequestedMasternodeAssets )
2015-07-15 04:44:58 +02:00
{
2016-08-29 21:11:34 +02:00
case ( MASTERNODE_SYNC_FAILED ) :
throw std : : runtime_error ( " Can't switch to next asset from failed, should use Reset() first! " ) ;
break ;
2015-07-17 12:26:24 +02:00
case ( MASTERNODE_SYNC_INITIAL ) :
2016-09-27 09:50:04 +02:00
ClearFulfilledRequests ( ) ;
2016-08-28 12:12:14 +02:00
nRequestedMasternodeAssets = MASTERNODE_SYNC_SPORKS ;
2015-07-17 05:03:42 +02:00
break ;
2015-07-17 12:26:24 +02:00
case ( MASTERNODE_SYNC_SPORKS ) :
2016-08-28 12:12:14 +02:00
nTimeLastMasternodeList = GetTime ( ) ;
nRequestedMasternodeAssets = MASTERNODE_SYNC_LIST ;
2015-07-15 04:44:58 +02:00
break ;
case ( MASTERNODE_SYNC_LIST ) :
2016-09-21 16:45:29 +02:00
nTimeLastPaymentVote = GetTime ( ) ;
2016-08-28 12:12:14 +02:00
nRequestedMasternodeAssets = MASTERNODE_SYNC_MNW ;
2015-07-15 04:44:58 +02:00
break ;
case ( MASTERNODE_SYNC_MNW ) :
2016-12-06 17:40:37 +01:00
nTimeLastGovernanceItem = GetTime ( ) ;
2016-08-28 12:12:14 +02:00
nRequestedMasternodeAssets = MASTERNODE_SYNC_GOVERNANCE ;
2015-07-15 04:44:58 +02:00
break ;
2016-06-08 08:57:16 +02:00
case ( MASTERNODE_SYNC_GOVERNANCE ) :
2016-08-28 12:12:14 +02:00
LogPrintf ( " CMasternodeSync::SwitchToNextAsset -- Sync has finished \n " ) ;
nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED ;
2016-02-19 19:09:54 +01:00
uiInterface . NotifyAdditionalDataSyncProgressChanged ( 1 ) ;
2016-08-05 18:25:03 +02:00
//try to activate our masternode if possible
2016-08-05 21:49:45 +02:00
activeMasternode . ManageState ( ) ;
2016-09-27 09:50:04 +02:00
TRY_LOCK ( cs_vNodes , lockRecv ) ;
if ( ! lockRecv ) return ;
BOOST_FOREACH ( CNode * pnode , vNodes ) {
netfulfilledman . AddFulfilledRequest ( pnode - > addr , " full-sync " ) ;
}
2015-07-15 04:44:58 +02:00
break ;
}
2016-08-28 12:12:14 +02:00
nRequestedMasternodeAttempt = 0 ;
nTimeAssetSyncStarted = GetTime ( ) ;
2015-07-15 04:44:58 +02:00
}
2015-08-15 17:53:55 +02:00
std : : string CMasternodeSync : : GetSyncStatus ( )
{
2016-08-28 12:12:14 +02:00
switch ( masternodeSync . nRequestedMasternodeAssets ) {
case MASTERNODE_SYNC_INITIAL : return _ ( " Synchronization pending... " ) ;
case MASTERNODE_SYNC_SPORKS : return _ ( " Synchronizing sporks... " ) ;
case MASTERNODE_SYNC_LIST : return _ ( " Synchronizing masternodes... " ) ;
2016-09-21 16:45:29 +02:00
case MASTERNODE_SYNC_MNW : return _ ( " Synchronizing masternode payments... " ) ;
2016-08-28 12:12:14 +02:00
case MASTERNODE_SYNC_GOVERNANCE : return _ ( " Synchronizing governance objects... " ) ;
case MASTERNODE_SYNC_FAILED : return _ ( " Synchronization failed " ) ;
case MASTERNODE_SYNC_FINISHED : return _ ( " Synchronization finished " ) ;
default : return " " ;
2015-08-15 17:53:55 +02:00
}
}
2015-07-29 06:16:11 +02:00
void CMasternodeSync : : ProcessMessage ( CNode * pfrom , std : : string & strCommand , CDataStream & vRecv )
{
2016-02-17 23:18:57 +01:00
if ( strCommand = = NetMsgType : : SYNCSTATUSCOUNT ) { //Sync status count
2015-07-29 06:16:11 +02:00
2016-08-29 21:11:34 +02:00
//do not care about stats if sync process finished or failed
if ( IsSynced ( ) | | IsFailed ( ) ) return ;
2015-07-29 06:16:11 +02:00
2016-09-11 19:49:40 +02:00
int nItemID ;
int nCount ;
vRecv > > nItemID > > nCount ;
2016-10-22 18:52:14 +02:00
LogPrintf ( " SYNCSTATUSCOUNT -- got inventory count: nItemID=%d nCount=%d peer=%d \n " , nItemID , nCount , pfrom - > id ) ;
2015-07-30 10:51:48 +02:00
}
}
2016-09-27 09:50:04 +02:00
void CMasternodeSync : : ClearFulfilledRequests ( )
2015-07-30 10:51:48 +02:00
{
2015-07-30 15:44:18 +02:00
TRY_LOCK ( cs_vNodes , lockRecv ) ;
if ( ! lockRecv ) return ;
2015-07-30 10:51:48 +02:00
BOOST_FOREACH ( CNode * pnode , vNodes )
{
2016-09-27 09:50:04 +02:00
netfulfilledman . RemoveFulfilledRequest ( pnode - > addr , " spork-sync " ) ;
netfulfilledman . RemoveFulfilledRequest ( pnode - > addr , " masternode-list-sync " ) ;
netfulfilledman . RemoveFulfilledRequest ( pnode - > addr , " masternode-payment-sync " ) ;
netfulfilledman . RemoveFulfilledRequest ( pnode - > addr , " governance-sync " ) ;
netfulfilledman . RemoveFulfilledRequest ( pnode - > addr , " full-sync " ) ;
2015-07-29 06:16:11 +02:00
}
}
2016-08-28 12:12:14 +02:00
void CMasternodeSync : : ProcessTick ( )
2015-07-15 04:44:58 +02:00
{
2016-08-28 12:12:14 +02:00
static int nTick = 0 ;
2016-12-26 07:44:36 +01:00
if ( nTick + + % MASTERNODE_SYNC_TICK_SECONDS ! = 0 ) return ;
2016-03-02 22:20:04 +01:00
if ( ! pCurrentBlockIndex ) return ;
2016-02-04 20:29:09 +01:00
//the actual count of masternodes we have currently
2016-10-17 20:54:28 +02:00
int nMnCount = mnodeman . CountMasternodes ( ) ;
2016-10-22 18:52:14 +02:00
if ( fDebug ) LogPrintf ( " CMasternodeSync::ProcessTick -- nTick %d nMnCount %d \n " , nTick , nMnCount ) ;
2015-07-19 10:19:54 +02:00
2016-02-04 20:29:09 +01:00
// RESET SYNCING INCASE OF FAILURE
{
if ( IsSynced ( ) ) {
2016-08-17 09:08:25 +02:00
/*
2016-02-04 20:29:09 +01:00
Resync if we lose all masternodes from sleep / wake or failure to sync originally
*/
2016-03-08 12:15:22 +01:00
if ( nMnCount = = 0 ) {
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- WARNING: not enough data, restarting sync \n " ) ;
2016-02-04 20:29:09 +01:00
Reset ( ) ;
2016-06-08 08:57:16 +02:00
} else {
//if syncing is complete and we have masternodes, return
2016-08-17 09:08:25 +02:00
return ;
2016-06-08 08:57:16 +02:00
}
2016-02-04 20:29:09 +01:00
}
//try syncing again
2016-08-28 12:12:14 +02:00
if ( IsFailed ( ) ) {
2016-08-29 21:11:34 +02:00
if ( nTimeLastFailure + ( 1 * 60 ) < GetTime ( ) ) { // 1 minute cooldown after failed sync
2016-08-28 12:12:14 +02:00
Reset ( ) ;
2016-08-29 21:11:34 +02:00
}
2015-07-19 10:19:54 +02:00
return ;
2016-02-04 20:29:09 +01:00
}
2015-07-18 01:49:41 +02:00
}
2015-07-15 04:44:58 +02:00
2016-06-08 08:57:16 +02:00
// INITIAL SYNC SETUP / LOG REPORTING
2016-08-28 12:12:14 +02:00
double nSyncProgress = double ( nRequestedMasternodeAttempt + ( nRequestedMasternodeAssets - 1 ) * 8 ) / ( 8 * 4 ) ;
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nRequestedMasternodeAttempt %d nSyncProgress %f \n " , nTick , nRequestedMasternodeAssets , nRequestedMasternodeAttempt , nSyncProgress ) ;
2016-08-05 18:25:03 +02:00
uiInterface . NotifyAdditionalDataSyncProgressChanged ( nSyncProgress ) ;
2015-07-17 11:17:15 +02:00
2016-08-05 18:25:03 +02:00
// sporks synced but blockchain is not, wait until we're almost at a recent block to continue
if ( Params ( ) . NetworkIDString ( ) ! = CBaseChainParams : : REGTEST & &
2016-10-22 18:52:14 +02:00
! IsBlockchainSynced ( ) & & nRequestedMasternodeAssets > MASTERNODE_SYNC_SPORKS )
{
LogPrintf ( " CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nRequestedMasternodeAttempt %d -- blockchain is not synced yet \n " , nTick , nRequestedMasternodeAssets , nRequestedMasternodeAttempt ) ;
2016-12-26 07:44:36 +01:00
nTimeLastMasternodeList = GetTime ( ) ;
nTimeLastPaymentVote = GetTime ( ) ;
nTimeLastGovernanceItem = GetTime ( ) ;
2016-10-22 18:52:14 +02:00
return ;
}
2015-07-15 04:44:58 +02:00
2016-09-27 11:02:57 +02:00
if ( nRequestedMasternodeAssets = = MASTERNODE_SYNC_INITIAL | |
( nRequestedMasternodeAssets = = MASTERNODE_SYNC_SPORKS & & IsBlockchainSynced ( ) ) )
{
2016-08-29 21:11:34 +02:00
SwitchToNextAsset ( ) ;
}
2015-07-30 15:44:18 +02:00
2016-11-28 15:21:50 +01:00
std : : vector < CNode * > vNodesCopy ;
{
LOCK ( cs_vNodes ) ;
vNodesCopy = vNodes ;
BOOST_FOREACH ( CNode * pnode , vNodesCopy )
pnode - > AddRef ( ) ;
}
BOOST_FOREACH ( CNode * pnode , vNodesCopy )
2015-07-17 11:17:15 +02:00
{
2016-06-08 08:57:16 +02:00
// QUICK MODE (REGTEST ONLY!)
if ( Params ( ) . NetworkIDString ( ) = = CBaseChainParams : : REGTEST )
{
2016-08-28 12:12:14 +02:00
if ( nRequestedMasternodeAttempt < = 2 ) {
2016-02-17 23:18:57 +01:00
pnode - > PushMessage ( NetMsgType : : GETSPORKS ) ; //get current network sporks
2016-08-28 12:12:14 +02:00
} else if ( nRequestedMasternodeAttempt < 4 ) {
2016-08-17 09:08:25 +02:00
mnodeman . DsegUpdate ( pnode ) ;
2016-08-28 12:12:14 +02:00
} else if ( nRequestedMasternodeAttempt < 6 ) {
2016-10-17 20:54:28 +02:00
int nMnCount = mnodeman . CountMasternodes ( ) ;
2016-09-21 16:45:29 +02:00
pnode - > PushMessage ( NetMsgType : : MASTERNODEPAYMENTSYNC , nMnCount ) ; //sync payment votes
2016-02-02 16:28:56 +01:00
uint256 n = uint256 ( ) ;
2016-06-08 08:57:16 +02:00
pnode - > PushMessage ( NetMsgType : : MNGOVERNANCESYNC , n ) ; //sync masternode votes
2015-07-23 23:35:14 +02:00
} else {
2016-08-28 12:12:14 +02:00
nRequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED ;
2015-07-17 11:17:15 +02:00
}
2016-08-28 12:12:14 +02:00
nRequestedMasternodeAttempt + + ;
2016-11-28 15:21:50 +01:00
ReleaseNodes ( vNodesCopy ) ;
2015-07-19 01:25:52 +02:00
return ;
}
2016-06-08 08:57:16 +02:00
// NORMAL NETWORK MODE - TESTNET/MAINNET
2016-08-17 09:08:25 +02:00
{
2016-09-27 09:50:04 +02:00
if ( netfulfilledman . HasFulfilledRequest ( pnode - > addr , " full-sync " ) ) {
// we already fully synced from this node recently,
// disconnect to free this connection slot for a new node
pnode - > fDisconnect = true ;
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- disconnecting from recently synced peer %d \n " , pnode - > id ) ;
2016-09-27 09:50:04 +02:00
continue ;
}
2017-01-11 00:33:14 +01:00
// Make sure this peer is presumably at the same height
if ( ! CheckNodeHeight ( pnode , true ) ) continue ;
2017-01-01 19:30:40 +01:00
2016-06-08 08:57:16 +02:00
// SPORK : ALWAYS ASK FOR SPORKS AS WE SYNC (we skip this mode now)
2015-07-20 20:56:02 +02:00
2016-09-27 09:50:04 +02:00
if ( ! netfulfilledman . HasFulfilledRequest ( pnode - > addr , " spork-sync " ) ) {
2016-08-05 18:25:03 +02:00
// only request once from each peer
2016-09-27 09:50:04 +02:00
netfulfilledman . AddFulfilledRequest ( pnode - > addr , " spork-sync " ) ;
2016-06-08 08:57:16 +02:00
// get current network sporks
2016-08-17 09:08:25 +02:00
pnode - > PushMessage ( NetMsgType : : GETSPORKS ) ;
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- requesting sporks from peer %d \n " , nTick , nRequestedMasternodeAssets , pnode - > id ) ;
2016-08-05 18:25:03 +02:00
continue ; // always get sporks first, switch to the next node without waiting for the next tick
2016-06-08 08:57:16 +02:00
}
2016-05-24 21:20:10 +02:00
2016-08-05 18:25:03 +02:00
// MNLIST : SYNC MASTERNODE LIST FROM OTHER CONNECTED CLIENTS
2015-07-15 04:44:58 +02:00
2016-08-28 12:12:14 +02:00
if ( nRequestedMasternodeAssets = = MASTERNODE_SYNC_LIST ) {
2016-10-22 18:52:14 +02:00
LogPrint ( " masternode " , " CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastMasternodeList %lld GetTime() %lld diff %lld \n " , nTick , nRequestedMasternodeAssets , nTimeLastMasternodeList , GetTime ( ) , GetTime ( ) - nTimeLastMasternodeList ) ;
2016-08-05 18:25:03 +02:00
// check for timeout first
2016-08-28 12:12:14 +02:00
if ( nTimeLastMasternodeList < GetTime ( ) - MASTERNODE_SYNC_TIMEOUT_SECONDS ) {
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout \n " , nTick , nRequestedMasternodeAssets ) ;
2016-08-28 12:12:14 +02:00
if ( nRequestedMasternodeAttempt = = 0 ) {
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- ERROR: failed to sync %s \n " , GetAssetName ( ) ) ;
2016-08-29 21:11:34 +02:00
// there is no way we can continue without masternode list, fail here and try later
Fail ( ) ;
2016-11-28 15:21:50 +01:00
ReleaseNodes ( vNodesCopy ) ;
2016-08-29 21:11:34 +02:00
return ;
2016-08-28 12:12:14 +02:00
}
SwitchToNextAsset ( ) ;
2016-11-28 15:21:50 +01:00
ReleaseNodes ( vNodesCopy ) ;
2015-08-15 15:27:26 +02:00
return ;
}
2016-08-05 18:25:03 +02:00
// only request once from each peer
2016-09-27 09:50:04 +02:00
if ( netfulfilledman . HasFulfilledRequest ( pnode - > addr , " masternode-list-sync " ) ) continue ;
netfulfilledman . AddFulfilledRequest ( pnode - > addr , " masternode-list-sync " ) ;
2015-07-27 05:41:25 +02:00
2016-08-05 18:25:03 +02:00
if ( pnode - > nVersion < mnpayments . GetMinMasternodePaymentsProto ( ) ) continue ;
2016-08-28 12:12:14 +02:00
nRequestedMasternodeAttempt + + ;
2015-07-21 04:24:43 +02:00
2016-08-05 18:25:03 +02:00
mnodeman . DsegUpdate ( pnode ) ;
2016-11-28 15:21:50 +01:00
ReleaseNodes ( vNodesCopy ) ;
2016-02-04 23:48:23 +01:00
return ; //this will cause each peer to get one request each six seconds for the various assets we need
}
2015-07-15 04:44:58 +02:00
2016-09-21 16:45:29 +02:00
// MNW : SYNC MASTERNODE PAYMENT VOTES FROM OTHER CONNECTED CLIENTS
2016-05-24 21:20:10 +02:00
2016-08-28 12:12:14 +02:00
if ( nRequestedMasternodeAssets = = MASTERNODE_SYNC_MNW ) {
2016-10-22 18:52:14 +02:00
LogPrint ( " mnpayments " , " CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastPaymentVote %lld GetTime() %lld diff %lld \n " , nTick , nRequestedMasternodeAssets , nTimeLastPaymentVote , GetTime ( ) , GetTime ( ) - nTimeLastPaymentVote ) ;
2016-08-05 18:25:03 +02:00
// check for timeout first
2016-08-28 12:12:14 +02:00
// This might take a lot longer than MASTERNODE_SYNC_TIMEOUT_SECONDS minutes due to new blocks,
2016-08-05 18:25:03 +02:00
// but that should be OK and it should timeout eventually.
2016-09-21 16:45:29 +02:00
if ( nTimeLastPaymentVote < GetTime ( ) - MASTERNODE_SYNC_TIMEOUT_SECONDS ) {
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout \n " , nTick , nRequestedMasternodeAssets ) ;
2016-08-28 12:12:14 +02:00
if ( nRequestedMasternodeAttempt = = 0 ) {
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- ERROR: failed to sync %s \n " , GetAssetName ( ) ) ;
2016-08-29 21:11:34 +02:00
// probably not a good idea to proceed without winner list
Fail ( ) ;
2016-11-28 15:21:50 +01:00
ReleaseNodes ( vNodesCopy ) ;
2016-08-29 21:11:34 +02:00
return ;
2016-08-28 12:12:14 +02:00
}
SwitchToNextAsset ( ) ;
2016-11-28 15:21:50 +01:00
ReleaseNodes ( vNodesCopy ) ;
2015-07-15 04:44:58 +02:00
return ;
}
2016-08-05 18:25:03 +02:00
// check for data
2016-08-28 12:12:14 +02:00
// if mnpayments already has enough blocks and votes, switch to the next asset
// try to fetch data from at least two peers though
2016-09-21 17:32:42 +02:00
if ( nRequestedMasternodeAttempt > 1 & & mnpayments . IsEnoughData ( ) ) {
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- found enough data \n " , nTick , nRequestedMasternodeAssets ) ;
2016-08-28 12:12:14 +02:00
SwitchToNextAsset ( ) ;
2016-11-28 15:21:50 +01:00
ReleaseNodes ( vNodesCopy ) ;
2016-05-29 20:35:09 +02:00
return ;
2015-08-14 05:56:58 +02:00
}
2016-08-05 18:25:03 +02:00
// only request once from each peer
2016-09-27 09:50:04 +02:00
if ( netfulfilledman . HasFulfilledRequest ( pnode - > addr , " masternode-payment-sync " ) ) continue ;
netfulfilledman . AddFulfilledRequest ( pnode - > addr , " masternode-payment-sync " ) ;
2016-02-04 20:29:09 +01:00
2016-08-28 12:12:14 +02:00
if ( pnode - > nVersion < mnpayments . GetMinMasternodePaymentsProto ( ) ) continue ;
nRequestedMasternodeAttempt + + ;
2016-02-04 20:29:09 +01:00
2016-09-21 16:45:29 +02:00
// ask node for all payment votes it has (new nodes will only return votes for future payments)
pnode - > PushMessage ( NetMsgType : : MASTERNODEPAYMENTSYNC , mnpayments . GetStorageLimit ( ) ) ;
2016-09-19 00:23:52 +02:00
// ask node for missing pieces only (old nodes will not be asked)
mnpayments . RequestLowDataPaymentBlocks ( pnode ) ;
2016-02-04 20:29:09 +01:00
2016-11-28 15:21:50 +01:00
ReleaseNodes ( vNodesCopy ) ;
2016-02-04 23:48:23 +01:00
return ; //this will cause each peer to get one request each six seconds for the various assets we need
}
2016-06-08 08:57:16 +02:00
2016-08-05 18:25:03 +02:00
// GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS
2016-06-08 08:57:16 +02:00
2016-08-28 12:12:14 +02:00
if ( nRequestedMasternodeAssets = = MASTERNODE_SYNC_GOVERNANCE ) {
2016-10-22 18:52:14 +02:00
LogPrint ( " mnpayments " , " CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d nTimeLastPaymentVote %lld GetTime() %lld diff %lld \n " , nTick , nRequestedMasternodeAssets , nTimeLastPaymentVote , GetTime ( ) , GetTime ( ) - nTimeLastPaymentVote ) ;
2016-08-05 18:25:03 +02:00
// check for timeout first
2016-12-06 17:40:37 +01:00
if ( GetTime ( ) - nTimeLastGovernanceItem > MASTERNODE_SYNC_TIMEOUT_SECONDS ) {
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- nTick %d nRequestedMasternodeAssets %d -- timeout \n " , nTick , nRequestedMasternodeAssets ) ;
2016-08-28 12:12:14 +02:00
if ( nRequestedMasternodeAttempt = = 0 ) {
2016-10-22 18:52:14 +02:00
LogPrintf ( " CMasternodeSync::ProcessTick -- WARNING: failed to sync %s \n " , GetAssetName ( ) ) ;
2016-08-28 12:12:14 +02:00
// it's kind of ok to skip this for now, hopefully we'll catch up later?
}
SwitchToNextAsset ( ) ;
2016-11-28 15:21:50 +01:00
ReleaseNodes ( vNodesCopy ) ;
2016-08-05 18:25:03 +02:00
return ;
}
2016-05-24 21:20:10 +02:00
2016-08-05 18:25:03 +02:00
// check for data
2016-08-28 12:12:14 +02:00
// if(nCountBudgetItemProp > 0 && nCountBudgetItemFin)
2016-05-24 21:25:33 +02:00
// {
2016-08-28 12:12:14 +02:00
// if(governance.CountProposalInventoryItems() >= (nSumBudgetItemProp / nCountBudgetItemProp)*0.9)
2016-05-24 21:25:33 +02:00
// {
2016-08-28 12:12:14 +02:00
// if(governance.CountFinalizedInventoryItems() >= (nSumBudgetItemFin / nCountBudgetItemFin)*0.9)
2016-05-24 21:25:33 +02:00
// {
2016-08-28 12:12:14 +02:00
// SwitchToNextAsset();
2016-05-24 21:25:33 +02:00
// return;
// }
// }
// }
2016-08-05 18:25:03 +02:00
// only request once from each peer
2016-09-27 09:50:04 +02:00
if ( netfulfilledman . HasFulfilledRequest ( pnode - > addr , " governance-sync " ) ) continue ;
netfulfilledman . AddFulfilledRequest ( pnode - > addr , " governance-sync " ) ;
2016-05-24 21:25:33 +02:00
2016-09-28 22:03:54 +02:00
if ( pnode - > nVersion < MIN_GOVERNANCE_PEER_PROTO_VERSION ) continue ;
2016-08-28 12:12:14 +02:00
nRequestedMasternodeAttempt + + ;
2016-05-24 21:25:33 +02:00
2016-08-05 18:25:03 +02:00
pnode - > PushMessage ( NetMsgType : : MNGOVERNANCESYNC , uint256 ( ) ) ; //sync masternode votes
2016-11-28 15:21:50 +01:00
ReleaseNodes ( vNodesCopy ) ;
2016-05-24 21:25:33 +02:00
return ; //this will cause each peer to get one request each six seconds for the various assets we need
}
}
2015-07-15 04:44:58 +02:00
}
2016-12-05 11:06:51 +01:00
// looped through all nodes, release them
ReleaseNodes ( vNodesCopy ) ;
2015-07-17 11:17:15 +02:00
}
2016-03-02 22:20:04 +01:00
void CMasternodeSync : : UpdatedBlockTip ( const CBlockIndex * pindex )
{
pCurrentBlockIndex = pindex ;
}