2016-02-02 16:28:56 +01:00
// Copyright (c) 2014-2016 The Dash Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2014-12-09 02:17:57 +01:00
# include "activemasternode.h"
2015-04-17 17:10:38 +02:00
# include "masternode.h"
2016-01-24 20:05:31 +01:00
# include "masternode-sync.h"
# include "masternodeman.h"
2016-08-05 21:49:45 +02:00
# include "protocol.h"
extern CWallet * pwalletMain ;
// Keep track of the active Masternode
CActiveMasternode activeMasternode ;
2014-12-09 02:17:57 +01:00
2016-08-05 21:49:45 +02:00
// Bootup the Masternode, look for a 1000DASH input and register on the network
void CActiveMasternode : : ManageState ( )
{
2016-09-05 18:09:25 +02:00
std : : string strError ;
2014-12-06 20:41:53 +01:00
2014-12-23 02:23:04 +01:00
if ( ! fMasterNode ) return ;
2014-12-06 20:41:53 +01:00
2016-08-05 21:49:45 +02:00
if ( fDebug ) LogPrintf ( " CActiveMasternode::ManageState -- Begin \n " ) ;
2014-12-09 02:17:57 +01:00
2015-07-14 07:25:07 +02:00
//need correct blocks to send ping
2016-02-02 16:28:56 +01:00
if ( Params ( ) . NetworkIDString ( ) ! = CBaseChainParams : : REGTEST & & ! masternodeSync . IsBlockchainSynced ( ) ) {
2016-08-05 21:49:45 +02:00
nState = ACTIVE_MASTERNODE_SYNC_IN_PROCESS ;
LogPrintf ( " CActiveMasternode::ManageState -- %s \n " , GetStatus ( ) ) ;
2014-12-09 02:17:57 +01:00
return ;
}
2016-08-05 21:49:45 +02:00
if ( nState = = ACTIVE_MASTERNODE_SYNC_IN_PROCESS ) nState = ACTIVE_MASTERNODE_INITIAL ;
2015-07-23 04:19:37 +02:00
2016-08-05 21:49:45 +02:00
if ( nState = = ACTIVE_MASTERNODE_INITIAL ) {
2015-07-14 07:25:07 +02:00
CMasternode * pmn ;
pmn = mnodeman . Find ( pubKeyMasternode ) ;
if ( pmn ! = NULL ) {
pmn - > Check ( ) ;
2016-09-16 00:00:06 +02:00
if ( ( pmn - > IsEnabled ( ) | | pmn - > IsPreEnabled ( ) ) & & pmn - > nProtocolVersion = = PROTOCOL_VERSION )
2016-09-05 18:09:25 +02:00
EnableRemoteMasterNode ( pmn - > vin , pmn - > addr ) ;
2015-07-14 07:25:07 +02:00
}
2014-12-09 02:17:57 +01:00
}
2016-08-05 21:49:45 +02:00
if ( nState ! = ACTIVE_MASTERNODE_STARTED ) {
2015-07-14 07:25:07 +02:00
// Set defaults
2016-08-05 21:49:45 +02:00
nState = ACTIVE_MASTERNODE_NOT_CAPABLE ;
strNotCapableReason = " " ;
2015-07-14 07:25:07 +02:00
2016-08-05 21:49:45 +02:00
if ( pwalletMain - > IsLocked ( ) ) {
strNotCapableReason = " Wallet is locked. " ;
LogPrintf ( " CActiveMasternode::ManageState -- not capable: %s \n " , strNotCapableReason ) ;
2015-08-24 03:14:32 +02:00
return ;
}
2016-08-05 21:49:45 +02:00
if ( pwalletMain - > GetBalance ( ) = = 0 ) {
nState = ACTIVE_MASTERNODE_INITIAL ;
LogPrintf ( " CActiveMasternode::ManageState() -- %s \n " , GetStatus ( ) ) ;
2015-08-24 03:14:32 +02:00
return ;
}
2016-09-28 22:02:54 +02:00
if ( ! GetLocal ( service ) ) {
strNotCapableReason = " Can't detect external address. Please consider using the externalip configuration option if problem persists. " ;
LogPrintf ( " CActiveMasternode::ManageState -- not capable: %s \n " , strNotCapableReason ) ;
return ;
2014-12-09 02:17:57 +01:00
}
2016-02-17 17:00:17 +01:00
int mainnetDefaultPort = Params ( CBaseChainParams : : MAIN ) . GetDefaultPort ( ) ;
2016-02-02 16:28:56 +01:00
if ( Params ( ) . NetworkIDString ( ) = = CBaseChainParams : : MAIN ) {
2016-02-17 17:00:17 +01:00
if ( service . GetPort ( ) ! = mainnetDefaultPort ) {
2016-08-05 21:49:45 +02:00
strNotCapableReason = strprintf ( " Invalid port: %u - only %d is supported on mainnet. " , service . GetPort ( ) , mainnetDefaultPort ) ;
LogPrintf ( " CActiveMasternode::ManageState -- not capable: %s \n " , strNotCapableReason ) ;
2015-02-06 20:41:39 +01:00
return ;
}
2016-02-17 17:00:17 +01:00
} else if ( service . GetPort ( ) = = mainnetDefaultPort ) {
2016-08-05 21:49:45 +02:00
strNotCapableReason = strprintf ( " Invalid port: %u - %d is only supported on mainnet. " , service . GetPort ( ) , mainnetDefaultPort ) ;
LogPrintf ( " CActiveMasternode::ManageState -- not capable: %s \n " , strNotCapableReason ) ;
2015-03-11 20:26:39 +01:00
return ;
2015-02-06 20:41:39 +01:00
}
2016-08-05 21:49:45 +02:00
LogPrintf ( " CActiveMasternode::ManageState -- Checking inbound connection to '%s' \n " , service . ToString ( ) ) ;
2016-03-02 11:53:39 +01:00
2016-08-05 21:49:45 +02:00
if ( ! ConnectNode ( ( CAddress ) service , NULL , true ) ) {
strNotCapableReason = " Could not connect to " + service . ToString ( ) ;
LogPrintf ( " CActiveMasternode::ManageState -- not capable: %s \n " , strNotCapableReason ) ;
2015-03-13 10:28:20 +01:00
return ;
2014-12-09 02:17:57 +01:00
}
// Choose coins to use
2016-08-05 21:49:45 +02:00
CPubKey pubKeyCollateral ;
CKey keyCollateral ;
2014-12-09 02:17:57 +01:00
2016-08-05 21:49:45 +02:00
if ( pwalletMain - > GetMasternodeVinAndKeys ( vin , pubKeyCollateral , keyCollateral ) ) {
2014-12-09 02:17:57 +01:00
2016-08-05 21:49:45 +02:00
int nInputAge = GetInputAge ( vin ) ;
if ( nInputAge < Params ( ) . GetConsensus ( ) . nMasternodeMinimumConfirmations ) {
nState = ACTIVE_MASTERNODE_INPUT_TOO_NEW ;
strNotCapableReason = strprintf ( " %s - %d confirmations " , GetStatus ( ) , nInputAge ) ;
LogPrintf ( " CActiveMasternode::ManageState -- %s \n " , strNotCapableReason ) ;
2014-12-09 02:17:57 +01:00
return ;
}
2015-07-30 15:44:18 +02:00
LOCK ( pwalletMain - > cs_wallet ) ;
2014-12-06 20:41:53 +01:00
pwalletMain - > LockCoin ( vin . prevout ) ;
2014-12-09 02:17:57 +01:00
2016-03-16 16:30:22 +01:00
CMasternodeBroadcast mnb ;
2016-09-05 18:09:25 +02:00
if ( ! CMasternodeBroadcast : : Create ( vin , service , keyCollateral , pubKeyCollateral , keyMasternode , pubKeyMasternode , strError , mnb ) ) {
strNotCapableReason = " Error on CMasternodeBroadcast::Create -- " + strError ;
2016-08-05 21:49:45 +02:00
LogPrintf ( " CActiveMasternode::ManageState -- %s \n " , strNotCapableReason ) ;
2015-07-14 07:25:07 +02:00
return ;
2014-12-09 02:17:57 +01:00
}
2016-05-10 22:45:11 +02:00
//update to masternode list
2016-08-05 21:49:45 +02:00
LogPrintf ( " CActiveMasternode::ManageState -- Update Masternode List \n " ) ;
2016-05-10 22:45:11 +02:00
mnodeman . UpdateMasternodeList ( mnb ) ;
2016-03-16 16:30:22 +01:00
//send to all peers
2016-08-05 21:49:45 +02:00
LogPrintf ( " CActiveMasternode::ManageState -- Relay broadcast, vin=%s \n " , vin . ToString ( ) ) ;
2016-03-16 16:30:22 +01:00
mnb . Relay ( ) ;
2016-08-05 21:49:45 +02:00
LogPrintf ( " CActiveMasternode::ManageState -- Is capable master node! \n " ) ;
nState = ACTIVE_MASTERNODE_STARTED ;
2015-07-14 07:25:07 +02:00
2014-12-09 02:17:57 +01:00
return ;
2014-12-06 20:41:53 +01:00
} else {
2016-08-05 21:49:45 +02:00
strNotCapableReason = " Could not find suitable coins! " ;
LogPrintf ( " CActiveMasternode::ManageState -- %s \n " , strNotCapableReason ) ;
2015-07-14 07:25:07 +02:00
return ;
2014-12-09 02:17:57 +01:00
}
}
2014-12-06 20:41:53 +01:00
//send to all peers
2016-09-05 18:09:25 +02:00
if ( ! SendMasternodePing ( strError ) ) {
LogPrintf ( " CActiveMasternode::ManageState -- Error on SendMasternodePing(): %s \n " , strError ) ;
2015-07-14 07:25:07 +02:00
}
}
2016-08-05 21:49:45 +02:00
std : : string CActiveMasternode : : GetStatus ( )
{
switch ( nState ) {
case ACTIVE_MASTERNODE_INITIAL : return " Node just started, not yet activated " ;
case ACTIVE_MASTERNODE_SYNC_IN_PROCESS : return " Sync in progress. Must wait until sync is complete to start Masternode " ;
case ACTIVE_MASTERNODE_INPUT_TOO_NEW : return strprintf ( " Masternode input must have at least %d confirmations " , Params ( ) . GetConsensus ( ) . nMasternodeMinimumConfirmations ) ;
case ACTIVE_MASTERNODE_NOT_CAPABLE : return " Not capable masternode: " + strNotCapableReason ;
2016-09-26 00:40:55 +02:00
case ACTIVE_MASTERNODE_STARTED : return " Masternode start request sent " ;
2016-08-05 21:49:45 +02:00
default : return " unknown " ;
2014-12-06 20:41:53 +01:00
}
}
2014-12-09 02:17:57 +01:00
2016-09-05 18:09:25 +02:00
bool CActiveMasternode : : SendMasternodePing ( std : : string & strErrorRet )
2016-08-05 21:49:45 +02:00
{
if ( nState ! = ACTIVE_MASTERNODE_STARTED ) {
2016-09-05 18:09:25 +02:00
strErrorRet = " Masternode is not in a running status " ;
2015-03-22 00:58:18 +01:00
return false ;
}
2014-12-09 02:17:57 +01:00
2015-04-17 17:10:38 +02:00
CMasternodePing mnp ( vin ) ;
2016-08-05 21:49:45 +02:00
if ( ! mnp . Sign ( keyMasternode , pubKeyMasternode ) ) {
2016-09-05 18:09:25 +02:00
strErrorRet = " Couldn't sign Masternode Ping " ;
2014-12-09 02:17:57 +01:00
return false ;
}
2015-07-14 07:25:07 +02:00
// Update lastPing for our masternode in Masternode list
2015-02-25 12:54:03 +01:00
CMasternode * pmn = mnodeman . Find ( vin ) ;
2016-08-05 21:49:45 +02:00
if ( pmn ! = NULL ) {
if ( pmn - > IsPingedWithin ( MASTERNODE_MIN_MNP_SECONDS , mnp . sigTime ) ) {
2016-09-05 18:09:25 +02:00
strErrorRet = " Too early to send Masternode Ping " ;
2015-07-14 07:25:07 +02:00
return false ;
}
pmn - > lastPing = mnp ;
2016-08-05 21:49:45 +02:00
mnodeman . mapSeenMasternodePing . insert ( std : : make_pair ( mnp . GetHash ( ) , mnp ) ) ;
2015-08-26 02:18:01 +02:00
//mnodeman.mapSeenMasternodeBroadcast.lastPing is probably outdated, so we'll update it
CMasternodeBroadcast mnb ( * pmn ) ;
uint256 hash = mnb . GetHash ( ) ;
2016-08-05 21:49:45 +02:00
if ( mnodeman . mapSeenMasternodeBroadcast . count ( hash ) )
mnodeman . mapSeenMasternodeBroadcast [ hash ] . lastPing = mnp ;
2015-08-26 02:18:01 +02:00
2016-08-05 21:49:45 +02:00
LogPrintf ( " CActiveMasternode::SendMasternodePing -- Relaying ping, collateral=%s \n " , vin . ToString ( ) ) ;
2015-07-14 07:25:07 +02:00
mnp . Relay ( ) ;
2015-07-19 17:49:46 +02:00
2015-07-14 07:25:07 +02:00
return true ;
2016-08-05 21:49:45 +02:00
} else {
2015-03-22 00:58:18 +01:00
// Seems like we are trying to send a ping while the Masternode is not registered in the network
2016-09-05 18:09:25 +02:00
strErrorRet = " PrivateSend Masternode List doesn't include our Masternode, shutting down Masternode pinging service! " + vin . ToString ( ) ;
2016-08-05 21:49:45 +02:00
nState = ACTIVE_MASTERNODE_NOT_CAPABLE ;
2016-09-05 18:09:25 +02:00
strNotCapableReason = strErrorRet ;
2014-12-09 02:17:57 +01:00
return false ;
}
2014-12-06 20:41:53 +01:00
}
2015-03-05 09:10:15 +01:00
// when starting a Masternode, this can enable to run as a hot wallet with no funds
2016-09-05 18:09:25 +02:00
bool CActiveMasternode : : EnableRemoteMasterNode ( CTxIn & vinNew , CService & serviceNew )
2014-12-09 02:17:57 +01:00
{
if ( ! fMasterNode ) return false ;
2016-08-05 21:49:45 +02:00
nState = ACTIVE_MASTERNODE_STARTED ;
2014-12-09 02:17:57 +01:00
2015-04-17 17:10:38 +02:00
//The values below are needed for signing mnping messages going forward
2016-09-05 18:09:25 +02:00
vin = vinNew ;
service = serviceNew ;
2014-12-09 02:17:57 +01:00
2016-08-05 21:49:45 +02:00
LogPrintf ( " CActiveMasternode::EnableHotColdMasterNode -- Enabled! You may shut down the cold daemon. \n " ) ;
2014-12-09 02:17:57 +01:00
return true ;
}