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 : }
|