Implement CActiveDeterministicMasternodeManager

This commit is contained in:
Alexander Block 2018-02-15 14:33:04 +01:00
parent a5e65aa373
commit d90b139967
3 changed files with 189 additions and 1 deletions

View File

@ -9,13 +9,144 @@
#include "netbase.h" #include "netbase.h"
#include "protocol.h" #include "protocol.h"
#include "netbase.h" #include "netbase.h"
#include "warnings.h"
#include "init.h"
#include "evo/deterministicmns.h"
// Keep track of the active Masternode // Keep track of the active Masternode
CActiveMasternodeInfo activeMasternodeInfo; CActiveMasternodeInfo activeMasternodeInfo;
CActiveLegacyMasternodeManager legacyActiveMasternodeManager; CActiveLegacyMasternodeManager legacyActiveMasternodeManager;
CActiveDeterministicMasternodeManager* activeMasternodeManager;
std::string CActiveDeterministicMasternodeManager::GetStateString() const
{
switch (state) {
case MASTERNODE_WAITING_FOR_PROTX: return "WAITING_FOR_PROTX";
case MASTERNODE_POSE_BANNED: return "POSE_BANNED";
case MASTERNODE_REMOVED: return "REMOVED";
case MASTERNODE_READY: return "READY";
case MASTERNODE_ERROR: return "ERROR";
default: return "UNKNOWN";
}
}
std::string CActiveDeterministicMasternodeManager::GetStatus() const
{
switch (state) {
case MASTERNODE_WAITING_FOR_PROTX: return "Waiting for ProTx to appear on-chain";
case MASTERNODE_POSE_BANNED: return "Masternode was PoSe banned";
case MASTERNODE_REMOVED: return "Masternode removed from list";
case MASTERNODE_READY: return "Ready";
case MASTERNODE_ERROR: return "Error. " + strError;
default: return "Unknown";
}
}
void CActiveDeterministicMasternodeManager::Init()
{
LOCK(cs_main);
if (!fMasternodeMode)
return;
if (!deterministicMNManager->IsDeterministicMNsSporkActive())
return;
if (!GetLocalAddress(activeMasternodeInfo.service)) {
state = MASTERNODE_ERROR;
return;
}
CDeterministicMNList mnList = deterministicMNManager->GetListAtChainTip();
CDeterministicMNCPtr dmn = mnList.GetMNByOperatorKey(activeMasternodeInfo.keyIDOperator);
if (!dmn) {
// MN not appeared on the chain yet
return;
}
if (!mnList.IsMNValid(dmn->proTxHash)) {
if (mnList.IsMNPoSeBanned(dmn->proTxHash)) {
state = MASTERNODE_POSE_BANNED;
} else {
state = MASTERNODE_REMOVED;
}
return;
}
mnListEntry = dmn;
LogPrintf("CActiveDeterministicMasternodeManager::Init -- proTxHash=%s, proTx=%s\n", mnListEntry->proTxHash.ToString(), mnListEntry->ToString());
if (activeMasternodeInfo.service != mnListEntry->pdmnState->addr) {
state = MASTERNODE_ERROR;
strError = "Local address does not match the address from ProTx";
LogPrintf("CActiveDeterministicMasternodeManager::Init -- ERROR: %s", strError);
return;
}
if (mnListEntry->pdmnState->nProtocolVersion != PROTOCOL_VERSION) {
state = MASTERNODE_ERROR;
strError = "Local protocol version does not match version from ProTx. You may need to update the ProTx";
LogPrintf("CActiveDeterministicMasternodeManager::Init -- ERROR: %s", strError);
return;
}
activeMasternodeInfo.outpoint = COutPoint(mnListEntry->proTxHash, mnListEntry->nCollateralIndex);
state = MASTERNODE_READY;
}
void CActiveDeterministicMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload)
{
LOCK(cs_main);
if (!fMasternodeMode)
return;
if (!deterministicMNManager->IsDeterministicMNsSporkActive(pindexNew->nHeight)) {
return;
}
if (state == MASTERNODE_WAITING_FOR_PROTX) {
Init();
} else if (state == MASTERNODE_READY) {
if (!deterministicMNManager->HasValidMNAtBlock(pindexNew->GetBlockHash(), mnListEntry->proTxHash)) {
// MN disappeared from MN list
state = MASTERNODE_REMOVED;
activeMasternodeInfo.outpoint.SetNull();
// MN might have reappeared in same block with a new ProTx (with same masternode key)
Init();
}
} else if (state == MASTERNODE_REMOVED || state == MASTERNODE_POSE_BANNED) {
// MN might have reappeared with a new ProTx (with same masternode key)
Init();
}
}
bool CActiveDeterministicMasternodeManager::GetLocalAddress(CService &addrRet)
{
// First try to find whatever local address is specified by externalip option
bool fFoundLocal = GetLocal(addrRet) && CMasternode::IsValidNetAddr(addrRet);
if (!fFoundLocal && Params().NetworkIDString() == CBaseChainParams::REGTEST) {
if (Lookup("127.0.0.1", addrRet, GetListenPort(), false)) {
fFoundLocal = true;
}
}
if(!fFoundLocal) {
strError = "Can't detect valid external address. Please consider using the externalip configuration option if problem persists. Make sure to use IPv4 address only.";
LogPrintf("CActiveDeterministicMasternodeManager::GetLocalAddress -- ERROR: %s\n", strError);
return false;
}
return true;
}
/********* LEGACY *********/
void CActiveLegacyMasternodeManager::ManageState(CConnman& connman) void CActiveLegacyMasternodeManager::ManageState(CConnman& connman)
{ {
if (deterministicMNManager->IsDeterministicMNsSporkActive())
return;
LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageState -- Start\n"); LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageState -- Start\n");
if(!fMasternodeMode) { if(!fMasternodeMode) {
LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageState -- Not a masternode, returning\n"); LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageState -- Not a masternode, returning\n");
@ -84,6 +215,9 @@ std::string CActiveLegacyMasternodeManager::GetTypeString() const
bool CActiveLegacyMasternodeManager::SendMasternodePing(CConnman& connman) bool CActiveLegacyMasternodeManager::SendMasternodePing(CConnman& connman)
{ {
if (deterministicMNManager->IsDeterministicMNsSporkActive())
return false;
if(!fPingerEnabled) { if(!fPingerEnabled) {
LogPrint("masternode", "CActiveLegacyMasternodeManager::SendMasternodePing -- %s: masternode ping service is disabled, skipping...\n", GetStateString()); LogPrint("masternode", "CActiveLegacyMasternodeManager::SendMasternodePing -- %s: masternode ping service is disabled, skipping...\n", GetStateString());
return false; return false;
@ -129,6 +263,9 @@ bool CActiveLegacyMasternodeManager::UpdateSentinelPing(int version)
void CActiveLegacyMasternodeManager::ManageStateInitial(CConnman& connman) void CActiveLegacyMasternodeManager::ManageStateInitial(CConnman& connman)
{ {
if (deterministicMNManager->IsDeterministicMNsSporkActive())
return;
LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageStateInitial -- status = %s, type = %s, pinger enabled = %d\n", GetStatus(), GetTypeString(), fPingerEnabled); LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageStateInitial -- status = %s, type = %s, pinger enabled = %d\n", GetStatus(), GetTypeString(), fPingerEnabled);
// Check that our local network configuration is correct // Check that our local network configuration is correct
@ -210,6 +347,9 @@ void CActiveLegacyMasternodeManager::ManageStateInitial(CConnman& connman)
void CActiveLegacyMasternodeManager::ManageStateRemote() void CActiveLegacyMasternodeManager::ManageStateRemote()
{ {
if (deterministicMNManager->IsDeterministicMNsSporkActive())
return;
LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageStateRemote -- Start status = %s, type = %s, pinger enabled = %d, keyIDOperator = %s\n", LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageStateRemote -- Start status = %s, type = %s, pinger enabled = %d, keyIDOperator = %s\n",
GetStatus(), GetTypeString(), fPingerEnabled, activeMasternodeInfo.keyIDOperator.ToString()); GetStatus(), GetTypeString(), fPingerEnabled, activeMasternodeInfo.keyIDOperator.ToString());

View File

@ -9,9 +9,14 @@
#include "key.h" #include "key.h"
#include "net.h" #include "net.h"
#include "primitives/transaction.h" #include "primitives/transaction.h"
#include "validationinterface.h"
#include "evo/providertx.h"
#include "evo/deterministicmns.h"
struct CActiveMasternodeInfo; struct CActiveMasternodeInfo;
class CActiveLegacyMasternodeManager; class CActiveLegacyMasternodeManager;
class CActiveDeterministicMasternodeManager;
static const int ACTIVE_MASTERNODE_INITIAL = 0; // initial state static const int ACTIVE_MASTERNODE_INITIAL = 0; // initial state
static const int ACTIVE_MASTERNODE_SYNC_IN_PROCESS = 1; static const int ACTIVE_MASTERNODE_SYNC_IN_PROCESS = 1;
@ -21,6 +26,7 @@ static const int ACTIVE_MASTERNODE_STARTED = 4;
extern CActiveMasternodeInfo activeMasternodeInfo; extern CActiveMasternodeInfo activeMasternodeInfo;
extern CActiveLegacyMasternodeManager legacyActiveMasternodeManager; extern CActiveLegacyMasternodeManager legacyActiveMasternodeManager;
extern CActiveDeterministicMasternodeManager* activeMasternodeManager;
struct CActiveMasternodeInfo { struct CActiveMasternodeInfo {
// Keys for the active Masternode // Keys for the active Masternode
@ -32,7 +38,39 @@ struct CActiveMasternodeInfo {
CService service; CService service;
}; };
// Responsible for activating the Masternode and pinging the network
class CActiveDeterministicMasternodeManager : public CValidationInterface
{
public:
enum masternode_state_t {
MASTERNODE_WAITING_FOR_PROTX,
MASTERNODE_POSE_BANNED,
MASTERNODE_REMOVED,
MASTERNODE_READY,
MASTERNODE_ERROR,
};
private:
CDeterministicMNCPtr mnListEntry;
masternode_state_t state{MASTERNODE_WAITING_FOR_PROTX};
std::string strError;
public:
virtual void UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload);
void Init();
CDeterministicMNCPtr GetDMN() const { return mnListEntry; }
masternode_state_t GetState() const { return state; }
std::string GetStateString() const;
std::string GetStatus() const;
private:
bool GetLocalAddress(CService &addrRet);
};
// Responsible for activating the Masternode and pinging the network (legacy MN list)
class CActiveLegacyMasternodeManager class CActiveLegacyMasternodeManager
{ {
public: public:

View File

@ -318,6 +318,9 @@ void PrepareShutdown()
delete pdsNotificationInterface; delete pdsNotificationInterface;
pdsNotificationInterface = NULL; pdsNotificationInterface = NULL;
} }
if (fMasternodeMode) {
UnregisterValidationInterface(activeMasternodeManager);
}
#ifndef WIN32 #ifndef WIN32
try { try {
@ -1880,6 +1883,10 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
} else { } else {
return InitError(_("You must specify a masternodeprivkey in the configuration. Please see documentation for help.")); return InitError(_("You must specify a masternodeprivkey in the configuration. Please see documentation for help."));
} }
// init and register activeMasternodeManager
activeMasternodeManager = new CActiveDeterministicMasternodeManager();
RegisterValidationInterface(activeMasternodeManager);
} }
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
@ -1996,6 +2003,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
// GetMainSignals().UpdatedBlockTip(chainActive.Tip()); // GetMainSignals().UpdatedBlockTip(chainActive.Tip());
pdsNotificationInterface->InitializeCurrentBlockTip(); pdsNotificationInterface->InitializeCurrentBlockTip();
if (activeMasternodeManager && fDIP0003ActiveAtTip)
activeMasternodeManager->Init();
// ********************************************************* Step 11d: schedule Dash-specific tasks // ********************************************************* Step 11d: schedule Dash-specific tasks
if (!fLiteMode) { if (!fLiteMode) {