diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index 88b86a9247036..71980c9ad1ab6 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -747,51 +747,6 @@ bool CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight, bool f return mnInfoRet.fInfoValid; } -masternode_info_t CMasternodeMan::FindRandomNotInVec(const std::vector &vecToExclude, int nProtocolVersion) -{ - LOCK(cs); - - nProtocolVersion = nProtocolVersion == -1 ? mnpayments.GetMinMasternodePaymentsProto() : nProtocolVersion; - - int nCountEnabled = CountEnabled(nProtocolVersion); - int nCountNotExcluded = nCountEnabled - vecToExclude.size(); - - LogPrintf("CMasternodeMan::FindRandomNotInVec -- %d enabled masternodes, %d masternodes to choose from\n", nCountEnabled, nCountNotExcluded); - if(nCountNotExcluded < 1) return masternode_info_t(); - - // fill a vector of pointers - std::vector vpMasternodesShuffled; - for (const auto& mnpair : mapMasternodes) { - vpMasternodesShuffled.push_back(&mnpair.second); - } - - FastRandomContext insecure_rand; - // shuffle pointers - std::random_shuffle(vpMasternodesShuffled.begin(), vpMasternodesShuffled.end(), insecure_rand); - bool fExclude; - - // loop through - for (const auto& pmn : vpMasternodesShuffled) { - if(pmn->nProtocolVersion < nProtocolVersion || !pmn->IsEnabled()) continue; - fExclude = false; - for (const auto& outpointToExclude : vecToExclude) { - if(pmn->outpoint == outpointToExclude) { - fExclude = true; - break; - } - } - if(fExclude) continue; - if (deterministicMNManager->IsDIP3Active() && !deterministicMNManager->HasValidMNCollateralAtChainTip(pmn->outpoint)) - continue; - // found the one not in vecToExclude - LogPrint("masternode", "CMasternodeMan::FindRandomNotInVec -- found, masternode=%s\n", pmn->outpoint.ToStringShort()); - return pmn->GetInfo(); - } - - LogPrint("masternode", "CMasternodeMan::FindRandomNotInVec -- failed\n"); - return masternode_info_t(); -} - std::map CMasternodeMan::GetFullMasternodeMap() { LOCK(cs); diff --git a/src/masternodeman.h b/src/masternodeman.h index 58c3ff91b6631..695229a96c2de 100644 --- a/src/masternodeman.h +++ b/src/masternodeman.h @@ -182,9 +182,6 @@ class CMasternodeMan /// Same as above but use current block height bool GetNextMasternodeInQueueForPayment(bool fFilterSigTime, int& nCountRet, masternode_info_t& mnInfoRet); - /// Find a random entry - masternode_info_t FindRandomNotInVec(const std::vector &vecToExclude, int nProtocolVersion = -1); - std::map GetFullMasternodeMap(); bool GetMasternodeRanks(rank_pair_vec_t& vecMasternodeRanksRet, int nBlockHeight = -1, int nMinProtocol = 0); diff --git a/src/privatesend-client.cpp b/src/privatesend-client.cpp index 6b809892388da..98590e8a78551 100644 --- a/src/privatesend-client.cpp +++ b/src/privatesend-client.cpp @@ -991,9 +991,43 @@ void CPrivateSendClientManager::AddUsedMasternode(const COutPoint& outpointMn) vecMasternodesUsed.push_back(outpointMn); } -masternode_info_t CPrivateSendClientManager::GetNotUsedMasternode() +CDeterministicMNCPtr CPrivateSendClientManager::GetRandomNotUsedMasternode() { - return mnodeman.FindRandomNotInVec(vecMasternodesUsed, MIN_PRIVATESEND_PEER_PROTO_VERSION); + auto mnList = deterministicMNManager->GetListAtChainTip(); + + int nCountEnabled = mnList.GetValidMNsCount(); + int nCountNotExcluded = nCountEnabled - vecMasternodesUsed.size(); + + LogPrintf("CPrivateSendClientManager::%s -- %d enabled masternodes, %d masternodes to choose from\n", __func__, nCountEnabled, nCountNotExcluded); + if(nCountNotExcluded < 1) { + return nullptr; + } + + // fill a vector + std::vector vpMasternodesShuffled; + vpMasternodesShuffled.reserve((size_t)nCountEnabled); + mnList.ForEachMN(true, [&](const CDeterministicMNCPtr& dmn) { + vpMasternodesShuffled.emplace_back(dmn); + }); + + FastRandomContext insecure_rand; + // shuffle pointers + std::random_shuffle(vpMasternodesShuffled.begin(), vpMasternodesShuffled.end(), insecure_rand); + + std::set excludeSet(vecMasternodesUsed.begin(), vecMasternodesUsed.end()); + + // loop through + for (const auto& dmn : vpMasternodesShuffled) { + if (excludeSet.count(dmn->collateralOutpoint)) { + continue; + } + + LogPrint("masternode", "CPrivateSendClientManager::%s -- found, masternode=%s\n", __func__, dmn->collateralOutpoint.ToStringShort()); + return dmn; + } + + LogPrint("masternode", "CPrivateSendClientManager::%s -- failed\n", __func__); + return nullptr; } bool CPrivateSendClientSession::JoinExistingQueue(CAmount nBalanceNeedsAnonymized, CConnman& connman) diff --git a/src/privatesend-client.h b/src/privatesend-client.h index 245089793ebea..1ab1b31c15723 100644 --- a/src/privatesend-client.h +++ b/src/privatesend-client.h @@ -248,7 +248,7 @@ class CPrivateSendClientManager : public CPrivateSendBaseManager void ProcessPendingDsaRequest(CConnman& connman); void AddUsedMasternode(const COutPoint& outpointMn); - masternode_info_t GetNotUsedMasternode(); + CDeterministicMNCPtr GetRandomNotUsedMasternode(); void UpdatedSuccessBlock();