From dc7292afa94f493d54ee41b0cb237ab5bfea7582 Mon Sep 17 00:00:00 2001 From: Alexander Block Date: Thu, 15 Feb 2018 19:14:28 +0100 Subject: [PATCH] Implement new MN payments logic and add compatibility code --- src/masternode-payments.cpp | 77 +++++++++++++++++++++++++++++++------ src/masternode.cpp | 15 ++++++++ src/masternodeman.cpp | 12 ++++++ src/masternodeman.h | 1 + src/net_processing.cpp | 29 ++++++++------ src/rpc/masternode.cpp | 24 +++++++++--- 6 files changed, 129 insertions(+), 29 deletions(-) diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index 03b2b7d51..2885ffb1d 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -14,6 +14,8 @@ #include "spork.h" #include "util.h" +#include "evo/deterministicmns.h" + #include /** Object for who's going to get paid on which blocks */ @@ -150,7 +152,7 @@ bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockRewar bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) { - if(!masternodeSync.IsSynced() || fLiteMode) { + if((!masternodeSync.IsSynced() && !deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) || fLiteMode) { //there is no budget data to use to check anything, let's just accept the longest chain if(fDebug) LogPrintf("%s -- WARNING: Not enough data, skipping block payee checks\n", __func__); return true; @@ -267,6 +269,9 @@ void CMasternodePayments::Clear() bool CMasternodePayments::UpdateLastVote(const CMasternodePaymentVote& vote) { + if (deterministicMNManager->IsDeterministicMNsSporkActive()) + return false; + LOCK(cs_mapMasternodePaymentVotes); const auto it = mapMasternodesLastVote.find(vote.masternodeOutpoint); @@ -294,6 +299,8 @@ bool CMasternodePayments::GetMasternodeTxOuts(int nBlockHeight, CAmount blockRew voutMasternodePaymentsRet.clear(); if(!GetBlockTxOuts(nBlockHeight, blockReward, voutMasternodePaymentsRet)) { + assert(!deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)); + // no masternode detected... int nCount = 0; masternode_info_t mnInfo; @@ -327,6 +334,9 @@ int CMasternodePayments::GetMinMasternodePaymentsProto() const { void CMasternodePayments::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman) { + if (deterministicMNManager->IsDeterministicMNsSporkActive()) + return; + if(fLiteMode) return; // disable all Dash specific functionality if (strCommand == NetMsgType::MASTERNODEPAYMENTSYNC) { //Masternode Payments Request Sync @@ -514,14 +524,29 @@ bool CMasternodePayments::GetBlockTxOuts(int nBlockHeight, CAmount blockReward, CAmount masternodeReward = GetMasternodePayment(nBlockHeight, blockReward); - LOCK(cs_mapMasternodeBlocks); - auto it = mapMasternodeBlocks.find(nBlockHeight); - CScript payee; - if (it == mapMasternodeBlocks.end() || !it->second.GetBestPayee(payee)) { - return false; + if (deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) { + uint256 blockHash; + { + LOCK(cs_main); + blockHash = chainActive[nBlockHeight - 1]->GetBlockHash(); + } + uint256 proTxHash; + auto dmnPayee = deterministicMNManager->GetListForBlock(blockHash).GetMNPayee(); + if (!dmnPayee) { + return false; + } + voutMasternodePaymentsRet.emplace_back(masternodeReward, dmnPayee->pdmnState->scriptPayout); + return true; + } else { + LOCK(cs_mapMasternodeBlocks); + auto it = mapMasternodeBlocks.find(nBlockHeight); + CScript payee; + if (it == mapMasternodeBlocks.end() || !it->second.GetBestPayee(payee)) { + return false; + } + voutMasternodePaymentsRet.emplace_back(masternodeReward, payee); + return true; } - voutMasternodePaymentsRet.emplace_back(masternodeReward, payee); - return true; } // Is this masternode scheduled to get paid soon? @@ -698,10 +723,22 @@ std::string CMasternodeBlockPayees::GetRequiredPaymentsString() const std::string CMasternodePayments::GetRequiredPaymentsString(int nBlockHeight) const { - LOCK(cs_mapMasternodeBlocks); - - const auto it = mapMasternodeBlocks.find(nBlockHeight); - return it == mapMasternodeBlocks.end() ? "Unknown" : it->second.GetRequiredPaymentsString(); + if (deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) { + LOCK(cs_main); + auto pindex = chainActive[nBlockHeight - 1]; + auto payee = deterministicMNManager->GetListForBlock(pindex->GetBlockHash()).GetMNPayee(); + if (!payee) { + return "Unknown"; + } + CTxDestination dest; + if (!ExtractDestination(payee->pdmnState->scriptPayout, dest)) + assert(false); + return CBitcoinAddress(dest).ToString(); + } else { + LOCK(cs_mapMasternodeBlocks); + const auto it = mapMasternodeBlocks.find(nBlockHeight); + return it == mapMasternodeBlocks.end() ? "Unknown" : it->second.GetRequiredPaymentsString(); + } } bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const @@ -713,6 +750,10 @@ bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlo void CMasternodePayments::CheckAndRemove() { + if (deterministicMNManager->IsDeterministicMNsSporkActive()) { + return; + } + if(!masternodeSync.IsBlockchainSynced()) return; LOCK2(cs_mapMasternodeBlocks, cs_mapMasternodePaymentVotes); @@ -794,6 +835,10 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s bool CMasternodePayments::ProcessBlock(int nBlockHeight, CConnman& connman) { + if (deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) { + return true; + } + // DETERMINE IF WE SHOULD BE VOTING FOR THE NEXT PAYEE if(fLiteMode || !fMasternodeMode) return false; @@ -929,6 +974,10 @@ void CMasternodePayments::CheckBlockVotes(int nBlockHeight) void CMasternodePaymentVote::Relay(CConnman& connman) const { + if (deterministicMNManager->IsDeterministicMNsSporkActive()) { + return; + } + // Do not relay until fully synced if(!masternodeSync.IsSynced()) { LogPrint("mnpayments", "CMasternodePayments::%s -- won't relay until fully synced\n", __func__); @@ -1130,6 +1179,10 @@ void CMasternodePayments::UpdatedBlockTip(const CBlockIndex *pindex, CConnman& c { if(!pindex) return; + if (deterministicMNManager->IsDeterministicMNsSporkActive(pindex->nHeight)) { + return; + } + nCachedBlockHeight = pindex->nHeight; LogPrint("mnpayments", "CMasternodePayments::%s -- nCachedBlockHeight=%d\n", __func__, nCachedBlockHeight); diff --git a/src/masternode.cpp b/src/masternode.cpp index 84a26ce6d..39350741f 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -18,6 +18,8 @@ #include "wallet/wallet.h" #endif // ENABLE_WALLET +#include "evo/deterministicmns.h" + #include @@ -347,6 +349,19 @@ void CMasternode::UpdateLastPaid(const CBlockIndex *pindex, int nMaxBlocksToScan { if(!pindex) return; + if (deterministicMNManager->IsDeterministicMNsSporkActive(pindex->nHeight)) { + auto dmn = deterministicMNManager->GetListForBlock(pindex->GetBlockHash()).GetMN(outpoint.hash); + if (!dmn || dmn->pdmnState->nLastPaidHeight == -1) { + LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s -- not found\n", outpoint.ToStringShort()); + } else { + LOCK(cs_main); + nBlockLastPaid = (int)dmn->pdmnState->nLastPaidHeight; + nTimeLastPaid = chainActive[nBlockLastPaid]->nTime; + LogPrint("masternode", "CMasternode::UpdateLastPaidBlock -- searching for block with payment to %s -- found new %d\n", outpoint.ToStringShort(), nBlockLastPaid); + } + return; + } + const CBlockIndex *BlockReading = pindex; CScript mnpayee = GetScriptForDestination(keyIDCollateralAddress); diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index c7a53e55c..318b45e1e 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -583,6 +583,14 @@ bool CMasternodeMan::Get(const COutPoint& outpoint, CMasternode& masternodeRet) return true; } +bool CMasternodeMan::GetMasternodeInfo(const uint256& proTxHash, masternode_info_t& mnInfoRet) +{ + auto dmn = deterministicMNManager->GetListAtChainTip().GetValidMN(proTxHash); + if (!dmn) + return false; + return GetMasternodeInfo(COutPoint(proTxHash, dmn->nCollateralIndex), mnInfoRet); +} + bool CMasternodeMan::GetMasternodeInfo(const COutPoint& outpoint, masternode_info_t& mnInfoRet) { LOCK(cs); @@ -654,6 +662,10 @@ bool CMasternodeMan::GetNextMasternodeInQueueForPayment(bool fFilterSigTime, int bool CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int& nCountRet, masternode_info_t& mnInfoRet) { + if (deterministicMNManager->IsDeterministicMNsSporkActive(nBlockHeight)) { + return false; + } + mnInfoRet = masternode_info_t(); nCountRet = 0; diff --git a/src/masternodeman.h b/src/masternodeman.h index 243ee8040..94d102cde 100644 --- a/src/masternodeman.h +++ b/src/masternodeman.h @@ -171,6 +171,7 @@ public: bool Get(const COutPoint& outpoint, CMasternode& masternodeRet); bool Has(const COutPoint& outpoint); + bool GetMasternodeInfo(const uint256& proTxHash, masternode_info_t& mnInfoRet); bool GetMasternodeInfo(const COutPoint& outpoint, masternode_info_t& mnInfoRet); bool GetMasternodeInfo(const CKeyID& keyIDOperator, masternode_info_t& mnInfoRet); bool GetMasternodeInfo(const CPubKey& pubKeyOperator, masternode_info_t& mnInfoRet); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 2bc080e9a..1a32aa252 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -42,6 +42,7 @@ #endif // ENABLE_WALLET #include "privatesend-server.h" +#include "evo/deterministicmns.h" #include "evo/simplifiedmns.h" #include @@ -1178,25 +1179,29 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam } if (!push && inv.type == MSG_MASTERNODE_PAYMENT_VOTE) { - if(mnpayments.HasVerifiedPaymentVote(inv.hash)) { - connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTVOTE, mnpayments.mapMasternodePaymentVotes[inv.hash])); - push = true; + if (!deterministicMNManager->IsDeterministicMNsSporkActive()) { + if (mnpayments.HasVerifiedPaymentVote(inv.hash)) { + connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTVOTE, mnpayments.mapMasternodePaymentVotes[inv.hash])); + push = true; + } } } if (!push && inv.type == MSG_MASTERNODE_PAYMENT_BLOCK) { - BlockMap::iterator mi = mapBlockIndex.find(inv.hash); - LOCK(cs_mapMasternodeBlocks); - if (mi != mapBlockIndex.end() && mnpayments.mapMasternodeBlocks.count(mi->second->nHeight)) { - BOOST_FOREACH(CMasternodePayee& payee, mnpayments.mapMasternodeBlocks[mi->second->nHeight].vecPayees) { - std::vector vecVoteHashes = payee.GetVoteHashes(); - BOOST_FOREACH(uint256& hash, vecVoteHashes) { - if(mnpayments.HasVerifiedPaymentVote(hash)) { - connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTVOTE, mnpayments.mapMasternodePaymentVotes[hash])); + if (!deterministicMNManager->IsDeterministicMNsSporkActive()) { + BlockMap::iterator mi = mapBlockIndex.find(inv.hash); + LOCK(cs_mapMasternodeBlocks); + if (mi != mapBlockIndex.end() && mnpayments.mapMasternodeBlocks.count(mi->second->nHeight)) { + BOOST_FOREACH(CMasternodePayee& payee, mnpayments.mapMasternodeBlocks[mi->second->nHeight].vecPayees) { + std::vector vecVoteHashes = payee.GetVoteHashes(); + BOOST_FOREACH(uint256& hash, vecVoteHashes) { + if(mnpayments.HasVerifiedPaymentVote(hash)) { + connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::MASTERNODEPAYMENTVOTE, mnpayments.mapMasternodePaymentVotes[hash])); + } } } + push = true; } - push = true; } } diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 33bace9ce..1fe361fd8 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -24,6 +24,8 @@ #include "evo/specialtx.h" #include "evo/deterministicmns.h" +#include "evo/deterministicmns.h" + #include #include #include @@ -223,10 +225,15 @@ UniValue masternode_count(const JSONRPCRequest& request) masternode_count_help(); int nCount; - masternode_info_t mnInfo; - mnodeman.GetNextMasternodeInQueueForPayment(true, nCount, mnInfo); + int total; + if (deterministicMNManager->IsDeterministicMNsSporkActive()) { + nCount = total = mnodeman.CountEnabled(); + } else { + masternode_info_t mnInfo; + mnodeman.GetNextMasternodeInQueueForPayment(true, nCount, mnInfo); + total = mnodeman.size(); + } - int total = mnodeman.size(); int ps = mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION); int enabled = mnodeman.CountEnabled(); @@ -272,11 +279,18 @@ UniValue GetNextMasternodeForPayment(int heightShift) LOCK(cs_main); pindex = chainActive.Tip(); } + nHeight = pindex->nHeight + heightShift; mnodeman.UpdateLastPaid(pindex); - if (!mnodeman.GetNextMasternodeInQueueForPayment(nHeight, true, nCount, mnInfo)) - return "unknown"; + if (deterministicMNManager->IsDeterministicMNsSporkActive()) { + auto payee = deterministicMNManager->GetListAtChainTip().GetMNPayee(); + if (!payee || !mnodeman.GetMasternodeInfo(payee->proTxHash, mnInfo)) + return "unknown"; + } else { + if (!mnodeman.GetNextMasternodeInQueueForPayment(nHeight, true, nCount, mnInfo)) + return "unknown"; + } UniValue obj(UniValue::VOBJ);