Dash Core  0.12.2.1
P2P Digital Currency
masternode.cpp
Go to the documentation of this file.
1 // Copyright (c) 2014-2017 The Dash Core developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "activemasternode.h"
6 #include "init.h"
7 #include "netbase.h"
8 #include "validation.h"
9 #include "masternode-payments.h"
10 #include "masternode-sync.h"
11 #include "masternodeconfig.h"
12 #include "masternodeman.h"
13 #include "privatesend-client.h"
14 #include "privatesend-server.h"
15 #include "rpc/server.h"
16 #include "util.h"
17 #include "utilmoneystr.h"
18 
19 #include <fstream>
20 #include <iomanip>
21 #include <univalue.h>
22 
24 
25 UniValue privatesend(const UniValue& params, bool fHelp)
26 {
27  if (fHelp || params.size() != 1)
28  throw std::runtime_error(
29  "privatesend \"command\"\n"
30  "\nArguments:\n"
31  "1. \"command\" (string or set of strings, required) The command to execute\n"
32  "\nAvailable commands:\n"
33  " start - Start mixing\n"
34  " stop - Stop mixing\n"
35  " reset - Reset mixing\n"
36  );
37 
38  if(params[0].get_str() == "start") {
39  {
42  }
43 
44  if(fMasterNode)
45  return "Mixing is not supported from masternodes";
46 
49  return "Mixing " + (result ? "started successfully" : ("start failed: " + privateSendClient.GetStatus() + ", will retry"));
50  }
51 
52  if(params[0].get_str() == "stop") {
54  return "Mixing was stopped";
55  }
56 
57  if(params[0].get_str() == "reset") {
59  return "Mixing was reset";
60  }
61 
62  return "Unknown command, please see \"help privatesend\"";
63 }
64 
65 UniValue getpoolinfo(const UniValue& params, bool fHelp)
66 {
67  if (fHelp || params.size() != 0)
68  throw std::runtime_error(
69  "getpoolinfo\n"
70  "Returns an object containing mixing pool related information.\n");
71 
73 
75  obj.push_back(Pair("state", privateSend.GetStateString()));
76  obj.push_back(Pair("mixing_mode", (!fMasterNode && privateSendClient.fPrivateSendMultiSession) ? "multi-session" : "normal"));
77  obj.push_back(Pair("queue", privateSend.GetQueueSize()));
78  obj.push_back(Pair("entries", privateSend.GetEntriesCount()));
79  obj.push_back(Pair("status", privateSendClient.GetStatus()));
80 
84  }
85 
86  if (pwalletMain) {
89  ? "WARNING: keypool is almost depleted!" : ""));
90  }
91 
92  return obj;
93 }
94 
95 
96 UniValue masternode(const UniValue& params, bool fHelp)
97 {
98  std::string strCommand;
99  if (params.size() >= 1) {
100  strCommand = params[0].get_str();
101  }
102 
103  if (strCommand == "start-many")
104  throw JSONRPCError(RPC_INVALID_PARAMETER, "DEPRECATED, please use start-all instead");
105 
106  if (fHelp ||
107  (strCommand != "start" && strCommand != "start-alias" && strCommand != "start-all" && strCommand != "start-missing" &&
108  strCommand != "start-disabled" && strCommand != "list" && strCommand != "list-conf" && strCommand != "count" &&
109  strCommand != "debug" && strCommand != "current" && strCommand != "winner" && strCommand != "winners" && strCommand != "genkey" &&
110  strCommand != "connect" && strCommand != "outputs" && strCommand != "status"))
111  throw std::runtime_error(
112  "masternode \"command\"...\n"
113  "Set of commands to execute masternode related actions\n"
114  "\nArguments:\n"
115  "1. \"command\" (string or set of strings, required) The command to execute\n"
116  "\nAvailable commands:\n"
117  " count - Print number of all known masternodes (optional: 'ps', 'enabled', 'all', 'qualify')\n"
118  " current - Print info on current masternode winner to be paid the next block (calculated locally)\n"
119  " debug - Print masternode status\n"
120  " genkey - Generate new masternodeprivkey\n"
121  " outputs - Print masternode compatible outputs\n"
122  " start - Start local Hot masternode configured in dash.conf\n"
123  " start-alias - Start single remote masternode by assigned alias configured in masternode.conf\n"
124  " start-<mode> - Start remote masternodes configured in masternode.conf (<mode>: 'all', 'missing', 'disabled')\n"
125  " status - Print masternode status information\n"
126  " list - Print list of all known masternodes (see masternodelist for more info)\n"
127  " list-conf - Print masternode.conf in JSON format\n"
128  " winner - Print info on next masternode winner to vote for\n"
129  " winners - Print list of masternode winners\n"
130  );
131 
132  if (strCommand == "list")
133  {
134  UniValue newParams(UniValue::VARR);
135  // forward params but skip "list"
136  for (unsigned int i = 1; i < params.size(); i++) {
137  newParams.push_back(params[i]);
138  }
139  return masternodelist(newParams, fHelp);
140  }
141 
142  if(strCommand == "connect")
143  {
144  if (params.size() < 2)
145  throw JSONRPCError(RPC_INVALID_PARAMETER, "Masternode address required");
146 
147  std::string strAddress = params[1].get_str();
148 
149  CService addr;
150  if (!Lookup(strAddress.c_str(), addr, 0, false))
151  throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Incorrect masternode address %s", strAddress));
152 
153  // TODO: Pass CConnman instance somehow and don't use global variable.
154  CNode *pnode = g_connman->ConnectNode(CAddress(addr, NODE_NETWORK), NULL);
155  if(!pnode)
156  throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Couldn't connect to masternode %s", strAddress));
157 
158  return "successfully connected";
159  }
160 
161  if (strCommand == "count")
162  {
163  if (params.size() > 2)
164  throw JSONRPCError(RPC_INVALID_PARAMETER, "Too many parameters");
165 
166  if (params.size() == 1)
167  return mnodeman.size();
168 
169  std::string strMode = params[1].get_str();
170 
171  if (strMode == "ps")
173 
174  if (strMode == "enabled")
175  return mnodeman.CountEnabled();
176 
177  int nCount;
178  masternode_info_t mnInfo;
179  mnodeman.GetNextMasternodeInQueueForPayment(true, nCount, mnInfo);
180 
181  if (strMode == "qualify")
182  return nCount;
183 
184  if (strMode == "all")
185  return strprintf("Total: %d (PS Compatible: %d / Enabled: %d / Qualify: %d)",
187  mnodeman.CountEnabled(), nCount);
188  }
189 
190  if (strCommand == "current" || strCommand == "winner")
191  {
192  int nCount;
193  int nHeight;
194  masternode_info_t mnInfo;
195  CBlockIndex* pindex = NULL;
196  {
197  LOCK(cs_main);
198  pindex = chainActive.Tip();
199  }
200  nHeight = pindex->nHeight + (strCommand == "current" ? 1 : 10);
201  mnodeman.UpdateLastPaid(pindex);
202 
203  if(!mnodeman.GetNextMasternodeInQueueForPayment(nHeight, true, nCount, mnInfo))
204  return "unknown";
205 
207 
208  obj.push_back(Pair("height", nHeight));
209  obj.push_back(Pair("IP:port", mnInfo.addr.ToString()));
210  obj.push_back(Pair("protocol", (int64_t)mnInfo.nProtocolVersion));
211  obj.push_back(Pair("outpoint", mnInfo.vin.prevout.ToStringShort()));
212  obj.push_back(Pair("payee", CBitcoinAddress(mnInfo.pubKeyCollateralAddress.GetID()).ToString()));
213  obj.push_back(Pair("lastseen", mnInfo.nTimeLastPing));
214  obj.push_back(Pair("activeseconds", mnInfo.nTimeLastPing - mnInfo.sigTime));
215  return obj;
216  }
217 
218  if (strCommand == "debug")
219  {
221  return activeMasternode.GetStatus();
222 
223  COutPoint outpoint;
224  CPubKey pubkey;
225  CKey key;
226 
227  if(!pwalletMain || !pwalletMain->GetMasternodeOutpointAndKeys(outpoint, pubkey, key))
228  throw JSONRPCError(RPC_INVALID_PARAMETER, "Missing masternode input, please look at the documentation for instructions on masternode creation");
229 
230  return activeMasternode.GetStatus();
231  }
232 
233  if (strCommand == "start")
234  {
235  if(!fMasterNode)
236  throw JSONRPCError(RPC_INTERNAL_ERROR, "You must set masternode=1 in the configuration");
237 
238  {
241  }
242 
244  activeMasternode.nState = ACTIVE_MASTERNODE_INITIAL; // TODO: consider better way
246  }
247 
248  return activeMasternode.GetStatus();
249  }
250 
251  if (strCommand == "start-alias")
252  {
253  if (params.size() < 2)
254  throw JSONRPCError(RPC_INVALID_PARAMETER, "Please specify an alias");
255 
256  {
259  }
260 
261  std::string strAlias = params[1].get_str();
262 
263  bool fFound = false;
264 
265  UniValue statusObj(UniValue::VOBJ);
266  statusObj.push_back(Pair("alias", strAlias));
267 
269  if(mne.getAlias() == strAlias) {
270  fFound = true;
271  std::string strError;
273 
274  bool fResult = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb);
275 
276  statusObj.push_back(Pair("result", fResult ? "successful" : "failed"));
277  if(fResult) {
279  mnb.Relay(*g_connman);
280  } else {
281  statusObj.push_back(Pair("errorMessage", strError));
282  }
284  break;
285  }
286  }
287 
288  if(!fFound) {
289  statusObj.push_back(Pair("result", "failed"));
290  statusObj.push_back(Pair("errorMessage", "Could not find alias in config. Verify with list-conf."));
291  }
292 
293  return statusObj;
294 
295  }
296 
297  if (strCommand == "start-all" || strCommand == "start-missing" || strCommand == "start-disabled")
298  {
299  {
302  }
303 
304  if((strCommand == "start-missing" || strCommand == "start-disabled") && !masternodeSync.IsMasternodeListSynced()) {
305  throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "You can't use this command until masternode list is synced");
306  }
307 
308  int nSuccessful = 0;
309  int nFailed = 0;
310 
311  UniValue resultsObj(UniValue::VOBJ);
312 
314  std::string strError;
315 
316  COutPoint outpoint = COutPoint(uint256S(mne.getTxHash()), uint32_t(atoi(mne.getOutputIndex().c_str())));
317  CMasternode mn;
318  bool fFound = mnodeman.Get(outpoint, mn);
320 
321  if(strCommand == "start-missing" && fFound) continue;
322  if(strCommand == "start-disabled" && fFound && mn.IsEnabled()) continue;
323 
324  bool fResult = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb);
325 
326  UniValue statusObj(UniValue::VOBJ);
327  statusObj.push_back(Pair("alias", mne.getAlias()));
328  statusObj.push_back(Pair("result", fResult ? "successful" : "failed"));
329 
330  if (fResult) {
331  nSuccessful++;
333  mnb.Relay(*g_connman);
334  } else {
335  nFailed++;
336  statusObj.push_back(Pair("errorMessage", strError));
337  }
338 
339  resultsObj.push_back(Pair("status", statusObj));
340  }
342 
343  UniValue returnObj(UniValue::VOBJ);
344  returnObj.push_back(Pair("overall", strprintf("Successfully started %d masternodes, failed to start %d, total %d", nSuccessful, nFailed, nSuccessful + nFailed)));
345  returnObj.push_back(Pair("detail", resultsObj));
346 
347  return returnObj;
348  }
349 
350  if (strCommand == "genkey")
351  {
352  CKey secret;
353  secret.MakeNewKey(false);
354 
355  return CBitcoinSecret(secret).ToString();
356  }
357 
358  if (strCommand == "list-conf")
359  {
360  UniValue resultObj(UniValue::VOBJ);
361 
363  COutPoint outpoint = COutPoint(uint256S(mne.getTxHash()), uint32_t(atoi(mne.getOutputIndex().c_str())));
364  CMasternode mn;
365  bool fFound = mnodeman.Get(outpoint, mn);
366 
367  std::string strStatus = fFound ? mn.GetStatus() : "MISSING";
368 
369  UniValue mnObj(UniValue::VOBJ);
370  mnObj.push_back(Pair("alias", mne.getAlias()));
371  mnObj.push_back(Pair("address", mne.getIp()));
372  mnObj.push_back(Pair("privateKey", mne.getPrivKey()));
373  mnObj.push_back(Pair("txHash", mne.getTxHash()));
374  mnObj.push_back(Pair("outputIndex", mne.getOutputIndex()));
375  mnObj.push_back(Pair("status", strStatus));
376  resultObj.push_back(Pair("masternode", mnObj));
377  }
378 
379  return resultObj;
380  }
381 
382  if (strCommand == "outputs") {
383  // Find possible candidates
384  std::vector<COutput> vPossibleCoins;
385  pwalletMain->AvailableCoins(vPossibleCoins, true, NULL, false, ONLY_1000);
386 
388  BOOST_FOREACH(COutput& out, vPossibleCoins) {
389  obj.push_back(Pair(out.tx->GetHash().ToString(), strprintf("%d", out.i)));
390  }
391 
392  return obj;
393 
394  }
395 
396  if (strCommand == "status")
397  {
398  if (!fMasterNode)
399  throw JSONRPCError(RPC_INTERNAL_ERROR, "This is not a masternode");
400 
401  UniValue mnObj(UniValue::VOBJ);
402 
403  mnObj.push_back(Pair("outpoint", activeMasternode.outpoint.ToStringShort()));
404  mnObj.push_back(Pair("service", activeMasternode.service.ToString()));
405 
406  CMasternode mn;
408  mnObj.push_back(Pair("payee", CBitcoinAddress(mn.pubKeyCollateralAddress.GetID()).ToString()));
409  }
410 
411  mnObj.push_back(Pair("status", activeMasternode.GetStatus()));
412  return mnObj;
413  }
414 
415  if (strCommand == "winners")
416  {
417  int nHeight;
418  {
419  LOCK(cs_main);
420  CBlockIndex* pindex = chainActive.Tip();
421  if(!pindex) return NullUniValue;
422 
423  nHeight = pindex->nHeight;
424  }
425 
426  int nLast = 10;
427  std::string strFilter = "";
428 
429  if (params.size() >= 2) {
430  nLast = atoi(params[1].get_str());
431  }
432 
433  if (params.size() == 3) {
434  strFilter = params[2].get_str();
435  }
436 
437  if (params.size() > 3)
438  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'masternode winners ( \"count\" \"filter\" )'");
439 
441 
442  for(int i = nHeight - nLast; i < nHeight + 20; i++) {
443  std::string strPayment = GetRequiredPaymentsString(i);
444  if (strFilter !="" && strPayment.find(strFilter) == std::string::npos) continue;
445  obj.push_back(Pair(strprintf("%d", i), strPayment));
446  }
447 
448  return obj;
449  }
450 
451  return NullUniValue;
452 }
453 
454 UniValue masternodelist(const UniValue& params, bool fHelp)
455 {
456  std::string strMode = "status";
457  std::string strFilter = "";
458 
459  if (params.size() >= 1) strMode = params[0].get_str();
460  if (params.size() == 2) strFilter = params[1].get_str();
461 
462  if (fHelp || (
463  strMode != "activeseconds" && strMode != "addr" && strMode != "full" && strMode != "info" &&
464  strMode != "lastseen" && strMode != "lastpaidtime" && strMode != "lastpaidblock" &&
465  strMode != "protocol" && strMode != "payee" && strMode != "pubkey" &&
466  strMode != "rank" && strMode != "status"))
467  {
468  throw std::runtime_error(
469  "masternodelist ( \"mode\" \"filter\" )\n"
470  "Get a list of masternodes in different modes\n"
471  "\nArguments:\n"
472  "1. \"mode\" (string, optional/required to use filter, defaults = status) The mode to run list in\n"
473  "2. \"filter\" (string, optional) Filter results. Partial match by outpoint by default in all modes,\n"
474  " additional matches in some modes are also available\n"
475  "\nAvailable modes:\n"
476  " activeseconds - Print number of seconds masternode recognized by the network as enabled\n"
477  " (since latest issued \"masternode start/start-many/start-alias\")\n"
478  " addr - Print ip address associated with a masternode (can be additionally filtered, partial match)\n"
479  " full - Print info in format 'status protocol payee lastseen activeseconds lastpaidtime lastpaidblock IP'\n"
480  " (can be additionally filtered, partial match)\n"
481  " info - Print info in format 'status protocol payee lastseen activeseconds sentinelversion sentinelstate IP'\n"
482  " (can be additionally filtered, partial match)\n"
483  " lastpaidblock - Print the last block height a node was paid on the network\n"
484  " lastpaidtime - Print the last time a node was paid on the network\n"
485  " lastseen - Print timestamp of when a masternode was last seen on the network\n"
486  " payee - Print Dash address associated with a masternode (can be additionally filtered,\n"
487  " partial match)\n"
488  " protocol - Print protocol of a masternode (can be additionally filtered, exact match))\n"
489  " pubkey - Print the masternode (not collateral) public key\n"
490  " rank - Print rank of a masternode based on current block\n"
491  " status - Print masternode status: PRE_ENABLED / ENABLED / EXPIRED / WATCHDOG_EXPIRED / NEW_START_REQUIRED /\n"
492  " UPDATE_REQUIRED / POSE_BAN / OUTPOINT_SPENT (can be additionally filtered, partial match)\n"
493  );
494  }
495 
496  if (strMode == "full" || strMode == "lastpaidtime" || strMode == "lastpaidblock") {
497  CBlockIndex* pindex = NULL;
498  {
499  LOCK(cs_main);
500  pindex = chainActive.Tip();
501  }
502  mnodeman.UpdateLastPaid(pindex);
503  }
504 
506  if (strMode == "rank") {
507  CMasternodeMan::rank_pair_vec_t vMasternodeRanks;
508  mnodeman.GetMasternodeRanks(vMasternodeRanks);
509  BOOST_FOREACH(PAIRTYPE(int, CMasternode)& s, vMasternodeRanks) {
510  std::string strOutpoint = s.second.vin.prevout.ToStringShort();
511  if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue;
512  obj.push_back(Pair(strOutpoint, s.first));
513  }
514  } else {
515  std::map<COutPoint, CMasternode> mapMasternodes = mnodeman.GetFullMasternodeMap();
516  for (auto& mnpair : mapMasternodes) {
517  CMasternode mn = mnpair.second;
518  std::string strOutpoint = mnpair.first.ToStringShort();
519  if (strMode == "activeseconds") {
520  if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue;
521  obj.push_back(Pair(strOutpoint, (int64_t)(mn.lastPing.sigTime - mn.sigTime)));
522  } else if (strMode == "addr") {
523  std::string strAddress = mn.addr.ToString();
524  if (strFilter !="" && strAddress.find(strFilter) == std::string::npos &&
525  strOutpoint.find(strFilter) == std::string::npos) continue;
526  obj.push_back(Pair(strOutpoint, strAddress));
527  } else if (strMode == "full") {
528  std::ostringstream streamFull;
529  streamFull << std::setw(18) <<
530  mn.GetStatus() << " " <<
531  mn.nProtocolVersion << " " <<
532  CBitcoinAddress(mn.pubKeyCollateralAddress.GetID()).ToString() << " " <<
533  (int64_t)mn.lastPing.sigTime << " " << std::setw(8) <<
534  (int64_t)(mn.lastPing.sigTime - mn.sigTime) << " " << std::setw(10) <<
535  mn.GetLastPaidTime() << " " << std::setw(6) <<
536  mn.GetLastPaidBlock() << " " <<
537  mn.addr.ToString();
538  std::string strFull = streamFull.str();
539  if (strFilter !="" && strFull.find(strFilter) == std::string::npos &&
540  strOutpoint.find(strFilter) == std::string::npos) continue;
541  obj.push_back(Pair(strOutpoint, strFull));
542  } else if (strMode == "info") {
543  std::ostringstream streamInfo;
544  streamInfo << std::setw(18) <<
545  mn.GetStatus() << " " <<
546  mn.nProtocolVersion << " " <<
547  CBitcoinAddress(mn.pubKeyCollateralAddress.GetID()).ToString() << " " <<
548  (int64_t)mn.lastPing.sigTime << " " << std::setw(8) <<
549  (int64_t)(mn.lastPing.sigTime - mn.sigTime) << " " <<
551  (mn.lastPing.fSentinelIsCurrent ? "current" : "expired") << " " <<
552  mn.addr.ToString();
553  std::string strInfo = streamInfo.str();
554  if (strFilter !="" && strInfo.find(strFilter) == std::string::npos &&
555  strOutpoint.find(strFilter) == std::string::npos) continue;
556  obj.push_back(Pair(strOutpoint, strInfo));
557  } else if (strMode == "lastpaidblock") {
558  if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue;
559  obj.push_back(Pair(strOutpoint, mn.GetLastPaidBlock()));
560  } else if (strMode == "lastpaidtime") {
561  if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue;
562  obj.push_back(Pair(strOutpoint, mn.GetLastPaidTime()));
563  } else if (strMode == "lastseen") {
564  if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue;
565  obj.push_back(Pair(strOutpoint, (int64_t)mn.lastPing.sigTime));
566  } else if (strMode == "payee") {
568  std::string strPayee = address.ToString();
569  if (strFilter !="" && strPayee.find(strFilter) == std::string::npos &&
570  strOutpoint.find(strFilter) == std::string::npos) continue;
571  obj.push_back(Pair(strOutpoint, strPayee));
572  } else if (strMode == "protocol") {
573  if (strFilter !="" && strFilter != strprintf("%d", mn.nProtocolVersion) &&
574  strOutpoint.find(strFilter) == std::string::npos) continue;
575  obj.push_back(Pair(strOutpoint, (int64_t)mn.nProtocolVersion));
576  } else if (strMode == "pubkey") {
577  if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue;
578  obj.push_back(Pair(strOutpoint, HexStr(mn.pubKeyMasternode)));
579  } else if (strMode == "status") {
580  std::string strStatus = mn.GetStatus();
581  if (strFilter !="" && strStatus.find(strFilter) == std::string::npos &&
582  strOutpoint.find(strFilter) == std::string::npos) continue;
583  obj.push_back(Pair(strOutpoint, strStatus));
584  }
585  }
586  }
587  return obj;
588 }
589 
590 bool DecodeHexVecMnb(std::vector<CMasternodeBroadcast>& vecMnb, std::string strHexMnb) {
591 
592  if (!IsHex(strHexMnb))
593  return false;
594 
595  std::vector<unsigned char> mnbData(ParseHex(strHexMnb));
596  CDataStream ssData(mnbData, SER_NETWORK, PROTOCOL_VERSION);
597  try {
598  ssData >> vecMnb;
599  }
600  catch (const std::exception&) {
601  return false;
602  }
603 
604  return true;
605 }
606 
607 UniValue masternodebroadcast(const UniValue& params, bool fHelp)
608 {
609  std::string strCommand;
610  if (params.size() >= 1)
611  strCommand = params[0].get_str();
612 
613  if (fHelp ||
614  (strCommand != "create-alias" && strCommand != "create-all" && strCommand != "decode" && strCommand != "relay"))
615  throw std::runtime_error(
616  "masternodebroadcast \"command\"...\n"
617  "Set of commands to create and relay masternode broadcast messages\n"
618  "\nArguments:\n"
619  "1. \"command\" (string or set of strings, required) The command to execute\n"
620  "\nAvailable commands:\n"
621  " create-alias - Create single remote masternode broadcast message by assigned alias configured in masternode.conf\n"
622  " create-all - Create remote masternode broadcast messages for all masternodes configured in masternode.conf\n"
623  " decode - Decode masternode broadcast message\n"
624  " relay - Relay masternode broadcast message to the network\n"
625  );
626 
627  if (strCommand == "create-alias")
628  {
629  // wait for reindex and/or import to finish
630  if (fImporting || fReindex)
631  throw JSONRPCError(RPC_INTERNAL_ERROR, "Wait for reindex and/or import to finish");
632 
633  if (params.size() < 2)
634  throw JSONRPCError(RPC_INVALID_PARAMETER, "Please specify an alias");
635 
636  {
639  }
640 
641  bool fFound = false;
642  std::string strAlias = params[1].get_str();
643 
644  UniValue statusObj(UniValue::VOBJ);
645  std::vector<CMasternodeBroadcast> vecMnb;
646 
647  statusObj.push_back(Pair("alias", strAlias));
648 
650  if(mne.getAlias() == strAlias) {
651  fFound = true;
652  std::string strError;
654 
655  bool fResult = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb, true);
656 
657  statusObj.push_back(Pair("result", fResult ? "successful" : "failed"));
658  if(fResult) {
659  vecMnb.push_back(mnb);
661  ssVecMnb << vecMnb;
662  statusObj.push_back(Pair("hex", HexStr(ssVecMnb.begin(), ssVecMnb.end())));
663  } else {
664  statusObj.push_back(Pair("errorMessage", strError));
665  }
666  break;
667  }
668  }
669 
670  if(!fFound) {
671  statusObj.push_back(Pair("result", "not found"));
672  statusObj.push_back(Pair("errorMessage", "Could not find alias in config. Verify with list-conf."));
673  }
674 
675  return statusObj;
676 
677  }
678 
679  if (strCommand == "create-all")
680  {
681  // wait for reindex and/or import to finish
682  if (fImporting || fReindex)
683  throw JSONRPCError(RPC_INTERNAL_ERROR, "Wait for reindex and/or import to finish");
684 
685  {
688  }
689 
690  std::vector<CMasternodeConfig::CMasternodeEntry> mnEntries;
691  mnEntries = masternodeConfig.getEntries();
692 
693  int nSuccessful = 0;
694  int nFailed = 0;
695 
696  UniValue resultsObj(UniValue::VOBJ);
697  std::vector<CMasternodeBroadcast> vecMnb;
698 
700  std::string strError;
702 
703  bool fResult = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb, true);
704 
705  UniValue statusObj(UniValue::VOBJ);
706  statusObj.push_back(Pair("alias", mne.getAlias()));
707  statusObj.push_back(Pair("result", fResult ? "successful" : "failed"));
708 
709  if(fResult) {
710  nSuccessful++;
711  vecMnb.push_back(mnb);
712  } else {
713  nFailed++;
714  statusObj.push_back(Pair("errorMessage", strError));
715  }
716 
717  resultsObj.push_back(Pair("status", statusObj));
718  }
719 
721  ssVecMnb << vecMnb;
722  UniValue returnObj(UniValue::VOBJ);
723  returnObj.push_back(Pair("overall", strprintf("Successfully created broadcast messages for %d masternodes, failed to create %d, total %d", nSuccessful, nFailed, nSuccessful + nFailed)));
724  returnObj.push_back(Pair("detail", resultsObj));
725  returnObj.push_back(Pair("hex", HexStr(ssVecMnb.begin(), ssVecMnb.end())));
726 
727  return returnObj;
728  }
729 
730  if (strCommand == "decode")
731  {
732  if (params.size() != 2)
733  throw JSONRPCError(RPC_INVALID_PARAMETER, "Correct usage is 'masternodebroadcast decode \"hexstring\"'");
734 
735  std::vector<CMasternodeBroadcast> vecMnb;
736 
737  if (!DecodeHexVecMnb(vecMnb, params[1].get_str()))
738  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Masternode broadcast message decode failed");
739 
740  int nSuccessful = 0;
741  int nFailed = 0;
742  int nDos = 0;
743  UniValue returnObj(UniValue::VOBJ);
744 
745  BOOST_FOREACH(CMasternodeBroadcast& mnb, vecMnb) {
746  UniValue resultObj(UniValue::VOBJ);
747 
748  if(mnb.CheckSignature(nDos)) {
749  nSuccessful++;
750  resultObj.push_back(Pair("outpoint", mnb.vin.prevout.ToStringShort()));
751  resultObj.push_back(Pair("addr", mnb.addr.ToString()));
752  resultObj.push_back(Pair("pubKeyCollateralAddress", CBitcoinAddress(mnb.pubKeyCollateralAddress.GetID()).ToString()));
753  resultObj.push_back(Pair("pubKeyMasternode", CBitcoinAddress(mnb.pubKeyMasternode.GetID()).ToString()));
754  resultObj.push_back(Pair("vchSig", EncodeBase64(&mnb.vchSig[0], mnb.vchSig.size())));
755  resultObj.push_back(Pair("sigTime", mnb.sigTime));
756  resultObj.push_back(Pair("protocolVersion", mnb.nProtocolVersion));
757  resultObj.push_back(Pair("nLastDsq", mnb.nLastDsq));
758 
759  UniValue lastPingObj(UniValue::VOBJ);
760  lastPingObj.push_back(Pair("outpoint", mnb.lastPing.vin.prevout.ToStringShort()));
761  lastPingObj.push_back(Pair("blockHash", mnb.lastPing.blockHash.ToString()));
762  lastPingObj.push_back(Pair("sigTime", mnb.lastPing.sigTime));
763  lastPingObj.push_back(Pair("vchSig", EncodeBase64(&mnb.lastPing.vchSig[0], mnb.lastPing.vchSig.size())));
764 
765  resultObj.push_back(Pair("lastPing", lastPingObj));
766  } else {
767  nFailed++;
768  resultObj.push_back(Pair("errorMessage", "Masternode broadcast signature verification failed"));
769  }
770 
771  returnObj.push_back(Pair(mnb.GetHash().ToString(), resultObj));
772  }
773 
774  returnObj.push_back(Pair("overall", strprintf("Successfully decoded broadcast messages for %d masternodes, failed to decode %d, total %d", nSuccessful, nFailed, nSuccessful + nFailed)));
775 
776  return returnObj;
777  }
778 
779  if (strCommand == "relay")
780  {
781  if (params.size() < 2 || params.size() > 3)
782  throw JSONRPCError(RPC_INVALID_PARAMETER, "masternodebroadcast relay \"hexstring\" ( fast )\n"
783  "\nArguments:\n"
784  "1. \"hex\" (string, required) Broadcast messages hex string\n"
785  "2. fast (string, optional) If none, using safe method\n");
786 
787  std::vector<CMasternodeBroadcast> vecMnb;
788 
789  if (!DecodeHexVecMnb(vecMnb, params[1].get_str()))
790  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Masternode broadcast message decode failed");
791 
792  int nSuccessful = 0;
793  int nFailed = 0;
794  bool fSafe = params.size() == 2;
795  UniValue returnObj(UniValue::VOBJ);
796 
797  // verify all signatures first, bailout if any of them broken
798  BOOST_FOREACH(CMasternodeBroadcast& mnb, vecMnb) {
799  UniValue resultObj(UniValue::VOBJ);
800 
801  resultObj.push_back(Pair("outpoint", mnb.vin.prevout.ToStringShort()));
802  resultObj.push_back(Pair("addr", mnb.addr.ToString()));
803 
804  int nDos = 0;
805  bool fResult;
806  if (mnb.CheckSignature(nDos)) {
807  if (fSafe) {
808  fResult = mnodeman.CheckMnbAndUpdateMasternodeList(NULL, mnb, nDos, *g_connman);
809  } else {
811  mnb.Relay(*g_connman);
812  fResult = true;
813  }
815  } else fResult = false;
816 
817  if(fResult) {
818  nSuccessful++;
819  resultObj.push_back(Pair(mnb.GetHash().ToString(), "successful"));
820  } else {
821  nFailed++;
822  resultObj.push_back(Pair("errorMessage", "Masternode broadcast signature verification failed"));
823  }
824 
825  returnObj.push_back(Pair(mnb.GetHash().ToString(), resultObj));
826  }
827 
828  returnObj.push_back(Pair("overall", strprintf("Successfully relayed broadcast messages for %d masternodes, failed to relay %d, total %d", nSuccessful, nFailed, nSuccessful + nFailed)));
829 
830  return returnObj;
831  }
832 
833  return NullUniValue;
834 }
835 
836 UniValue sentinelping(const UniValue& params, bool fHelp)
837 {
838  if (fHelp || params.size() != 1) {
839  throw std::runtime_error(
840  "sentinelping version\n"
841  "\nSentinel ping.\n"
842  "\nArguments:\n"
843  "1. version (string, required) Sentinel version in the form \"x.x.x\"\n"
844  "\nResult:\n"
845  "state (boolean) Ping result\n"
846  "\nExamples:\n"
847  + HelpExampleCli("sentinelping", "1.0.2")
848  + HelpExampleRpc("sentinelping", "1.0.2")
849  );
850  }
851 
853  return true;
854 }
int GetLastPaidTime()
Definition: masternode.h:270
void EnsureWalletIsUnlocked()
Definition: rpcwallet.cpp:54
std::string GetStateString() const
uint32_t nSentinelVersion
Definition: masternode.h:41
CMasternodeMan mnodeman
CMasternodeSync masternodeSync
CPrivateSendServer privateSendServer
std::vector< CMasternodeEntry > & getEntries()
bool CheckMnbAndUpdateMasternodeList(CNode *pfrom, CMasternodeBroadcast mnb, int &nDos, CConnman &connman)
Perform complete check and only then update list and maps.
CMasternodeConfig masternodeConfig
CActiveMasternode activeMasternode
void Relay(CConnman &connman)
Definition: masternode.cpp:665
std::string GetStatus() const
UniValue privatesend(const UniValue &params, bool fHelp)
Definition: masternode.cpp:25
#define strprintf
Definition: tinyformat.h:1011
CMasternodePing lastPing
Definition: masternode.h:156
CCriticalSection cs_wallet
Definition: wallet.h:672
const std::string & getOutputIndex() const
bool Get(const COutPoint &outpoint, CMasternode &masternodeRet)
Versions of Find that are safe to use from outside the class.
CCriticalSection cs_main
Definition: validation.cpp:62
bool fReindex
Definition: validation.cpp:71
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
static const int PRIVATESEND_KEYS_THRESHOLD_WARNING
std::vector< unsigned char > vchSig
Definition: masternode.h:157
const_iterator end() const
Definition: streams.h:120
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: server.cpp:586
const std::string & getTxHash() const
bool GetMasternodeRanks(rank_pair_vec_t &vecMasternodeRanksRet, int nBlockHeight=-1, int nMinProtocol=0)
CWallet * pwalletMain
CPubKey pubKeyMasternode
Definition: masternode.h:117
UniValue sentinelping(const UniValue &params, bool fHelp)
Definition: masternode.cpp:836
bool IsHex(const string &str)
int GetLastPaidBlock()
Definition: masternode.h:271
uint256 blockHash
Definition: masternode.h:36
masternode_info_t infoMixingMasternode
std::string ToString(bool fUseGetnameinfo=true) const
Definition: netaddress.cpp:568
bool DecodeHexVecMnb(std::vector< CMasternodeBroadcast > &vecMnb, std::string strHexMnb)
Definition: masternode.cpp:590
bool push_back(const UniValue &val)
Definition: univalue.cpp:176
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:144
Ran out of memory during operation.
Definition: protocol.h:46
std::vector< unsigned char > vchSig
Definition: masternode.h:38
const std::string & getIp() const
int GetQueueSize() const
Definition: privatesend.h:301
std::string ToString() const
Definition: base58.cpp:193
string EncodeBase64(const unsigned char *pch, size_t len)
int64_t nTimeLastPing
Definition: masternode.h:123
bool fMasterNode
Definition: util.cpp:108
uint32_t StringVersionToInt(const std::string &strVersion)
Converts version strings to 4-byte unsigned integer.
Definition: util.cpp:958
std::string SafeIntVersionToString(uint32_t nVersion)
Copy of the IntVersionToString, that returns "Invalid version" string instead of throwing std::bad_ca...
Definition: util.cpp:994
void UpdateLastPaid(const CBlockIndex *pindex)
std::string GetStatus() const
Definition: masternode.cpp:314
bool UpdateSentinelPing(int version)
COutPoint prevout
Definition: transaction.h:61
Definition: net.h:661
std::string GetRequiredPaymentsString(int nBlockHeight)
const_iterator begin() const
Definition: streams.h:118
#define LOCK(cs)
Definition: sync.h:168
UniValue masternode(const UniValue &params, bool fHelp)
Definition: masternode.cpp:96
static const int ACTIVE_MASTERNODE_INITIAL
uint256 uint256S(const char *str)
Definition: uint256.h:140
bool GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int &nCountRet, masternode_info_t &mnInfoRet)
Find an entry in the masternode list that is next to be paid.
static bool Create(const COutPoint &outpoint, const CService &service, const CKey &keyCollateralAddressNew, const CPubKey &pubKeyCollateralAddressNew, const CKey &keyMasternodeNew, const CPubKey &pubKeyMasternodeNew, std::string &strErrorRet, CMasternodeBroadcast &mnbRet)
Create Masternode broadcast, needs to be relayed manually after that.
Definition: masternode.cpp:397
vector< unsigned char > ParseHex(const char *psz)
std::vector< rank_pair_t > rank_pair_vec_t
Definition: masternodeman.h:24
CChain chainActive
Definition: validation.cpp:65
std::string ToString() const
Definition: uint256.cpp:65
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: server.cpp:581
static std::pair< std::string, UniValue > Pair(const char *cKey, const char *cVal)
Definition: univalue.h:166
int size()
Return the number of (unique) Masternodes.
static const int ACTIVE_MASTERNODE_STARTED
UniValue masternodebroadcast(const UniValue &params, bool fHelp)
Definition: masternode.cpp:607
void ManageState(CConnman &connman)
Manage state of active Masternode.
CPrivateSendClient privateSendClient
UniValue masternodelist(const UniValue &params, bool fHelp)
Definition: masternode.cpp:454
CPubKey pubKeyCollateralAddress
Definition: masternode.h:116
int64_t sigTime
Definition: masternode.h:37
int CountEnabled(int nProtocolVersion=-1)
std::map< COutPoint, CMasternode > GetFullMasternodeMap()
uint256 GetHash() const
Definition: masternode.h:338
int GetEntriesCount() const
Definition: privatesend.h:305
bool fSentinelIsCurrent
Definition: masternode.h:39
bool CheckSignature(int &nDos)
Definition: masternode.cpp:644
static const int PROTOCOL_VERSION
Definition: version.h:13
bool IsBlockchainSynced()
bool fImporting
Definition: validation.cpp:70
bool Lookup(const char *pszName, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Definition: netbase.cpp:200
static const int MIN_PRIVATESEND_PEER_PROTO_VERSION
minimum peer version accepted by mixing pool
Definition: privatesend.h:25
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:103
const UniValue NullUniValue
Definition: univalue.cpp:78
void NotifyMasternodeUpdates(CConnman &connman)
CBlockIndex * Tip() const
Definition: chain.h:366
const std::string & getAlias() const
bool GetMasternodeOutpointAndKeys(COutPoint &outpointRet, CPubKey &pubKeyRet, CKey &keyRet, std::string strTxHash="", std::string strOutputIndex="")
Get 1000DASH output and keys which can be used for the Masternode.
Definition: wallet.cpp:2987
Definition: pubkey.h:37
void UpdateMasternodeList(CMasternodeBroadcast mnb, CConnman &connman)
Update masternode list and maps using provided CMasternodeBroadcast.
Dash Core is not connected.
Definition: protocol.h:61
UniValue getpoolinfo(const UniValue &params, bool fHelp)
Definition: masternode.cpp:65
bool DoAutomaticDenominating(CConnman &connman, bool fDryRun=false)
Passively run mixing in the background according to the configuration in settings.
Definition: key.h:35
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:113
std::string ToStringShort() const
Definition: transaction.cpp:17
const std::string & getPrivKey() const
#define PAIRTYPE(t1, t2)
bool IsMasternodeListSynced()
UniValue JSONRPCError(int code, const string &message)
Definition: protocol.cpp:57
int64_t nKeysLeftSinceAutoBackup
Definition: wallet.h:755
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:126
size_t size() const
Definition: univalue.h:69
std::string get_str() const
Definition: univalue.cpp:310
int atoi(const std::string &str)
Database error.
Definition: protocol.h:48
result
Definition: rpcuser.py:37
void AvailableCoins(std::vector< COutput > &vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl=NULL, bool fIncludeZeroValue=false, AvailableCoinsType nCoinType=ALL_COINS, bool fUseInstantSend=false) const
Definition: wallet.cpp:2360