LCOV - code coverage report
Current view: top level - src - activemasternode.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 203 280 72.5 %
Date: 2025-02-23 09:33:43 Functions: 15 18 83.3 %

          Line data    Source code
       1             : // Copyright (c) 2014-2016 The Dash developers
       2             : // Copyright (c) 2015-2022 The PIVX Core developers
       3             : // Distributed under the MIT/X11 software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #include "activemasternode.h"
       7             : 
       8             : #include "addrman.h"
       9             : #include "bls/key_io.h"
      10             : #include "bls/bls_wrapper.h"
      11             : #include "masternode.h"
      12             : #include "masternodeconfig.h"
      13             : #include "masternodeman.h"
      14             : #include "messagesigner.h"
      15             : #include "netbase.h"
      16             : #include "protocol.h"
      17             : #include "tiertwo/net_masternodes.h"
      18             : #include "tiertwo/tiertwo_sync_state.h"
      19             : #include "validation.h"
      20             : 
      21             : // Keep track of the active Masternode
      22             : CActiveDeterministicMasternodeManager* activeMasternodeManager{nullptr};
      23             : 
      24         261 : static bool GetLocalAddress(CService& addrRet)
      25             : {
      26             :     // First try to find whatever our own local address is known internally.
      27             :     // Addresses could be specified via 'externalip' or 'bind' option, discovered via UPnP
      28             :     // or added by TorController. Use some random dummy IPv4 peer to prefer the one
      29             :     // reachable via IPv4.
      30         261 :     CNetAddr addrDummyPeer;
      31         261 :     bool fFound{false};
      32         261 :     if (LookupHost("8.8.8.8", addrDummyPeer, false)) {
      33         261 :         fFound = GetLocal(addrRet, &addrDummyPeer) && CActiveDeterministicMasternodeManager::IsValidNetAddr(addrRet);
      34             :     }
      35         261 :     if (!fFound && Params().IsRegTestNet()) {
      36         261 :         if (Lookup("127.0.0.1", addrRet, GetListenPort(), false)) {
      37         261 :             fFound = true;
      38             :         }
      39             :     }
      40         261 :     if (!fFound) {
      41             :         // If we have some peers, let's try to find our local address from one of them
      42           0 :         g_connman->ForEachNodeContinueIf([&fFound, &addrRet](CNode* pnode) {
      43           0 :             if (pnode->addr.IsIPv4())
      44           0 :                 fFound = GetLocal(addrRet, &pnode->addr) && CActiveDeterministicMasternodeManager::IsValidNetAddr(addrRet);
      45           0 :             return !fFound;
      46             :         });
      47             :     }
      48         261 :     return fFound;
      49             : }
      50             : 
      51          40 : std::string CActiveDeterministicMasternodeManager::GetStatus() const
      52             : {
      53          40 :     switch (state) {
      54           0 :         case MASTERNODE_WAITING_FOR_PROTX:    return "Waiting for ProTx to appear on-chain";
      55           0 :         case MASTERNODE_POSE_BANNED:          return "Masternode was PoSe banned";
      56           0 :         case MASTERNODE_REMOVED:              return "Masternode removed from list";
      57           0 :         case MASTERNODE_OPERATOR_KEY_CHANGED: return "Operator key changed or revoked";
      58           0 :         case MASTERNODE_PROTX_IP_CHANGED:     return "IP address specified in ProTx changed";
      59          40 :         case MASTERNODE_READY:                return "Ready";
      60           0 :         case MASTERNODE_ERROR:                return "Error. " + strError;
      61           0 :         default:                              return "Unknown";
      62             :     }
      63             : }
      64             : 
      65          41 : OperationResult CActiveDeterministicMasternodeManager::SetOperatorKey(const std::string& strMNOperatorPrivKey)
      66             : {
      67          82 :     LOCK(cs_main); // Lock cs_main so the node doesn't perform any action while we setup the Masternode
      68          41 :     LogPrintf("Initializing deterministic masternode...\n");
      69          41 :     if (strMNOperatorPrivKey.empty()) {
      70           0 :         return errorOut("ERROR: Masternode operator priv key cannot be empty.");
      71             :     }
      72             : 
      73          82 :     auto opSk = bls::DecodeSecret(Params(), strMNOperatorPrivKey);
      74          41 :     if (!opSk) {
      75           0 :         return errorOut(_("Invalid mnoperatorprivatekey. Please see the documentation."));
      76             :     }
      77          41 :     info.keyOperator = *opSk;
      78          41 :     info.pubKeyOperator = info.keyOperator.GetPublicKey();
      79          41 :     return {true};
      80             : }
      81             : 
      82         425 : OperationResult CActiveDeterministicMasternodeManager::GetOperatorKey(CBLSSecretKey& key, CDeterministicMNCPtr& dmn) const
      83             : {
      84         425 :     if (!IsReady()) {
      85         411 :         return errorOut("Active masternode not ready");
      86             :     }
      87         576 :     dmn = deterministicMNManager->GetListAtChainTip().GetValidMN(info.proTxHash);
      88         288 :     if (!dmn) {
      89           2 :         return errorOut(strprintf("Active masternode %s not registered or PoSe banned", info.proTxHash.ToString()));
      90             :     }
      91         287 :     if (info.pubKeyOperator != dmn->pdmnState->pubKeyOperator.Get()) {
      92           0 :         return errorOut("Active masternode operator key changed or revoked");
      93             :     }
      94             :     // return key
      95         287 :     key = info.keyOperator;
      96         425 :     return {true};
      97             : }
      98             : 
      99         261 : void CActiveDeterministicMasternodeManager::Init(const CBlockIndex* pindexTip)
     100             : {
     101             :     // set masternode arg if called from RPC
     102         261 :     if (!fMasterNode) {
     103          82 :         gArgs.ForceSetArg("-masternode", "1");
     104          41 :         fMasterNode = true;
     105             :     }
     106             : 
     107         261 :     if (!deterministicMNManager->IsDIP3Enforced(pindexTip->nHeight)) {
     108           0 :         state = MASTERNODE_ERROR;
     109           0 :         strError = "Evo upgrade is not active yet.";
     110           0 :         LogPrintf("%s -- ERROR: %s\n", __func__, strError);
     111           0 :         return;
     112             :     }
     113             : 
     114         304 :     LOCK(cs_main);
     115             : 
     116             :     // Check that our local network configuration is correct
     117         261 :     if (!fListen) {
     118             :         // listen option is probably overwritten by smth else, no good
     119           0 :         state = MASTERNODE_ERROR;
     120           0 :         strError = "Masternode must accept connections from outside. Make sure listen configuration option is not overwritten by some another parameter.";
     121           0 :         LogPrintf("%s ERROR: %s\n", __func__, strError);
     122         218 :         return;
     123             :     }
     124             : 
     125         261 :     if (!GetLocalAddress(info.service)) {
     126           0 :         state = MASTERNODE_ERROR;
     127           0 :         strError = "Can't detect valid external address. Please consider using the externalip configuration option if problem persists. Make sure to use IPv4 address only.";
     128           0 :         LogPrintf("%s ERROR: %s\n", __func__, strError);
     129             :         return;
     130             :     }
     131             : 
     132         304 :     CDeterministicMNList mnList = deterministicMNManager->GetListForBlock(pindexTip);
     133             : 
     134         304 :     CDeterministicMNCPtr dmn = mnList.GetMNByOperatorKey(info.pubKeyOperator);
     135         261 :     if (!dmn) {
     136             :         // MN not appeared on the chain yet
     137         218 :         return;
     138             :     }
     139             : 
     140          51 :     if (dmn->IsPoSeBanned()) {
     141           0 :         state = MASTERNODE_POSE_BANNED;
     142           0 :         return;
     143             :     }
     144             : 
     145         102 :     LogPrintf("%s: proTxHash=%s, proTx=%s\n", __func__, dmn->proTxHash.ToString(), dmn->ToString());
     146             : 
     147          51 :     if (info.service != dmn->pdmnState->addr) {
     148           8 :         state = MASTERNODE_ERROR;
     149          24 :         strError = strprintf("Local address %s does not match the address from ProTx (%s)",
     150          24 :                              info.service.ToStringIPPort(), dmn->pdmnState->addr.ToStringIPPort());
     151           8 :         LogPrintf("%s ERROR: %s\n", __func__, strError);
     152             :         return;
     153             :     }
     154             : 
     155             :     // Check socket connectivity
     156          86 :     const std::string& strService = info.service.ToString();
     157          43 :     LogPrintf("%s: Checking inbound connection to '%s'\n", __func__, strService);
     158          43 :     SOCKET hSocket = CreateSocket(info.service);
     159          43 :     if (hSocket == INVALID_SOCKET) {
     160           0 :         state = MASTERNODE_ERROR;
     161           0 :         strError = "DMN connectivity check failed, could not create socket to DMN running at " + strService;
     162           0 :         LogPrintf("%s -- ERROR: %s\n", __func__, strError);
     163         218 :         return;
     164             :     }
     165          43 :     bool fConnected = ConnectSocketDirectly(info.service, hSocket, nConnectTimeout, true) && IsSelectableSocket(hSocket);
     166          43 :     CloseSocket(hSocket);
     167             : 
     168          43 :     if (!fConnected) {
     169           0 :         state = MASTERNODE_ERROR;
     170           0 :         strError = "DMN connectivity check failed, could not connect to DMN running at " + strService;
     171           0 :         LogPrintf("%s ERROR: %s\n", __func__, strError);
     172             :         return;
     173             :     }
     174             : 
     175          43 :     info.proTxHash = dmn->proTxHash;
     176          43 :     g_connman->GetTierTwoConnMan()->setLocalDMN(info.proTxHash);
     177          43 :     state = MASTERNODE_READY;
     178          43 :     LogPrintf("Deterministic Masternode initialized\n");
     179             : }
     180             : 
     181           6 : void CActiveDeterministicMasternodeManager::Reset(masternode_state_t _state, const CBlockIndex* pindexTip)
     182             : {
     183           6 :     state = _state;
     184           6 :     SetNullProTx();
     185             :     // MN might have reappeared in same block with a new ProTx
     186           6 :     Init(pindexTip);
     187           6 : }
     188             : 
     189        4496 : void CActiveDeterministicMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload)
     190             : {
     191        4496 :     if (fInitialDownload)
     192             :         return;
     193             : 
     194        4496 :     if (!fMasterNode || !deterministicMNManager->IsDIP3Enforced(pindexNew->nHeight))
     195           0 :         return;
     196             : 
     197        4496 :     if (state == MASTERNODE_READY) {
     198        8558 :         auto newDmn = deterministicMNManager->GetListForBlock(pindexNew).GetValidMN(info.proTxHash);
     199        4282 :         if (newDmn == nullptr) {
     200             :             // MN disappeared from MN list
     201           5 :             Reset(MASTERNODE_REMOVED, pindexNew);
     202           6 :             return;
     203             :         }
     204             : 
     205        8553 :         auto oldDmn = deterministicMNManager->GetListForBlock(pindexNew->pprev).GetMN(info.proTxHash);
     206        4277 :         if (oldDmn == nullptr) {
     207             :             // should never happen if state is MASTERNODE_READY
     208           0 :             LogPrintf("%s: WARNING: unable to find active mn %s in prev block list %s\n",
     209           0 :                       __func__, info.proTxHash.ToString(), pindexNew->pprev->GetBlockHash().ToString());
     210           6 :             return;
     211             :         }
     212             : 
     213        4277 :         if (newDmn->pdmnState->pubKeyOperator != oldDmn->pdmnState->pubKeyOperator) {
     214             :             // MN operator key changed or revoked
     215           0 :             Reset(MASTERNODE_OPERATOR_KEY_CHANGED, pindexNew);
     216             :             return;
     217             :         }
     218             : 
     219        4277 :         if (newDmn->pdmnState->addr != oldDmn->pdmnState->addr) {
     220             :             // MN IP changed
     221           1 :             Reset(MASTERNODE_PROTX_IP_CHANGED, pindexNew);
     222             :             return;
     223             :         }
     224             :     } else {
     225             :         // MN might have (re)appeared with a new ProTx or we've found some peers
     226             :         // and figured out our local address
     227         214 :         Init(pindexNew);
     228             :     }
     229             : }
     230             : 
     231           0 : bool CActiveDeterministicMasternodeManager::IsValidNetAddr(const CService& addrIn)
     232             : {
     233             :     // TODO: check IPv6 and TOR addresses
     234           0 :     return Params().IsRegTestNet() || (addrIn.IsIPv4() && IsReachable(addrIn) && addrIn.IsRoutable());
     235             : }
     236             : 
     237             : 
     238             : /********* LEGACY *********/
     239             : 
     240          11 : OperationResult initMasternode(const std::string& _strMasterNodePrivKey, const std::string& _strMasterNodeAddr, bool isFromInit)
     241             : {
     242          11 :     if (!isFromInit && fMasterNode) {
     243           0 :         return errorOut( "ERROR: Masternode already initialized.");
     244             :     }
     245             : 
     246          22 :     LOCK(cs_main); // Lock cs_main so the node doesn't perform any action while we setup the Masternode
     247          11 :     LogPrintf("Initializing masternode, addr %s..\n", _strMasterNodeAddr.c_str());
     248             : 
     249          11 :     if (_strMasterNodePrivKey.empty()) {
     250           0 :         return errorOut("ERROR: Masternode priv key cannot be empty.");
     251             :     }
     252             : 
     253          11 :     if (_strMasterNodeAddr.empty()) {
     254           0 :         return errorOut("ERROR: Empty masternodeaddr");
     255             :     }
     256             : 
     257             :     // Address parsing.
     258          11 :     const CChainParams& params = Params();
     259          11 :     int nPort = 0;
     260          11 :     int nDefaultPort = params.GetDefaultPort();
     261          22 :     std::string strHost;
     262          22 :     SplitHostPort(_strMasterNodeAddr, nPort, strHost);
     263             : 
     264             :     // Allow for the port number to be omitted here and just double check
     265             :     // that if a port is supplied, it matches the required default port.
     266          11 :     if (nPort == 0) nPort = nDefaultPort;
     267          11 :     if (nPort != nDefaultPort && !params.IsRegTestNet()) {
     268           0 :         return errorOut(strprintf(_("Invalid -masternodeaddr port %d, only %d is supported on %s-net."),
     269           0 :                                            nPort, nDefaultPort, Params().NetworkIDString()));
     270             :     }
     271          22 :     CService addrTest(LookupNumeric(strHost, nPort));
     272          11 :     if (!addrTest.IsValid()) {
     273           0 :         return errorOut(strprintf(_("Invalid -masternodeaddr address: %s"), _strMasterNodeAddr));
     274             :     }
     275             : 
     276             :     // Peer port needs to match the masternode public one for IPv4 and IPv6.
     277             :     // Onion can run in other ports because those are behind a hidden service which has the public port fixed to the default port.
     278          11 :     if (nPort != GetListenPort() && !addrTest.IsTor()) {
     279           0 :         return errorOut(strprintf(_("Invalid -masternodeaddr port %d, isn't the same as the peer port %d"),
     280           0 :                                   nPort, GetListenPort()));
     281             :     }
     282             : 
     283          22 :     CKey key;
     284          11 :     CPubKey pubkey;
     285          11 :     if (!CMessageSigner::GetKeysFromSecret(_strMasterNodePrivKey, key, pubkey)) {
     286           0 :         return errorOut(_("Invalid masternodeprivkey. Please see the documentation."));
     287             :     }
     288             : 
     289          11 :     activeMasternode.pubKeyMasternode = pubkey;
     290          11 :     activeMasternode.privKeyMasternode = key;
     291          11 :     activeMasternode.service = addrTest;
     292          11 :     fMasterNode = true;
     293             : 
     294          11 :     if (g_tiertwo_sync_state.IsBlockchainSynced()) {
     295             :         // Check if the masternode already exists in the list
     296          11 :         CMasternode* pmn = mnodeman.Find(pubkey);
     297          11 :         if (pmn) activeMasternode.EnableHotColdMasterNode(pmn->vin, pmn->addr);
     298             :     }
     299             : 
     300          11 :     return {true};
     301             : }
     302             : 
     303             : //
     304             : // Bootup the Masternode, look for a 10000 PIVX input and register on the network
     305             : //
     306        1287 : void CActiveMasternode::ManageStatus()
     307             : {
     308        1578 :     if (!fMasterNode) return;
     309         380 :     if (activeMasternodeManager != nullptr) {
     310             :         // Deterministic masternode
     311             :         return;
     312             :     }
     313             : 
     314             :     // !TODO: Legacy masternodes - remove after enforcement
     315         109 :     LogPrint(BCLog::MASTERNODE, "CActiveMasternode::ManageStatus() - Begin\n");
     316             : 
     317             :     // If a DMN has been registered with same collateral, disable me.
     318         109 :     CMasternode* pmn = mnodeman.Find(pubKeyMasternode);
     319         109 :     if (pmn && deterministicMNManager->GetListAtChainTip().HasMNByCollateral(pmn->vin.prevout)) {
     320           0 :         LogPrintf("%s: Disabling active legacy Masternode %s as the collateral is now registered with a DMN\n",
     321           0 :                          __func__, pmn->vin.prevout.ToString());
     322           0 :         status = ACTIVE_MASTERNODE_NOT_CAPABLE;
     323           0 :         notCapableReason = "Collateral registered with DMN";
     324           0 :         return;
     325             :     }
     326             : 
     327             :     //need correct blocks to send ping
     328         109 :     if (!Params().IsRegTestNet() && !g_tiertwo_sync_state.IsBlockchainSynced()) {
     329           0 :         status = ACTIVE_MASTERNODE_SYNC_IN_PROCESS;
     330           0 :         LogPrintf("CActiveMasternode::ManageStatus() - %s\n", GetStatusMessage());
     331           0 :         return;
     332             :     }
     333             : 
     334         109 :     if (status == ACTIVE_MASTERNODE_SYNC_IN_PROCESS) status = ACTIVE_MASTERNODE_INITIAL;
     335             : 
     336         109 :     if (status == ACTIVE_MASTERNODE_INITIAL || (pmn && status == ACTIVE_MASTERNODE_NOT_CAPABLE)) {
     337           4 :         if (pmn) {
     338           0 :             if (pmn->protocolVersion != PROTOCOL_VERSION) {
     339           0 :                 LogPrintf("%s: ERROR Trying to start a masternode running an old protocol version, " /* Continued */
     340             :                           "the controller and masternode wallets need to be running the latest release version.\n", __func__);
     341           0 :                 return;
     342             :             }
     343             :             // Update vin and service
     344           0 :             EnableHotColdMasterNode(pmn->vin, pmn->addr);
     345             :         }
     346             :     }
     347             : 
     348         109 :     if (status != ACTIVE_MASTERNODE_STARTED) {
     349             :         // Set defaults
     350          20 :         status = ACTIVE_MASTERNODE_NOT_CAPABLE;
     351          20 :         notCapableReason = "";
     352             : 
     353          20 :         LogPrintf("%s - Checking inbound connection for masternode to '%s'\n", __func__ , service.ToString());
     354             : 
     355          40 :         CAddress addr(service, NODE_NETWORK);
     356          20 :         if (!g_connman->IsNodeConnected(addr)) {
     357          20 :             CNode* node = g_connman->ConnectNode(addr);
     358          20 :             if (!node) {
     359          20 :                 notCapableReason =
     360          40 :                         "Masternode address:port connection availability test failed, could not open a connection to the public masternode address (" +
     361          56 :                         service.ToString() + ")";
     362          20 :                 LogPrintf("%s - not capable: %s\n", __func__, notCapableReason);
     363             :             } else {
     364             :                 // don't leak allocated object in memory
     365           0 :                 delete node;
     366             :             }
     367          20 :             return;
     368             :         }
     369             : 
     370          20 :         notCapableReason = "Waiting for start message from controller.";
     371             :         return;
     372             :     }
     373             : 
     374             :     //send to all peers
     375         178 :     std::string errorMessage;
     376          89 :     if (!SendMasternodePing(errorMessage)) {
     377          34 :         LogPrintf("CActiveMasternode::ManageStatus() - Error on Ping: %s\n", errorMessage);
     378             :     }
     379             : }
     380             : 
     381           0 : void CActiveMasternode::ResetStatus()
     382             : {
     383           0 :     status = ACTIVE_MASTERNODE_INITIAL;
     384           0 :     ManageStatus();
     385           0 : }
     386             : 
     387         185 : std::string CActiveMasternode::GetStatusMessage() const
     388             : {
     389         185 :     switch (status) {
     390           0 :     case ACTIVE_MASTERNODE_INITIAL:
     391           0 :         return "Node just started, not yet activated";
     392           0 :     case ACTIVE_MASTERNODE_SYNC_IN_PROCESS:
     393           0 :         return "Sync in progress. Must wait until sync is complete to start Masternode";
     394         181 :     case ACTIVE_MASTERNODE_NOT_CAPABLE:
     395         181 :         return "Not capable masternode: " + notCapableReason;
     396           4 :     case ACTIVE_MASTERNODE_STARTED:
     397           4 :         return "Masternode successfully started";
     398           0 :     default:
     399           0 :         return "unknown";
     400             :     }
     401             : }
     402             : 
     403         577 : bool CActiveMasternode::SendMasternodePing(std::string& errorMessage)
     404             : {
     405         577 :     if (vin == nullopt) {
     406           0 :         errorMessage = "Active Masternode not initialized";
     407           0 :         return false;
     408             :     }
     409             : 
     410         577 :     if (status != ACTIVE_MASTERNODE_STARTED) {
     411           6 :         errorMessage = "Masternode is not in a running status";
     412           6 :         return false;
     413             :     }
     414             : 
     415         571 :     if (!privKeyMasternode.IsValid() || !pubKeyMasternode.IsValid()) {
     416           0 :         errorMessage = "Error upon masternode key.\n";
     417           0 :         return false;
     418             :     }
     419             : 
     420         571 :     LogPrintf("CActiveMasternode::SendMasternodePing() - Relay Masternode Ping vin = %s\n", vin->ToString());
     421             : 
     422         571 :     const uint256& nBlockHash = mnodeman.GetBlockHashToPing();
     423         571 :     CMasternodePing mnp(*vin, nBlockHash, GetAdjustedTime());
     424         571 :     if (!mnp.Sign(privKeyMasternode, pubKeyMasternode.GetID())) {
     425           0 :         errorMessage = "Couldn't sign Masternode Ping";
     426             :         return false;
     427             :     }
     428             : 
     429             :     // Update lastPing for our masternode in Masternode list
     430         571 :     CMasternode* pmn = mnodeman.Find(vin->prevout);
     431         571 :     if (pmn != nullptr) {
     432         569 :         if (pmn->IsPingedWithin(MasternodePingSeconds(), mnp.sigTime)) {
     433          87 :             errorMessage = "Too early to send Masternode Ping";
     434             :             return false;
     435             :         }
     436             : 
     437             :         // SetLastPing locks the masternode cs, be careful with the lock order.
     438         482 :         pmn->SetLastPing(mnp);
     439         482 :         mnodeman.mapSeenMasternodePing.emplace(mnp.GetHash(), mnp);
     440             : 
     441             :         //mnodeman.mapSeenMasternodeBroadcast.lastPing is probably outdated, so we'll update it
     442        1051 :         CMasternodeBroadcast mnb(*pmn);
     443         482 :         uint256 hash = mnb.GetHash();
     444         482 :         if (mnodeman.mapSeenMasternodeBroadcast.count(hash)) {
     445             :             // SetLastPing locks the masternode cs, be careful with the lock order.
     446             :             // TODO: check why are we double setting the last ping here..
     447         482 :             mnodeman.mapSeenMasternodeBroadcast[hash].SetLastPing(mnp);
     448             :         }
     449             : 
     450         482 :         mnp.Relay();
     451         482 :         return true;
     452             : 
     453             :     } else {
     454             :         // Seems like we are trying to send a ping while the Masternode is not registered in the network
     455           2 :         errorMessage = "Masternode List doesn't include our Masternode, shutting down Masternode pinging service! " + vin->ToString();
     456           2 :         status = ACTIVE_MASTERNODE_NOT_CAPABLE;
     457         571 :         notCapableReason = errorMessage;
     458             :         return false;
     459             :     }
     460             : }
     461             : 
     462             : // when starting a Masternode, this can enable to run as a hot wallet with no funds
     463          13 : bool CActiveMasternode::EnableHotColdMasterNode(CTxIn& newVin, CService& newService)
     464             : {
     465          13 :     if (!fMasterNode) return false;
     466             : 
     467          13 :     status = ACTIVE_MASTERNODE_STARTED;
     468             : 
     469             :     //The values below are needed for signing mnping messages going forward
     470          13 :     vin = newVin;
     471          13 :     service = newService;
     472             : 
     473          13 :     LogPrintf("CActiveMasternode::EnableHotColdMasterNode() - Enabled! You may shut down the cold daemon.\n");
     474             : 
     475          13 :     return true;
     476             : }
     477             : 
     478         477 : void CActiveMasternode::GetKeys(CKey& _privKeyMasternode, CPubKey& _pubKeyMasternode) const
     479             : {
     480         477 :     if (!privKeyMasternode.IsValid() || !pubKeyMasternode.IsValid()) {
     481           0 :         throw std::runtime_error("Error trying to get masternode keys");
     482             :     }
     483         477 :     _privKeyMasternode = privKeyMasternode;
     484         477 :     _pubKeyMasternode = pubKeyMasternode;
     485         477 : }
     486             : 
     487         424 : bool GetActiveDMNKeys(CBLSSecretKey& key, CTxIn& vin)
     488             : {
     489         424 :     if (activeMasternodeManager == nullptr) {
     490           0 :         return error("%s: Active Masternode not initialized", __func__);
     491             :     }
     492         424 :     CDeterministicMNCPtr dmn;
     493         848 :     auto res = activeMasternodeManager->GetOperatorKey(key, dmn);
     494         424 :     if (!res) {
     495         276 :         return error("%s: %s", __func__, res.getError());
     496             :     }
     497         286 :     vin = CTxIn(dmn->collateralOutpoint);
     498         286 :     return true;
     499             : }
     500             : 
     501        1091 : bool GetActiveMasternodeKeys(CTxIn& vin, Optional<CKey>& key, CBLSSecretKey& blsKey)
     502             : {
     503        1091 :     if (activeMasternodeManager != nullptr) {
     504             :         // deterministic mn
     505         422 :         key = nullopt;
     506         422 :         return GetActiveDMNKeys(blsKey, vin);
     507             :     }
     508             :     // legacy mn
     509         669 :     if (activeMasternode.vin == nullopt) {
     510          11 :         return error("%s: Active Masternode not initialized", __func__);
     511             :     }
     512         658 :     if (activeMasternode.GetStatus() != ACTIVE_MASTERNODE_STARTED) {
     513         362 :         return error("%s: MN not started (%s)", __func__, activeMasternode.GetStatusMessage());
     514             :     }
     515         477 :     vin = *activeMasternode.vin;
     516        1568 :     CKey sk;
     517         477 :     CPubKey pk;
     518         477 :     activeMasternode.GetKeys(sk, pk);
     519         477 :     key = Optional<CKey>(sk);
     520         477 :     blsKey.Reset();
     521         477 :     return true;
     522             : }

Generated by: LCOV version 1.14