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 "masternode.h"
9 #include "masternode-payments.h"
10 #include "masternode-sync.h"
11 #include "masternodeman.h"
12 #include "messagesigner.h"
13 #include "util.h"
14 
15 #include <boost/lexical_cast.hpp>
16 
17 
20  fAllowMixingTx(true)
21 {}
22 
23 CMasternode::CMasternode(CService addr, COutPoint outpoint, CPubKey pubKeyCollateralAddress, CPubKey pubKeyMasternode, int nProtocolVersionIn) :
26  fAllowMixingTx(true)
27 {}
28 
30  masternode_info_t{other},
31  lastPing(other.lastPing),
32  vchSig(other.vchSig),
33  nCollateralMinConfBlockHash(other.nCollateralMinConfBlockHash),
34  nBlockLastPaid(other.nBlockLastPaid),
35  nPoSeBanScore(other.nPoSeBanScore),
36  nPoSeBanHeight(other.nPoSeBanHeight),
37  fAllowMixingTx(other.fAllowMixingTx),
38  fUnitTest(other.fUnitTest)
39 {}
40 
44  mnb.sigTime /*nTimeLastWatchdogVote*/},
45  lastPing(mnb.lastPing),
46  vchSig(mnb.vchSig),
47  fAllowMixingTx(true)
48 {}
49 
50 //
51 // When a new masternode broadcast is sent, update our information
52 //
54 {
55  if(mnb.sigTime <= sigTime && !mnb.fRecovery) return false;
56 
58  sigTime = mnb.sigTime;
59  vchSig = mnb.vchSig;
61  addr = mnb.addr;
62  nPoSeBanScore = 0;
63  nPoSeBanHeight = 0;
64  nTimeLastChecked = 0;
65  int nDos = 0;
66  if(mnb.lastPing == CMasternodePing() || (mnb.lastPing != CMasternodePing() && mnb.lastPing.CheckAndUpdate(this, true, nDos, connman))) {
67  lastPing = mnb.lastPing;
68  mnodeman.mapSeenMasternodePing.insert(std::make_pair(lastPing.GetHash(), lastPing));
69  }
70  // if it matches our Masternode privkey...
74  // ... and PROTOCOL_VERSION, then we've been remotely activated ...
76  } else {
77  // ... otherwise we need to reactivate our node, do not add it to the list and do not relay
78  // but also do not ban the node we get this message from
79  LogPrintf("CMasternode::UpdateFromNewBroadcast -- wrong PROTOCOL_VERSION, re-activate your MN: message nProtocolVersion=%d PROTOCOL_VERSION=%d\n", nProtocolVersion, PROTOCOL_VERSION);
80  return false;
81  }
82  }
83  return true;
84 }
85 
86 //
87 // Deterministically calculate a given "score" for a Masternode depending on how close it's hash is to
88 // the proof of work for that block. The further away they are the better, the furthest will win the election
89 // and get paid this block
90 //
92 {
93  if (fDIP0001WasLockedIn) {
94  // Deterministically calculate a "score" for a Masternode based on any given (block)hash
96  ss << vin.prevout << nCollateralMinConfBlockHash << blockHash;
97  return UintToArith256(ss.GetHash());
98  }
99 
100  // TODO: remove calculations below after migration to 12.2
101 
103 
105  ss << blockHash;
106  arith_uint256 hash2 = UintToArith256(ss.GetHash());
107 
109  ss2 << blockHash;
110  ss2 << aux;
111  arith_uint256 hash3 = UintToArith256(ss2.GetHash());
112 
113  return (hash3 > hash2 ? hash3 - hash2 : hash2 - hash3);
114 }
115 
117 {
118  int nHeight;
119  return CheckCollateral(outpoint, nHeight);
120 }
121 
123 {
125 
126  CCoins coins;
127  if(!GetUTXOCoins(outpoint, coins)) {
129  }
130 
131  if(coins.vout[outpoint.n].nValue != 1000 * COIN) {
133  }
134 
135  nHeightRet = coins.nHeight;
136  return COLLATERAL_OK;
137 }
138 
139 void CMasternode::Check(bool fForce)
140 {
141  LOCK(cs);
142 
143  if(ShutdownRequested()) return;
144 
145  if(!fForce && (GetTime() - nTimeLastChecked < MASTERNODE_CHECK_SECONDS)) return;
147 
148  LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state\n", vin.prevout.ToStringShort(), GetStateString());
149 
150  //once spent, stop doing the checks
151  if(IsOutpointSpent()) return;
152 
153  int nHeight = 0;
154  if(!fUnitTest) {
155  TRY_LOCK(cs_main, lockMain);
156  if(!lockMain) return;
157 
161  LogPrint("masternode", "CMasternode::Check -- Failed to find Masternode UTXO, masternode=%s\n", vin.prevout.ToStringShort());
162  return;
163  }
164 
165  nHeight = chainActive.Height();
166  }
167 
168  if(IsPoSeBanned()) {
169  if(nHeight < nPoSeBanHeight) return; // too early?
170  // Otherwise give it a chance to proceed further to do all the usual checks and to change its state.
171  // Masternode still will be on the edge and can be banned back easily if it keeps ignoring mnverify
172  // or connect attempts. Will require few mnverify messages to strengthen its position in mn list.
173  LogPrintf("CMasternode::Check -- Masternode %s is unbanned and back in list now\n", vin.prevout.ToStringShort());
177  // ban for the whole payment cycle
178  nPoSeBanHeight = nHeight + mnodeman.size();
179  LogPrintf("CMasternode::Check -- Masternode %s is banned till block %d now\n", vin.prevout.ToStringShort(), nPoSeBanHeight);
180  return;
181  }
182 
183  int nActiveStatePrev = nActiveState;
185 
186  // masternode doesn't meet payment protocol requirements ...
187  bool fRequireUpdate = nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto() ||
188  // or it's our own node and we just updated it to the new protocol but we are still waiting for activation ...
189  (fOurMasternode && nProtocolVersion < PROTOCOL_VERSION);
190 
191  if(fRequireUpdate) {
193  if(nActiveStatePrev != nActiveState) {
194  LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString());
195  }
196  return;
197  }
198 
199  // keep old masternodes on start, give them a chance to receive updates...
201 
202  if(fWaitForPing && !fOurMasternode) {
203  // ...but if it was already expired before the initial check - return right away
205  LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state, waiting for ping\n", vin.prevout.ToStringShort(), GetStateString());
206  return;
207  }
208  }
209 
210  // don't expire if we are still in "waiting for ping" mode unless it's our own masternode
211  if(!fWaitForPing || fOurMasternode) {
212 
215  if(nActiveStatePrev != nActiveState) {
216  LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString());
217  }
218  return;
219  }
220 
221  bool fWatchdogActive = masternodeSync.IsSynced() && mnodeman.IsWatchdogActive();
222  bool fWatchdogExpired = (fWatchdogActive && ((GetAdjustedTime() - nTimeLastWatchdogVote) > MASTERNODE_WATCHDOG_MAX_SECONDS));
223 
224  LogPrint("masternode", "CMasternode::Check -- outpoint=%s, nTimeLastWatchdogVote=%d, GetAdjustedTime()=%d, fWatchdogExpired=%d\n",
226 
227  if(fWatchdogExpired) {
229  if(nActiveStatePrev != nActiveState) {
230  LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString());
231  }
232  return;
233  }
234 
237  if(nActiveStatePrev != nActiveState) {
238  LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString());
239  }
240  return;
241  }
242  }
243 
246  if(nActiveStatePrev != nActiveState) {
247  LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString());
248  }
249  return;
250  }
251 
253  if(nActiveStatePrev != nActiveState) {
254  LogPrint("masternode", "CMasternode::Check -- Masternode %s is in %s state now\n", vin.prevout.ToStringShort(), GetStateString());
255  }
256 }
257 
259 {
260  CScript payee;
262 
263  CTransaction tx;
264  uint256 hash;
265  if(GetTransaction(vin.prevout.hash, tx, Params().GetConsensus(), hash, true)) {
266  BOOST_FOREACH(CTxOut out, tx.vout)
267  if(out.nValue == 1000*COIN && out.scriptPubKey == payee) return true;
268  }
269 
270  return false;
271 }
272 
274 {
275  return IsValidNetAddr(addr);
276 }
277 
279 {
280  // TODO: regtest is fine with any addresses for now,
281  // should probably be a bit smarter if one day we start to implement tests for this
283  (addrIn.IsIPv4() && IsReachable(addrIn) && addrIn.IsRoutable());
284 }
285 
287 {
288  masternode_info_t info{*this};
290  info.fInfoValid = true;
291  return info;
292 }
293 
294 std::string CMasternode::StateToString(int nStateIn)
295 {
296  switch(nStateIn) {
297  case MASTERNODE_PRE_ENABLED: return "PRE_ENABLED";
298  case MASTERNODE_ENABLED: return "ENABLED";
299  case MASTERNODE_EXPIRED: return "EXPIRED";
300  case MASTERNODE_OUTPOINT_SPENT: return "OUTPOINT_SPENT";
301  case MASTERNODE_UPDATE_REQUIRED: return "UPDATE_REQUIRED";
302  case MASTERNODE_WATCHDOG_EXPIRED: return "WATCHDOG_EXPIRED";
303  case MASTERNODE_NEW_START_REQUIRED: return "NEW_START_REQUIRED";
304  case MASTERNODE_POSE_BAN: return "POSE_BAN";
305  default: return "UNKNOWN";
306  }
307 }
308 
309 std::string CMasternode::GetStateString() const
310 {
311  return StateToString(nActiveState);
312 }
313 
314 std::string CMasternode::GetStatus() const
315 {
316  // TODO: return smth a bit more human readable here
317  return GetStateString();
318 }
319 
320 void CMasternode::UpdateLastPaid(const CBlockIndex *pindex, int nMaxBlocksToScanBack)
321 {
322  if(!pindex) return;
323 
324  const CBlockIndex *BlockReading = pindex;
325 
327  // LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s\n", vin.prevout.ToStringShort());
328 
330 
331  for (int i = 0; BlockReading && BlockReading->nHeight > nBlockLastPaid && i < nMaxBlocksToScanBack; i++) {
332  if(mnpayments.mapMasternodeBlocks.count(BlockReading->nHeight) &&
333  mnpayments.mapMasternodeBlocks[BlockReading->nHeight].HasPayeeWithVotes(mnpayee, 2))
334  {
335  CBlock block;
336  if(!ReadBlockFromDisk(block, BlockReading, Params().GetConsensus())) // shouldn't really happen
337  continue;
338 
339  CAmount nMasternodePayment = GetMasternodePayment(BlockReading->nHeight, block.vtx[0].GetValueOut());
340 
341  BOOST_FOREACH(CTxOut txout, block.vtx[0].vout)
342  if(mnpayee == txout.scriptPubKey && nMasternodePayment == txout.nValue) {
343  nBlockLastPaid = BlockReading->nHeight;
344  nTimeLastPaid = BlockReading->nTime;
345  LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s -- found new %d\n", vin.prevout.ToStringShort(), nBlockLastPaid);
346  return;
347  }
348  }
349 
350  if (BlockReading->pprev == NULL) { assert(BlockReading); break; }
351  BlockReading = BlockReading->pprev;
352  }
353 
354  // Last payment for this masternode wasn't found in latest mnpayments blocks
355  // or it was found in mnpayments blocks but wasn't found in the blockchain.
356  // LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s -- keeping old %d\n", vin.prevout.ToStringShort(), nBlockLastPaid);
357 }
358 
359 bool CMasternodeBroadcast::Create(std::string strService, std::string strKeyMasternode, std::string strTxHash, std::string strOutputIndex, std::string& strErrorRet, CMasternodeBroadcast &mnbRet, bool fOffline)
360 {
361  COutPoint outpoint;
362  CPubKey pubKeyCollateralAddressNew;
363  CKey keyCollateralAddressNew;
364  CPubKey pubKeyMasternodeNew;
365  CKey keyMasternodeNew;
366 
367  auto Log = [&strErrorRet](std::string sErr)->bool
368  {
369  strErrorRet = sErr;
370  LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
371  return false;
372  };
373 
374  //need correct blocks to send ping
375  if (!fOffline && !masternodeSync.IsBlockchainSynced())
376  return Log("Sync in progress. Must wait until sync is complete to start Masternode");
377 
378  if (!CMessageSigner::GetKeysFromSecret(strKeyMasternode, keyMasternodeNew, pubKeyMasternodeNew))
379  return Log(strprintf("Invalid masternode key %s", strKeyMasternode));
380 
381  if (!pwalletMain->GetMasternodeOutpointAndKeys(outpoint, pubKeyCollateralAddressNew, keyCollateralAddressNew, strTxHash, strOutputIndex))
382  return Log(strprintf("Could not allocate outpoint %s:%s for masternode %s", strTxHash, strOutputIndex, strService));
383 
384  CService service;
385  if (!Lookup(strService.c_str(), service, 0, false))
386  return Log(strprintf("Invalid address %s for masternode.", strService));
387  int mainnetDefaultPort = Params(CBaseChainParams::MAIN).GetDefaultPort();
388  if (Params().NetworkIDString() == CBaseChainParams::MAIN) {
389  if (service.GetPort() != mainnetDefaultPort)
390  return Log(strprintf("Invalid port %u for masternode %s, only %d is supported on mainnet.", service.GetPort(), strService, mainnetDefaultPort));
391  } else if (service.GetPort() == mainnetDefaultPort)
392  return Log(strprintf("Invalid port %u for masternode %s, %d is the only supported on mainnet.", service.GetPort(), strService, mainnetDefaultPort));
393 
394  return Create(outpoint, service, keyCollateralAddressNew, pubKeyCollateralAddressNew, keyMasternodeNew, pubKeyMasternodeNew, strErrorRet, mnbRet);
395 }
396 
397 bool CMasternodeBroadcast::Create(const COutPoint& outpoint, const CService& service, const CKey& keyCollateralAddressNew, const CPubKey& pubKeyCollateralAddressNew, const CKey& keyMasternodeNew, const CPubKey& pubKeyMasternodeNew, std::string &strErrorRet, CMasternodeBroadcast &mnbRet)
398 {
399  // wait for reindex and/or import to finish
400  if (fImporting || fReindex) return false;
401 
402  LogPrint("masternode", "CMasternodeBroadcast::Create -- pubKeyCollateralAddressNew = %s, pubKeyMasternodeNew.GetID() = %s\n",
403  CBitcoinAddress(pubKeyCollateralAddressNew.GetID()).ToString(),
404  pubKeyMasternodeNew.GetID().ToString());
405 
406  auto Log = [&strErrorRet,&mnbRet](std::string sErr)->bool
407  {
408  strErrorRet = sErr;
409  LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
410  mnbRet = CMasternodeBroadcast();
411  return false;
412  };
413 
414  CMasternodePing mnp(outpoint);
415  if (!mnp.Sign(keyMasternodeNew, pubKeyMasternodeNew))
416  return Log(strprintf("Failed to sign ping, masternode=%s", outpoint.ToStringShort()));
417 
418  mnbRet = CMasternodeBroadcast(service, outpoint, pubKeyCollateralAddressNew, pubKeyMasternodeNew, PROTOCOL_VERSION);
419 
420  if (!mnbRet.IsValidNetAddr())
421  return Log(strprintf("Invalid IP address, masternode=%s", outpoint.ToStringShort()));
422 
423  mnbRet.lastPing = mnp;
424  if (!mnbRet.Sign(keyCollateralAddressNew))
425  return Log(strprintf("Failed to sign broadcast, masternode=%s", outpoint.ToStringShort()));
426 
427  return true;
428 }
429 
431 {
432  nDos = 0;
433 
434  // make sure addr is valid
435  if(!IsValidNetAddr()) {
436  LogPrintf("CMasternodeBroadcast::SimpleCheck -- Invalid addr, rejected: masternode=%s addr=%s\n",
438  return false;
439  }
440 
441  // make sure signature isn't in the future (past is OK)
442  if (sigTime > GetAdjustedTime() + 60 * 60) {
443  LogPrintf("CMasternodeBroadcast::SimpleCheck -- Signature rejected, too far into the future: masternode=%s\n", vin.prevout.ToStringShort());
444  nDos = 1;
445  return false;
446  }
447 
448  // empty ping or incorrect sigTime/unknown blockhash
449  if(lastPing == CMasternodePing() || !lastPing.SimpleCheck(nDos)) {
450  // one of us is probably forked or smth, just mark it as expired and check the rest of the rules
452  }
453 
455  LogPrintf("CMasternodeBroadcast::SimpleCheck -- ignoring outdated Masternode: masternode=%s nProtocolVersion=%d\n", vin.prevout.ToStringShort(), nProtocolVersion);
456  return false;
457  }
458 
459  CScript pubkeyScript;
461 
462  if(pubkeyScript.size() != 25) {
463  LogPrintf("CMasternodeBroadcast::SimpleCheck -- pubKeyCollateralAddress has the wrong size\n");
464  nDos = 100;
465  return false;
466  }
467 
468  CScript pubkeyScript2;
470 
471  if(pubkeyScript2.size() != 25) {
472  LogPrintf("CMasternodeBroadcast::SimpleCheck -- pubKeyMasternode has the wrong size\n");
473  nDos = 100;
474  return false;
475  }
476 
477  if(!vin.scriptSig.empty()) {
478  LogPrintf("CMasternodeBroadcast::SimpleCheck -- Ignore Not Empty ScriptSig %s\n",vin.ToString());
479  nDos = 100;
480  return false;
481  }
482 
483  int mainnetDefaultPort = Params(CBaseChainParams::MAIN).GetDefaultPort();
484  if(Params().NetworkIDString() == CBaseChainParams::MAIN) {
485  if(addr.GetPort() != mainnetDefaultPort) return false;
486  } else if(addr.GetPort() == mainnetDefaultPort) return false;
487 
488  return true;
489 }
490 
491 bool CMasternodeBroadcast::Update(CMasternode* pmn, int& nDos, CConnman& connman)
492 {
493  nDos = 0;
494 
495  if(pmn->sigTime == sigTime && !fRecovery) {
496  // mapSeenMasternodeBroadcast in CMasternodeMan::CheckMnbAndUpdateMasternodeList should filter legit duplicates
497  // but this still can happen if we just started, which is ok, just do nothing here.
498  return false;
499  }
500 
501  // this broadcast is older than the one that we already have - it's bad and should never happen
502  // unless someone is doing something fishy
503  if(pmn->sigTime > sigTime) {
504  LogPrintf("CMasternodeBroadcast::Update -- Bad sigTime %d (existing broadcast is at %d) for Masternode %s %s\n",
506  return false;
507  }
508 
509  pmn->Check();
510 
511  // masternode is banned by PoSe
512  if(pmn->IsPoSeBanned()) {
513  LogPrintf("CMasternodeBroadcast::Update -- Banned by PoSe, masternode=%s\n", vin.prevout.ToStringShort());
514  return false;
515  }
516 
517  // IsVnAssociatedWithPubkey is validated once in CheckOutpoint, after that they just need to match
519  LogPrintf("CMasternodeBroadcast::Update -- Got mismatched pubKeyCollateralAddress and vin\n");
520  nDos = 33;
521  return false;
522  }
523 
524  if (!CheckSignature(nDos)) {
525  LogPrintf("CMasternodeBroadcast::Update -- CheckSignature() failed, masternode=%s\n", vin.prevout.ToStringShort());
526  return false;
527  }
528 
529  // if ther was no masternode broadcast recently or if it matches our Masternode privkey...
531  // take the newest entry
532  LogPrintf("CMasternodeBroadcast::Update -- Got UPDATED Masternode entry: addr=%s\n", addr.ToString());
533  if(pmn->UpdateFromNewBroadcast(*this, connman)) {
534  pmn->Check();
535  Relay(connman);
536  }
537  masternodeSync.BumpAssetLastTime("CMasternodeBroadcast::Update");
538  }
539 
540  return true;
541 }
542 
544 {
545  // we are a masternode with the same vin (i.e. already activated) and this mnb is ours (matches our Masternode privkey)
546  // so nothing to do here for us
548  return false;
549  }
550 
551  if (!CheckSignature(nDos)) {
552  LogPrintf("CMasternodeBroadcast::CheckOutpoint -- CheckSignature() failed, masternode=%s\n", vin.prevout.ToStringShort());
553  return false;
554  }
555 
556  {
557  TRY_LOCK(cs_main, lockMain);
558  if(!lockMain) {
559  // not mnb fault, let it to be checked again later
560  LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Failed to aquire lock, addr=%s", addr.ToString());
562  return false;
563  }
564 
565  int nHeight;
568  LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Failed to find Masternode UTXO, masternode=%s\n", vin.prevout.ToStringShort());
569  return false;
570  }
571 
573  LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Masternode UTXO should have 1000 DASH, masternode=%s\n", vin.prevout.ToStringShort());
574  return false;
575  }
576 
578  LogPrintf("CMasternodeBroadcast::CheckOutpoint -- Masternode UTXO must have at least %d confirmations, masternode=%s\n",
579  Params().GetConsensus().nMasternodeMinimumConfirmations, vin.prevout.ToStringShort());
580  // maybe we miss few blocks, let this mnb to be checked again later
582  return false;
583  }
584  // remember the hash of the block where masternode collateral had minimum required confirmations
586  }
587 
588  LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Masternode UTXO verified\n");
589 
590  // make sure the input that was signed in masternode broadcast message is related to the transaction
591  // that spawned the Masternode - this is expensive, so it's only done once per Masternode
593  LogPrintf("CMasternodeMan::CheckOutpoint -- Got mismatched pubKeyCollateralAddress and vin\n");
594  nDos = 33;
595  return false;
596  }
597 
598  // verify that sig time is legit in past
599  // should be at least not earlier than block when 1000 DASH tx got nMasternodeMinimumConfirmations
600  uint256 hashBlock = uint256();
601  CTransaction tx2;
602  GetTransaction(vin.prevout.hash, tx2, Params().GetConsensus(), hashBlock, true);
603  {
604  LOCK(cs_main);
605  BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
606  if (mi != mapBlockIndex.end() && (*mi).second) {
607  CBlockIndex* pMNIndex = (*mi).second; // block for 1000 DASH tx -> 1 confirmation
608  CBlockIndex* pConfIndex = chainActive[pMNIndex->nHeight + Params().GetConsensus().nMasternodeMinimumConfirmations - 1]; // block where tx got nMasternodeMinimumConfirmations
609  if(pConfIndex->GetBlockTime() > sigTime) {
610  LogPrintf("CMasternodeBroadcast::CheckOutpoint -- Bad sigTime %d (%d conf block is at %d) for Masternode %s %s\n",
611  sigTime, Params().GetConsensus().nMasternodeMinimumConfirmations, pConfIndex->GetBlockTime(), vin.prevout.ToStringShort(), addr.ToString());
612  return false;
613  }
614  }
615  }
616 
617  return true;
618 }
619 
620 bool CMasternodeBroadcast::Sign(const CKey& keyCollateralAddress)
621 {
622  std::string strError;
623  std::string strMessage;
624 
626 
627  strMessage = addr.ToString(false) + boost::lexical_cast<std::string>(sigTime) +
629  boost::lexical_cast<std::string>(nProtocolVersion);
630 
631  if(!CMessageSigner::SignMessage(strMessage, vchSig, keyCollateralAddress)) {
632  LogPrintf("CMasternodeBroadcast::Sign -- SignMessage() failed\n");
633  return false;
634  }
635 
636  if(!CMessageSigner::VerifyMessage(pubKeyCollateralAddress, vchSig, strMessage, strError)) {
637  LogPrintf("CMasternodeBroadcast::Sign -- VerifyMessage() failed, error: %s\n", strError);
638  return false;
639  }
640 
641  return true;
642 }
643 
645 {
646  std::string strMessage;
647  std::string strError = "";
648  nDos = 0;
649 
650  strMessage = addr.ToString(false) + boost::lexical_cast<std::string>(sigTime) +
652  boost::lexical_cast<std::string>(nProtocolVersion);
653 
654  LogPrint("masternode", "CMasternodeBroadcast::CheckSignature -- strMessage: %s pubKeyCollateralAddress address: %s sig: %s\n", strMessage, CBitcoinAddress(pubKeyCollateralAddress.GetID()).ToString(), EncodeBase64(&vchSig[0], vchSig.size()));
655 
656  if(!CMessageSigner::VerifyMessage(pubKeyCollateralAddress, vchSig, strMessage, strError)){
657  LogPrintf("CMasternodeBroadcast::CheckSignature -- Got bad Masternode announce signature, error: %s\n", strError);
658  nDos = 100;
659  return false;
660  }
661 
662  return true;
663 }
664 
666 {
668  connman.RelayInv(inv);
669 }
670 
672 {
673  LOCK(cs_main);
674  if (!chainActive.Tip() || chainActive.Height() < 12) return;
675 
676  vin = CTxIn(outpoint);
677  blockHash = chainActive[chainActive.Height() - 12]->GetBlockHash();
679 }
680 
681 bool CMasternodePing::Sign(const CKey& keyMasternode, const CPubKey& pubKeyMasternode)
682 {
683  std::string strError;
684  std::string strMasterNodeSignMessage;
685 
686  // TODO: add sentinel data
688  std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime);
689 
690  if(!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) {
691  LogPrintf("CMasternodePing::Sign -- SignMessage() failed\n");
692  return false;
693  }
694 
695  if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
696  LogPrintf("CMasternodePing::Sign -- VerifyMessage() failed, error: %s\n", strError);
697  return false;
698  }
699 
700  return true;
701 }
702 
703 bool CMasternodePing::CheckSignature(CPubKey& pubKeyMasternode, int &nDos)
704 {
705  // TODO: add sentinel data
706  std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime);
707  std::string strError = "";
708  nDos = 0;
709 
710  if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
711  LogPrintf("CMasternodePing::CheckSignature -- Got bad Masternode ping signature, masternode=%s, error: %s\n", vin.prevout.ToStringShort(), strError);
712  nDos = 33;
713  return false;
714  }
715  return true;
716 }
717 
719 {
720  // don't ban by default
721  nDos = 0;
722 
723  if (sigTime > GetAdjustedTime() + 60 * 60) {
724  LogPrintf("CMasternodePing::SimpleCheck -- Signature rejected, too far into the future, masternode=%s\n", vin.prevout.ToStringShort());
725  nDos = 1;
726  return false;
727  }
728 
729  {
731  BlockMap::iterator mi = mapBlockIndex.find(blockHash);
732  if (mi == mapBlockIndex.end()) {
733  LogPrint("masternode", "CMasternodePing::SimpleCheck -- Masternode ping is invalid, unknown block hash: masternode=%s blockHash=%s\n", vin.prevout.ToStringShort(), blockHash.ToString());
734  // maybe we stuck or forked so we shouldn't ban this node, just fail to accept this ping
735  // TODO: or should we also request this block?
736  return false;
737  }
738  }
739  LogPrint("masternode", "CMasternodePing::SimpleCheck -- Masternode ping verified: masternode=%s blockHash=%s sigTime=%d\n", vin.prevout.ToStringShort(), blockHash.ToString(), sigTime);
740  return true;
741 }
742 
743 bool CMasternodePing::CheckAndUpdate(CMasternode* pmn, bool fFromNewBroadcast, int& nDos, CConnman& connman)
744 {
745  // don't ban by default
746  nDos = 0;
747 
748  if (!SimpleCheck(nDos)) {
749  return false;
750  }
751 
752  if (pmn == NULL) {
753  LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Couldn't find Masternode entry, masternode=%s\n", vin.prevout.ToStringShort());
754  return false;
755  }
756 
757  if(!fFromNewBroadcast) {
758  if (pmn->IsUpdateRequired()) {
759  LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- masternode protocol is outdated, masternode=%s\n", vin.prevout.ToStringShort());
760  return false;
761  }
762 
763  if (pmn->IsNewStartRequired()) {
764  LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- masternode is completely expired, new start is required, masternode=%s\n", vin.prevout.ToStringShort());
765  return false;
766  }
767  }
768 
769  {
770  LOCK(cs_main);
771  BlockMap::iterator mi = mapBlockIndex.find(blockHash);
772  if ((*mi).second && (*mi).second->nHeight < chainActive.Height() - 24) {
773  LogPrintf("CMasternodePing::CheckAndUpdate -- Masternode ping is invalid, block hash is too old: masternode=%s blockHash=%s\n", vin.prevout.ToStringShort(), blockHash.ToString());
774  // nDos = 1;
775  return false;
776  }
777  }
778 
779  LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- New ping: masternode=%s blockHash=%s sigTime=%d\n", vin.prevout.ToStringShort(), blockHash.ToString(), sigTime);
780 
781  // LogPrintf("mnping - Found corresponding mn for vin: %s\n", vin.prevout.ToStringShort());
782  // update only if there is no known ping for this masternode or
783  // last ping was more then MASTERNODE_MIN_MNP_SECONDS-60 ago comparing to this one
785  LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Masternode ping arrived too early, masternode=%s\n", vin.prevout.ToStringShort());
786  //nDos = 1; //disable, this is happening frequently and causing banned peers
787  return false;
788  }
789 
790  if (!CheckSignature(pmn->pubKeyMasternode, nDos)) return false;
791 
792  // so, ping seems to be ok
793 
794  // if we are still syncing and there was no known ping for this mn for quite a while
795  // (NOTE: assuming that MASTERNODE_EXPIRATION_SECONDS/2 should be enough to finish mn list sync)
797  // let's bump sync timeout
798  LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- bumping sync timeout, masternode=%s\n", vin.prevout.ToStringShort());
799  masternodeSync.BumpAssetLastTime("CMasternodePing::CheckAndUpdate");
800  }
801 
802  // let's store this ping as the last one
803  LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Masternode ping accepted, masternode=%s\n", vin.prevout.ToStringShort());
804  pmn->lastPing = *this;
805 
806  // and update mnodeman.mapSeenMasternodeBroadcast.lastPing which is probably outdated
807  CMasternodeBroadcast mnb(*pmn);
808  uint256 hash = mnb.GetHash();
809  if (mnodeman.mapSeenMasternodeBroadcast.count(hash)) {
810  mnodeman.mapSeenMasternodeBroadcast[hash].second.lastPing = *this;
811  }
812 
813  // force update, ignoring cache
814  pmn->Check(true);
815  // relay ping for nodes in ENABLED/EXPIRED/WATCHDOG_EXPIRED state only, skip everyone else
816  if (!pmn->IsEnabled() && !pmn->IsExpired() && !pmn->IsWatchdogExpired()) return false;
817 
818  LogPrint("masternode", "CMasternodePing::CheckAndUpdate -- Masternode ping acceepted and relayed, masternode=%s\n", vin.prevout.ToStringShort());
819  Relay(connman);
820 
821  return true;
822 }
823 
825 {
827  connman.RelayInv(inv);
828 }
829 
830 void CMasternode::AddGovernanceVote(uint256 nGovernanceObjectHash)
831 {
832  if(mapGovernanceObjectsVotedOn.count(nGovernanceObjectHash)) {
833  mapGovernanceObjectsVotedOn[nGovernanceObjectHash]++;
834  } else {
835  mapGovernanceObjectsVotedOn.insert(std::make_pair(nGovernanceObjectHash, 1));
836  }
837 }
838 
839 void CMasternode::RemoveGovernanceObject(uint256 nGovernanceObjectHash)
840 {
841  std::map<uint256, int>::iterator it = mapGovernanceObjectsVotedOn.find(nGovernanceObjectHash);
842  if(it == mapGovernanceObjectsVotedOn.end()) {
843  return;
844  }
845  mapGovernanceObjectsVotedOn.erase(it);
846 }
847 
848 void CMasternode::UpdateWatchdogVoteTime(uint64_t nVoteTime)
849 {
850  LOCK(cs);
851  nTimeLastWatchdogVote = (nVoteTime == 0) ? GetAdjustedTime() : nVoteTime;
852 }
853 
861 {
862  std::vector<uint256> vecDirty;
863  {
864  std::map<uint256, int>::iterator it = mapGovernanceObjectsVotedOn.begin();
865  while(it != mapGovernanceObjectsVotedOn.end()) {
866  vecDirty.push_back(it->first);
867  ++it;
868  }
869  }
870  for(size_t i = 0; i < vecDirty.size(); ++i) {
872  }
873 }
bool CheckOutpoint(int &nDos)
Definition: masternode.cpp:543
uint32_t n
Definition: transaction.h:19
CMasternodeMan mnodeman
CMasternodeSync masternodeSync
bool Update(CMasternode *pmn, int &nDos, CConnman &connman)
Definition: masternode.cpp:491
bool IsPoSeBanned()
Definition: masternode.h:224
CAmount GetMasternodePayment(int nHeight, CAmount blockValue)
Definition: coins.h:73
std::string NetworkIDString() const
Definition: chainparams.h:75
void UpdateWatchdogVoteTime(uint64_t nVoteTime=0)
Definition: masternode.cpp:848
uint256 GetHash() const
Definition: masternode.h:65
CActiveMasternode activeMasternode
#define TRY_LOCK(cs, name)
Definition: sync.h:170
void Relay(CConnman &connman)
Definition: masternode.cpp:665
bool UpdateFromNewBroadcast(CMasternodeBroadcast &mnb, CConnman &connman)
Definition: masternode.cpp:53
bool ShutdownRequested()
Definition: init.cpp:168
#define strprintf
Definition: tinyformat.h:1011
CMasternodePing lastPing
Definition: masternode.h:156
bool GetUTXOCoins(const COutPoint &outpoint, CCoins &coins)
Definition: validation.cpp:446
bool SimpleCheck(int &nDos)
Definition: masternode.cpp:718
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:55
static const CAmount COIN
Definition: amount.h:16
int64_t nTimeLastWatchdogVote
Definition: masternode.h:118
CCriticalSection cs_main
Definition: validation.cpp:62
bool fReindex
Definition: validation.cpp:71
CAmount nValue
Definition: transaction.h:136
void AddDirtyGovernanceObjectHash(const uint256 &nHash)
std::vector< unsigned char > vchSig
Definition: masternode.h:157
Definition: net.h:108
bool CheckAndUpdate(CMasternode *pmn, bool fFromNewBroadcast, int &nDos, CConnman &connman)
Definition: masternode.cpp:743
void FlagGovernanceItemsAsDirty()
Definition: masternode.cpp:860
std::map< uint256, CMasternodePing > mapSeenMasternodePing
Definition: masternodeman.h:87
CWallet * pwalletMain
void RelayInv(CInv &inv, const int minProtoVersion=MIN_PEER_PROTO_VERSION)
Definition: net.cpp:2528
CPubKey pubKeyMasternode
Definition: masternode.h:117
int nBlockLastPaid
Definition: masternode.h:160
uint256 blockHash
Definition: masternode.h:36
bool IsEnabled()
Definition: masternode.h:222
std::map< uint256, std::pair< int64_t, CMasternodeBroadcast > > mapSeenMasternodeBroadcast
Definition: masternodeman.h:85
std::string ToString(bool fUseGetnameinfo=true) const
Definition: netaddress.cpp:568
bool Sign(const CKey &keyCollateralAddress)
Definition: masternode.cpp:620
static const int MASTERNODE_NEW_START_REQUIRED_SECONDS
Definition: masternode.h:21
CCriticalSection cs_mapMasternodeBlocks
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:144
int nPoSeBanHeight
Definition: masternode.h:162
std::vector< unsigned char > vchSig
Definition: masternode.h:38
arith_uint256 UintToArith256(const uint256 &a)
int GetDefaultPort() const
Definition: chainparams.h:58
std::vector< CTransaction > vtx
Definition: block.h:77
string EncodeBase64(const unsigned char *pch, size_t len)
unsigned short GetPort() const
Definition: netaddress.cpp:495
static const int MASTERNODE_WATCHDOG_MAX_SECONDS
Definition: masternode.h:20
int64_t nTimeLastPing
Definition: masternode.h:123
bool fMasterNode
Definition: util.cpp:108
bool IsBroadcastedWithin(int nSeconds)
Definition: masternode.h:210
CScript scriptSig
Definition: transaction.h:62
static CollateralStatus CheckCollateral(const COutPoint &outpoint)
Definition: masternode.cpp:116
int64_t CAmount
Definition: amount.h:14
std::map< uint256, int > mapGovernanceObjectsVotedOn
Definition: masternode.h:167
std::string GetStateString() const
Definition: masternode.cpp:309
uint256 GetHash()
Definition: hash.h:254
#define AssertLockHeld(cs)
Definition: sync.h:96
bool IsInputAssociatedWithPubkey()
Is the input associated with collateral public key? (and there is 1000 DASH - checking if valid maste...
Definition: masternode.cpp:258
static bool GetKeysFromSecret(const std::string strSecret, CKey &keyRet, CPubKey &pubkeyRet)
Set the private/public key values, returns true if successful.
std::atomic< bool > fDIP0001WasLockedIn
Definition: validation.cpp:88
std::vector< CTxOut > vout
unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are d...
Definition: coins.h:80
static const int MASTERNODE_MIN_MNB_SECONDS
Definition: masternode.h:17
std::string GetStatus() const
Definition: masternode.cpp:314
int64_t nTimeLastChecked
Definition: masternode.h:121
int nMasternodeMinimumConfirmations
Definition: params.h:58
#define LogPrintf(...)
Definition: util.h:98
bool Sign(const CKey &keyMasternode, const CPubKey &pubKeyMasternode)
Definition: masternode.cpp:681
static const int MASTERNODE_CHECK_SECONDS
Definition: masternode.h:16
arith_uint256 CalculateScore(const uint256 &blockHash)
Definition: masternode.cpp:91
bool IsIPv4() const
Definition: netaddress.cpp:78
COutPoint prevout
Definition: transaction.h:61
CMasternodePayments mnpayments
CMasternodePing()=default
static int LogPrint(const char *category, const char *format)
Definition: util.h:126
#define LOCK(cs)
Definition: sync.h:168
std::string ToString() const
Definition: transaction.cpp:36
int Height() const
Definition: chain.h:397
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
void RemoveGovernanceObject(uint256 nGovernanceObjectHash)
Definition: masternode.cpp:839
unsigned int nTime
Definition: chain.h:142
void UpdateLastPaid(const CBlockIndex *pindex, int nMaxBlocksToScanBack)
Definition: masternode.cpp:320
void Check(bool fForce=false)
Definition: masternode.cpp:139
static bool VerifyMessage(const CPubKey pubkey, const std::vector< unsigned char > &vchSig, const std::string strMessage, std::string &strErrorRet)
Verify the message signature, returns true if succcessful.
CChain chainActive
Definition: validation.cpp:65
std::string ToString() const
Definition: uint256.cpp:65
bool IsExpired()
Definition: masternode.h:227
CScript GetScriptForDestination(const CTxDestination &dest)
Definition: standard.cpp:262
bool CheckSignature(CPubKey &pubKeyMasternode, int &nDos)
Definition: masternode.cpp:703
int size()
Return the number of (unique) Masternodes.
CScript scriptPubKey
Definition: transaction.h:137
bool IsWatchdogExpired()
Definition: masternode.h:230
static const int MASTERNODE_MIN_MNP_SECONDS
Definition: masternode.h:18
bool IsNewStartRequired()
Definition: masternode.h:231
void ManageState(CConnman &connman)
Manage state of active Masternode.
void AddGovernanceVote(uint256 nGovernanceObjectHash)
Definition: masternode.cpp:830
CPubKey pubKeyCollateralAddress
Definition: masternode.h:116
int64_t sigTime
Definition: masternode.h:37
static const int MASTERNODE_EXPIRATION_SECONDS
Definition: masternode.h:19
bool IsReachable(enum Network net)
Definition: net.cpp:285
uint256 ArithToUint256(const arith_uint256 &a)
static const int MASTERNODE_POSE_BAN_MAX_SCORE
Definition: masternode.h:23
uint256 GetHash() const
Definition: masternode.h:338
const CChainParams & Params()
bool CheckSignature(int &nDos)
Definition: masternode.cpp:644
CCriticalSection cs
Definition: masternode.h:135
static const int PROTOCOL_VERSION
Definition: version.h:13
static std::string StateToString(int nStateIn)
Definition: masternode.cpp:294
bool IsValidNetAddr()
Definition: masternode.cpp:273
bool empty() const
Definition: prevector.h:266
int64_t GetAdjustedTime()
Definition: timedata.cpp:33
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
bool IsRoutable() const
Definition: netaddress.cpp:222
Definition: protocol.h:314
bool SimpleCheck(int &nDos)
Definition: masternode.cpp:430
bool fUnitTest
Definition: masternode.h:164
CBlockIndex * Tip() const
Definition: chain.h:366
masternode_info_t GetInfo()
Definition: masternode.cpp:286
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
bool IsOutpointSpent()
Definition: masternode.h:228
static const std::string MAIN
Definition: pubkey.h:37
size_type size() const
Definition: prevector.h:262
static bool SignMessage(const std::string strMessage, std::vector< unsigned char > &vchSigRet, const CKey key)
Sign the message, returns true if successful.
#define ss2(x)
Definition: bmw.c:142
int64_t GetBlockTime() const
Definition: chain.h:223
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:107
int nPoSeBanScore
Definition: masternode.h:161
int64_t GetTime()
For unit testing.
Definition: utiltime.cpp:20
bool GetTransaction(const uint256 &hash, CTransaction &txOut, const Consensus::Params &consensusParams, uint256 &hashBlock, bool fAllowSlow)
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
void BumpAssetLastTime(std::string strFuncName)
void Relay(CConnman &connman)
Definition: masternode.cpp:824
Definition: block.h:73
bool IsUpdateRequired()
Definition: masternode.h:229
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
uint256 hash
Definition: transaction.h:18
void DecreasePoSeBanScore()
Definition: masternode.h:261
bool IsMasternodeListSynced()
uint256 nCollateralMinConfBlockHash
Definition: masternode.h:159
BlockMap mapBlockIndex
Definition: validation.cpp:64
std::map< int, CMasternodeBlockPayees > mapMasternodeBlocks
int64_t nTimeLastPaid
Definition: masternode.h:122
int nHeight
at which height this transaction was included in the active block chain
Definition: coins.h:83
bool IsPingedWithin(int nSeconds, int64_t nTimeToCheckAt=-1)
Definition: masternode.h:212
static const std::string REGTEST