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 7 : 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 7 : CNetAddr addrDummyPeer;
31 7 : bool fFound{false};
32 7 : if (LookupHost("8.8.8.8", addrDummyPeer, false)) {
33 7 : fFound = GetLocal(addrRet, &addrDummyPeer) && CActiveDeterministicMasternodeManager::IsValidNetAddr(addrRet);
34 : }
35 7 : if (!fFound && Params().IsRegTestNet()) {
36 7 : if (Lookup("127.0.0.1", addrRet, GetListenPort(), false)) {
37 7 : fFound = true;
38 : }
39 : }
40 7 : 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 7 : return fFound;
49 : }
50 :
51 6 : std::string CActiveDeterministicMasternodeManager::GetStatus() const
52 : {
53 6 : 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 6 : case MASTERNODE_READY: return "Ready";
60 0 : case MASTERNODE_ERROR: return "Error. " + strError;
61 0 : default: return "Unknown";
62 : }
63 : }
64 :
65 7 : OperationResult CActiveDeterministicMasternodeManager::SetOperatorKey(const std::string& strMNOperatorPrivKey)
66 : {
67 14 : LOCK(cs_main); // Lock cs_main so the node doesn't perform any action while we setup the Masternode
68 7 : LogPrintf("Initializing deterministic masternode...\n");
69 7 : if (strMNOperatorPrivKey.empty()) {
70 0 : return errorOut("ERROR: Masternode operator priv key cannot be empty.");
71 : }
72 :
73 14 : auto opSk = bls::DecodeSecret(Params(), strMNOperatorPrivKey);
74 7 : if (!opSk) {
75 0 : return errorOut(_("Invalid mnoperatorprivatekey. Please see the documentation."));
76 : }
77 7 : info.keyOperator = *opSk;
78 7 : info.pubKeyOperator = info.keyOperator.GetPublicKey();
79 7 : return {true};
80 : }
81 :
82 6 : OperationResult CActiveDeterministicMasternodeManager::GetOperatorKey(CBLSSecretKey& key, CDeterministicMNCPtr& dmn) const
83 : {
84 6 : if (!IsReady()) {
85 0 : return errorOut("Active masternode not ready");
86 : }
87 12 : dmn = deterministicMNManager->GetListAtChainTip().GetValidMN(info.proTxHash);
88 6 : if (!dmn) {
89 0 : return errorOut(strprintf("Active masternode %s not registered or PoSe banned", info.proTxHash.ToString()));
90 : }
91 6 : if (info.pubKeyOperator != dmn->pdmnState->pubKeyOperator.Get()) {
92 0 : return errorOut("Active masternode operator key changed or revoked");
93 : }
94 : // return key
95 6 : key = info.keyOperator;
96 6 : return {true};
97 : }
98 :
99 7 : void CActiveDeterministicMasternodeManager::Init(const CBlockIndex* pindexTip)
100 : {
101 : // set masternode arg if called from RPC
102 7 : if (!fMasterNode) {
103 14 : gArgs.ForceSetArg("-masternode", "1");
104 7 : fMasterNode = true;
105 : }
106 :
107 7 : 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 14 : LOCK(cs_main);
115 :
116 : // Check that our local network configuration is correct
117 7 : 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 0 : return;
123 : }
124 :
125 7 : 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 14 : CDeterministicMNList mnList = deterministicMNManager->GetListForBlock(pindexTip);
133 :
134 14 : CDeterministicMNCPtr dmn = mnList.GetMNByOperatorKey(info.pubKeyOperator);
135 7 : if (!dmn) {
136 : // MN not appeared on the chain yet
137 0 : return;
138 : }
139 :
140 7 : if (dmn->IsPoSeBanned()) {
141 0 : state = MASTERNODE_POSE_BANNED;
142 0 : return;
143 : }
144 :
145 14 : LogPrintf("%s: proTxHash=%s, proTx=%s\n", __func__, dmn->proTxHash.ToString(), dmn->ToString());
146 :
147 7 : if (info.service != dmn->pdmnState->addr) {
148 0 : state = MASTERNODE_ERROR;
149 0 : strError = strprintf("Local address %s does not match the address from ProTx (%s)",
150 0 : info.service.ToStringIPPort(), dmn->pdmnState->addr.ToStringIPPort());
151 0 : LogPrintf("%s ERROR: %s\n", __func__, strError);
152 : return;
153 : }
154 :
155 : // Check socket connectivity
156 14 : const std::string& strService = info.service.ToString();
157 7 : LogPrintf("%s: Checking inbound connection to '%s'\n", __func__, strService);
158 7 : SOCKET hSocket = CreateSocket(info.service);
159 7 : 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 0 : return;
164 : }
165 7 : bool fConnected = ConnectSocketDirectly(info.service, hSocket, nConnectTimeout, true) && IsSelectableSocket(hSocket);
166 7 : CloseSocket(hSocket);
167 :
168 7 : 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 7 : info.proTxHash = dmn->proTxHash;
176 7 : g_connman->GetTierTwoConnMan()->setLocalDMN(info.proTxHash);
177 7 : state = MASTERNODE_READY;
178 7 : LogPrintf("Deterministic Masternode initialized\n");
179 : }
180 :
181 0 : void CActiveDeterministicMasternodeManager::Reset(masternode_state_t _state, const CBlockIndex* pindexTip)
182 : {
183 0 : state = _state;
184 0 : SetNullProTx();
185 : // MN might have reappeared in same block with a new ProTx
186 0 : Init(pindexTip);
187 0 : }
188 :
189 12 : void CActiveDeterministicMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, const CBlockIndex* pindexFork, bool fInitialDownload)
190 : {
191 12 : if (fInitialDownload)
192 : return;
193 :
194 12 : if (!fMasterNode || !deterministicMNManager->IsDIP3Enforced(pindexNew->nHeight))
195 0 : return;
196 :
197 12 : if (state == MASTERNODE_READY) {
198 24 : auto newDmn = deterministicMNManager->GetListForBlock(pindexNew).GetValidMN(info.proTxHash);
199 12 : if (newDmn == nullptr) {
200 : // MN disappeared from MN list
201 0 : Reset(MASTERNODE_REMOVED, pindexNew);
202 0 : return;
203 : }
204 :
205 24 : auto oldDmn = deterministicMNManager->GetListForBlock(pindexNew->pprev).GetMN(info.proTxHash);
206 12 : 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 0 : return;
211 : }
212 :
213 12 : 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 12 : if (newDmn->pdmnState->addr != oldDmn->pdmnState->addr) {
220 : // MN IP changed
221 0 : 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 0 : 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 7 : OperationResult initMasternode(const std::string& _strMasterNodePrivKey, const std::string& _strMasterNodeAddr, bool isFromInit)
241 : {
242 7 : if (!isFromInit && fMasterNode) {
243 0 : return errorOut( "ERROR: Masternode already initialized.");
244 : }
245 :
246 14 : LOCK(cs_main); // Lock cs_main so the node doesn't perform any action while we setup the Masternode
247 7 : LogPrintf("Initializing masternode, addr %s..\n", _strMasterNodeAddr.c_str());
248 :
249 7 : if (_strMasterNodePrivKey.empty()) {
250 0 : return errorOut("ERROR: Masternode priv key cannot be empty.");
251 : }
252 :
253 7 : if (_strMasterNodeAddr.empty()) {
254 0 : return errorOut("ERROR: Empty masternodeaddr");
255 : }
256 :
257 : // Address parsing.
258 7 : const CChainParams& params = Params();
259 7 : int nPort = 0;
260 7 : int nDefaultPort = params.GetDefaultPort();
261 14 : std::string strHost;
262 14 : 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 7 : if (nPort == 0) nPort = nDefaultPort;
267 7 : 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 14 : CService addrTest(LookupNumeric(strHost, nPort));
272 7 : 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 7 : 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 14 : CKey key;
284 7 : CPubKey pubkey;
285 7 : if (!CMessageSigner::GetKeysFromSecret(_strMasterNodePrivKey, key, pubkey)) {
286 0 : return errorOut(_("Invalid masternodeprivkey. Please see the documentation."));
287 : }
288 :
289 7 : activeMasternode.pubKeyMasternode = pubkey;
290 7 : activeMasternode.privKeyMasternode = key;
291 7 : activeMasternode.service = addrTest;
292 7 : fMasterNode = true;
293 :
294 7 : if (g_tiertwo_sync_state.IsBlockchainSynced()) {
295 : // Check if the masternode already exists in the list
296 7 : CMasternode* pmn = mnodeman.Find(pubkey);
297 7 : if (pmn) activeMasternode.EnableHotColdMasterNode(pmn->vin, pmn->addr);
298 : }
299 :
300 7 : return {true};
301 : }
302 :
303 : //
304 : // Bootup the Masternode, look for a 10000 PIVX input and register on the network
305 : //
306 620 : void CActiveMasternode::ManageStatus()
307 : {
308 656 : if (!fMasterNode) return;
309 81 : if (activeMasternodeManager != nullptr) {
310 : // Deterministic masternode
311 : return;
312 : }
313 :
314 : // !TODO: Legacy masternodes - remove after enforcement
315 54 : LogPrint(BCLog::MASTERNODE, "CActiveMasternode::ManageStatus() - Begin\n");
316 :
317 : // If a DMN has been registered with same collateral, disable me.
318 54 : CMasternode* pmn = mnodeman.Find(pubKeyMasternode);
319 54 : 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 54 : 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 54 : if (status == ACTIVE_MASTERNODE_SYNC_IN_PROCESS) status = ACTIVE_MASTERNODE_INITIAL;
335 :
336 54 : if (status == ACTIVE_MASTERNODE_INITIAL || (pmn && status == ACTIVE_MASTERNODE_NOT_CAPABLE)) {
337 6 : 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 54 : if (status != ACTIVE_MASTERNODE_STARTED) {
349 : // Set defaults
350 9 : status = ACTIVE_MASTERNODE_NOT_CAPABLE;
351 9 : notCapableReason = "";
352 :
353 9 : LogPrintf("%s - Checking inbound connection for masternode to '%s'\n", __func__ , service.ToString());
354 :
355 18 : CAddress addr(service, NODE_NETWORK);
356 9 : if (!g_connman->IsNodeConnected(addr)) {
357 9 : CNode* node = g_connman->ConnectNode(addr);
358 9 : if (!node) {
359 9 : notCapableReason =
360 18 : "Masternode address:port connection availability test failed, could not open a connection to the public masternode address (" +
361 21 : service.ToString() + ")";
362 9 : LogPrintf("%s - not capable: %s\n", __func__, notCapableReason);
363 : } else {
364 : // don't leak allocated object in memory
365 0 : delete node;
366 : }
367 9 : return;
368 : }
369 :
370 9 : notCapableReason = "Waiting for start message from controller.";
371 : return;
372 : }
373 :
374 : //send to all peers
375 90 : std::string errorMessage;
376 45 : if (!SendMasternodePing(errorMessage)) {
377 27 : 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 0 : std::string CActiveMasternode::GetStatusMessage() const
388 : {
389 0 : 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 0 : case ACTIVE_MASTERNODE_NOT_CAPABLE:
395 0 : return "Not capable masternode: " + notCapableReason;
396 0 : case ACTIVE_MASTERNODE_STARTED:
397 0 : return "Masternode successfully started";
398 0 : default:
399 0 : return "unknown";
400 : }
401 : }
402 :
403 177 : bool CActiveMasternode::SendMasternodePing(std::string& errorMessage)
404 : {
405 177 : if (vin == nullopt) {
406 0 : errorMessage = "Active Masternode not initialized";
407 0 : return false;
408 : }
409 :
410 177 : if (status != ACTIVE_MASTERNODE_STARTED) {
411 0 : errorMessage = "Masternode is not in a running status";
412 0 : return false;
413 : }
414 :
415 177 : if (!privKeyMasternode.IsValid() || !pubKeyMasternode.IsValid()) {
416 0 : errorMessage = "Error upon masternode key.\n";
417 0 : return false;
418 : }
419 :
420 177 : LogPrintf("CActiveMasternode::SendMasternodePing() - Relay Masternode Ping vin = %s\n", vin->ToString());
421 :
422 177 : const uint256& nBlockHash = mnodeman.GetBlockHashToPing();
423 177 : CMasternodePing mnp(*vin, nBlockHash, GetAdjustedTime());
424 177 : 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 177 : CMasternode* pmn = mnodeman.Find(vin->prevout);
431 177 : if (pmn != nullptr) {
432 176 : if (pmn->IsPingedWithin(MasternodePingSeconds(), mnp.sigTime)) {
433 47 : 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 129 : pmn->SetLastPing(mnp);
439 129 : mnodeman.mapSeenMasternodePing.emplace(mnp.GetHash(), mnp);
440 :
441 : //mnodeman.mapSeenMasternodeBroadcast.lastPing is probably outdated, so we'll update it
442 305 : CMasternodeBroadcast mnb(*pmn);
443 129 : uint256 hash = mnb.GetHash();
444 129 : 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 129 : mnodeman.mapSeenMasternodeBroadcast[hash].SetLastPing(mnp);
448 : }
449 :
450 129 : mnp.Relay();
451 129 : 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 1 : errorMessage = "Masternode List doesn't include our Masternode, shutting down Masternode pinging service! " + vin->ToString();
456 1 : status = ACTIVE_MASTERNODE_NOT_CAPABLE;
457 177 : 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 9 : bool CActiveMasternode::EnableHotColdMasterNode(CTxIn& newVin, CService& newService)
464 : {
465 9 : if (!fMasterNode) return false;
466 :
467 9 : status = ACTIVE_MASTERNODE_STARTED;
468 :
469 : //The values below are needed for signing mnping messages going forward
470 9 : vin = newVin;
471 9 : service = newService;
472 :
473 9 : LogPrintf("CActiveMasternode::EnableHotColdMasterNode() - Enabled! You may shut down the cold daemon.\n");
474 :
475 9 : return true;
476 : }
477 :
478 128 : void CActiveMasternode::GetKeys(CKey& _privKeyMasternode, CPubKey& _pubKeyMasternode) const
479 : {
480 128 : if (!privKeyMasternode.IsValid() || !pubKeyMasternode.IsValid()) {
481 0 : throw std::runtime_error("Error trying to get masternode keys");
482 : }
483 128 : _privKeyMasternode = privKeyMasternode;
484 128 : _pubKeyMasternode = pubKeyMasternode;
485 128 : }
486 :
487 6 : bool GetActiveDMNKeys(CBLSSecretKey& key, CTxIn& vin)
488 : {
489 6 : if (activeMasternodeManager == nullptr) {
490 0 : return error("%s: Active Masternode not initialized", __func__);
491 : }
492 6 : CDeterministicMNCPtr dmn;
493 12 : auto res = activeMasternodeManager->GetOperatorKey(key, dmn);
494 6 : if (!res) {
495 0 : return error("%s: %s", __func__, res.getError());
496 : }
497 6 : vin = CTxIn(dmn->collateralOutpoint);
498 6 : return true;
499 : }
500 :
501 141 : bool GetActiveMasternodeKeys(CTxIn& vin, Optional<CKey>& key, CBLSSecretKey& blsKey)
502 : {
503 141 : if (activeMasternodeManager != nullptr) {
504 : // deterministic mn
505 6 : key = nullopt;
506 6 : return GetActiveDMNKeys(blsKey, vin);
507 : }
508 : // legacy mn
509 135 : if (activeMasternode.vin == nullopt) {
510 7 : return error("%s: Active Masternode not initialized", __func__);
511 : }
512 128 : if (activeMasternode.GetStatus() != ACTIVE_MASTERNODE_STARTED) {
513 0 : return error("%s: MN not started (%s)", __func__, activeMasternode.GetStatusMessage());
514 : }
515 128 : vin = *activeMasternode.vin;
516 269 : CKey sk;
517 128 : CPubKey pk;
518 128 : activeMasternode.GetKeys(sk, pk);
519 128 : key = Optional<CKey>(sk);
520 128 : blsKey.Reset();
521 128 : return true;
522 : }
|