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
2015-08-12 14:27:58 +02:00
# include "addrman.h"
2014-12-09 02:17:57 +01:00
# include "protocol.h"
# 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"
2015-08-09 15:06:54 +02:00
# include "spork.h"
2014-12-09 02:17:57 +01:00
//
2015-03-05 09:10:15 +01:00
// Bootup the Masternode, look for a 1000DRK input and register on the network
2014-12-09 02:17:57 +01:00
//
2014-12-06 20:41:53 +01:00
void CActiveMasternode : : ManageStatus ( )
2015-07-26 04:27:40 +02:00
{
2014-12-06 20:41:53 +01:00
std : : string errorMessage ;
2014-12-23 02:23:04 +01:00
if ( ! fMasterNode ) return ;
2014-12-06 20:41:53 +01:00
2014-12-23 02:23:04 +01:00
if ( fDebug ) LogPrintf ( " CActiveMasternode::ManageStatus() - 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 ( ) ) {
2015-07-17 12:26:24 +02:00
status = ACTIVE_MASTERNODE_SYNC_IN_PROCESS ;
2015-07-23 04:19:37 +02:00
LogPrintf ( " CActiveMasternode::ManageStatus() - %s \n " , GetStatus ( ) ) ;
2014-12-09 02:17:57 +01:00
return ;
}
2015-07-23 04:19:37 +02:00
if ( status = = ACTIVE_MASTERNODE_SYNC_IN_PROCESS ) status = ACTIVE_MASTERNODE_INITIAL ;
if ( status = = ACTIVE_MASTERNODE_INITIAL ) {
2015-07-14 07:25:07 +02:00
CMasternode * pmn ;
pmn = mnodeman . Find ( pubKeyMasternode ) ;
if ( pmn ! = NULL ) {
pmn - > Check ( ) ;
2015-08-05 05:16:29 +02:00
if ( ( pmn - > IsEnabled ( ) | | pmn - > IsPreEnabled ( ) ) & & pmn - > protocolVersion = = PROTOCOL_VERSION )
EnableHotColdMasterNode ( pmn - > vin , pmn - > addr ) ;
2015-07-14 07:25:07 +02:00
}
2014-12-09 02:17:57 +01:00
}
2015-07-17 12:26:24 +02:00
if ( status ! = ACTIVE_MASTERNODE_STARTED ) {
2015-07-14 07:25:07 +02:00
// Set defaults
2015-07-17 12:26:24 +02:00
status = ACTIVE_MASTERNODE_NOT_CAPABLE ;
2015-07-14 07:25:07 +02:00
notCapableReason = " " ;
2015-08-24 03:14:32 +02:00
if ( pwalletMain - > IsLocked ( ) ) {
notCapableReason = " Wallet is locked. " ;
LogPrintf ( " CActiveMasternode::ManageStatus() - not capable: %s \n " , notCapableReason ) ;
return ;
}
if ( pwalletMain - > GetBalance ( ) = = 0 ) {
notCapableReason = " Hot node, waiting for remote activation. " ;
LogPrintf ( " CActiveMasternode::ManageStatus() - not capable: %s \n " , notCapableReason ) ;
return ;
}
2014-12-09 02:17:57 +01:00
if ( strMasterNodeAddr . empty ( ) ) {
2014-12-06 20:41:53 +01:00
if ( ! GetLocal ( service ) ) {
2015-08-05 05:02:54 +02:00
notCapableReason = " Can't detect external address. Please use the masternodeaddr configuration option. " ;
2015-07-14 07:25:07 +02:00
LogPrintf ( " CActiveMasternode::ManageStatus() - not capable: %s \n " , notCapableReason ) ;
2014-12-09 02:17:57 +01:00
return ;
}
} else {
2015-03-22 00:58:18 +01:00
service = CService ( strMasterNodeAddr ) ;
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 ) {
notCapableReason = strprintf ( " Invalid port: %u - only %d is supported on mainnet. " , service . GetPort ( ) , mainnetDefaultPort ) ;
2015-07-14 07:25:07 +02:00
LogPrintf ( " CActiveMasternode::ManageStatus() - not capable: %s \n " , notCapableReason ) ;
2015-02-06 20:41:39 +01:00
return ;
}
2016-02-17 17:00:17 +01:00
} else if ( service . GetPort ( ) = = mainnetDefaultPort ) {
notCapableReason = strprintf ( " Invalid port: %u - %d is only supported on mainnet. " , service . GetPort ( ) , mainnetDefaultPort ) ;
2015-07-14 07:25:07 +02:00
LogPrintf ( " CActiveMasternode::ManageStatus() - not capable: %s \n " , notCapableReason ) ;
2015-03-11 20:26:39 +01:00
return ;
2015-02-06 20:41:39 +01:00
}
2016-03-02 11:53:39 +01:00
LogPrintf ( " CActiveMasternode::ManageStatus() - Checking inbound connection to '%s' \n " , service . ToString ( ) ) ;
2016-05-10 16:07:25 +02:00
if ( ! ConnectNode ( ( CAddress ) service , NULL , true ) ) {
2015-03-13 10:28:20 +01:00
notCapableReason = " Could not connect to " + service . ToString ( ) ;
2015-07-14 07:25:07 +02:00
LogPrintf ( " CActiveMasternode::ManageStatus() - not capable: %s \n " , notCapableReason ) ;
2015-03-13 10:28:20 +01:00
return ;
2014-12-09 02:17:57 +01:00
}
// Choose coins to use
2014-12-06 20:41:53 +01:00
CPubKey pubKeyCollateralAddress ;
CKey keyCollateralAddress ;
2014-12-09 02:17:57 +01:00
2016-07-15 08:33:16 +02:00
if ( pwalletMain - > GetMasternodeVinAndKeys ( vin , pubKeyCollateralAddress , keyCollateralAddress ) ) {
2014-12-09 02:17:57 +01:00
2016-05-19 21:03:17 +02:00
if ( GetInputAge ( vin ) < Params ( ) . GetConsensus ( ) . nMasternodeMinimumConfirmations ) {
2015-07-17 12:26:24 +02:00
status = ACTIVE_MASTERNODE_INPUT_TOO_NEW ;
2015-07-23 04:19:37 +02:00
notCapableReason = strprintf ( " %s - %d confirmations " , GetStatus ( ) , GetInputAge ( vin ) ) ;
LogPrintf ( " CActiveMasternode::ManageStatus() - %s \n " , notCapableReason ) ;
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
2014-12-06 20:41:53 +01:00
// send to all nodes
2016-03-16 16:30:22 +01:00
CMasternodeBroadcast mnb ;
2016-07-29 07:32:08 +02:00
if ( ! CMasternodeBroadcast : : Create ( vin , service , keyCollateralAddress , pubKeyCollateralAddress , keyMasternode , pubKeyMasternode , errorMessage , mnb ) ) {
2016-03-16 16:30:22 +01:00
notCapableReason = " Error on CreateBroadcast: " + errorMessage ;
2016-03-15 00:16:29 +01:00
LogPrintf ( " CActiveMasternode::ManageStatus() - %s \n " , notCapableReason ) ;
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
LogPrintf ( " CActiveMasternode::ManageStatus() - Update Masternode List \n " ) ;
mnodeman . UpdateMasternodeList ( mnb ) ;
2016-03-16 16:30:22 +01:00
//send to all peers
LogPrintf ( " CActiveMasternode::ManageStatus() - Relay broadcast vin = %s \n " , vin . ToString ( ) ) ;
mnb . Relay ( ) ;
2015-07-14 07:25:07 +02:00
LogPrintf ( " CActiveMasternode::ManageStatus() - Is capable master node! \n " ) ;
2015-07-17 12:26:24 +02:00
status = 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 {
2015-02-16 00:01:06 +01:00
notCapableReason = " Could not find suitable coins! " ;
2015-07-14 07:25:07 +02:00
LogPrintf ( " CActiveMasternode::ManageStatus() - %s \n " , notCapableReason ) ;
return ;
2014-12-09 02:17:57 +01:00
}
}
2014-12-06 20:41:53 +01:00
//send to all peers
2015-07-14 07:25:07 +02:00
if ( ! SendMasternodePing ( errorMessage ) ) {
LogPrintf ( " CActiveMasternode::ManageStatus() - Error on Ping: %s \n " , errorMessage ) ;
}
}
std : : string CActiveMasternode : : GetStatus ( ) {
switch ( status ) {
2015-07-23 04:19:37 +02:00
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 " ;
2016-05-19 21:03:17 +02:00
case ACTIVE_MASTERNODE_INPUT_TOO_NEW : return strprintf ( " Masternode input must have at least %d confirmations " , Params ( ) . GetConsensus ( ) . nMasternodeMinimumConfirmations ) ;
2015-07-23 04:19:37 +02:00
case ACTIVE_MASTERNODE_NOT_CAPABLE : return " Not capable masternode: " + notCapableReason ;
case ACTIVE_MASTERNODE_STARTED : return " Masternode successfully started " ;
2015-07-14 07:25:07 +02:00
default : return " unknown " ;
2014-12-06 20:41:53 +01:00
}
}
2014-12-09 02:17:57 +01:00
2015-07-14 07:25:07 +02:00
bool CActiveMasternode : : SendMasternodePing ( std : : string & errorMessage ) {
2015-07-17 12:26:24 +02:00
if ( status ! = ACTIVE_MASTERNODE_STARTED ) {
2015-03-22 00:58:18 +01:00
errorMessage = " Masternode is not in a running status " ;
return false ;
}
2014-12-09 02:17:57 +01:00
2015-07-14 07:25:07 +02:00
LogPrintf ( " CActiveMasternode::SendMasternodePing() - Relay Masternode Ping vin = %s \n " , vin . ToString ( ) ) ;
2015-04-17 17:10:38 +02:00
CMasternodePing mnp ( vin ) ;
if ( ! mnp . Sign ( keyMasternode , pubKeyMasternode ) )
2014-12-09 02:17:57 +01:00
{
2015-07-14 07:25:07 +02:00
errorMessage = " 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 ) ;
if ( pmn ! = NULL )
2015-02-23 21:01:21 +01:00
{
2015-07-14 07:25:07 +02:00
if ( pmn - > IsPingedWithin ( MASTERNODE_PING_SECONDS , mnp . sigTime ) ) {
errorMessage = " Too early to send Masternode Ping " ;
return false ;
}
pmn - > lastPing = mnp ;
2015-07-30 18:00:28 +02:00
mnodeman . mapSeenMasternodePing . insert ( 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 ( ) ;
if ( mnodeman . mapSeenMasternodeBroadcast . count ( hash ) ) mnodeman . mapSeenMasternodeBroadcast [ hash ] . lastPing = mnp ;
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 ;
2014-12-09 02:17:57 +01:00
}
2015-02-23 21:01:21 +01: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-05-09 21:08:13 +02:00
errorMessage = " PrivateSend Masternode List doesn't include our Masternode, shutting down Masternode pinging service! " + vin . ToString ( ) ;
2015-07-17 12:26:24 +02:00
status = ACTIVE_MASTERNODE_NOT_CAPABLE ;
2015-07-14 07:25:07 +02:00
notCapableReason = errorMessage ;
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
2014-12-06 20:41:53 +01:00
bool CActiveMasternode : : EnableHotColdMasterNode ( CTxIn & newVin , CService & newService )
2014-12-09 02:17:57 +01:00
{
if ( ! fMasterNode ) return false ;
2015-07-17 12:26:24 +02:00
status = 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
2015-07-30 18:00:28 +02:00
vin = newVin ;
service = newService ;
2014-12-09 02:17:57 +01:00
LogPrintf ( " CActiveMasternode::EnableHotColdMasterNode() - Enabled! You may shut down the cold daemon. \n " ) ;
return true ;
}