diff --git a/src/activemasternode.cpp b/src/activemasternode.cpp index 8045cf57d..18d0eee32 100644 --- a/src/activemasternode.cpp +++ b/src/activemasternode.cpp @@ -100,14 +100,14 @@ bool CActiveMasternode::SendMasternodePing() return false; } - if(!mnodeman.Has(vin)) { + if(!mnodeman.Has(outpoint)) { strNotCapableReason = "Masternode not in masternode list"; nState = ACTIVE_MASTERNODE_NOT_CAPABLE; LogPrintf("CActiveMasternode::SendMasternodePing -- %s: %s\n", GetStateString(), strNotCapableReason); return false; } - CMasternodePing mnp(vin); + CMasternodePing mnp(outpoint); mnp.nSentinelVersion = nSentinelVersion; mnp.fSentinelIsCurrent = (abs(GetAdjustedTime() - nSentinelPingTime) < MASTERNODE_WATCHDOG_MAX_SECONDS); @@ -117,14 +117,14 @@ bool CActiveMasternode::SendMasternodePing() } // Update lastPing for our masternode in Masternode list - if(mnodeman.IsMasternodePingedWithin(vin, MASTERNODE_MIN_MNP_SECONDS, mnp.sigTime)) { + if(mnodeman.IsMasternodePingedWithin(outpoint, MASTERNODE_MIN_MNP_SECONDS, mnp.sigTime)) { LogPrintf("CActiveMasternode::SendMasternodePing -- Too early to send Masternode Ping\n"); return false; } - mnodeman.SetMasternodeLastPing(vin, mnp); + mnodeman.SetMasternodeLastPing(outpoint, mnp); - LogPrintf("CActiveMasternode::SendMasternodePing -- Relaying ping, collateral=%s\n", vin.ToString()); + LogPrintf("CActiveMasternode::SendMasternodePing -- Relaying ping, collateral=%s\n", outpoint.ToStringShort()); mnp.Relay(); return true; @@ -227,7 +227,7 @@ void CActiveMasternode::ManageStateInitial() CKey keyCollateral; // If collateral is found switch to LOCAL mode - if(pwalletMain->GetMasternodeVinAndKeys(vin, pubKeyCollateral, keyCollateral)) { + if(pwalletMain->GetMasternodeOutpointAndKeys(outpoint, pubKeyCollateral, keyCollateral)) { eType = MASTERNODE_LOCAL; } @@ -240,8 +240,8 @@ void CActiveMasternode::ManageStateRemote() GetStatus(), GetTypeString(), fPingerEnabled, pubKeyMasternode.GetID().ToString()); mnodeman.CheckMasternode(pubKeyMasternode, true); - masternode_info_t infoMn = mnodeman.GetMasternodeInfo(pubKeyMasternode); - if(infoMn.fInfoValid) { + masternode_info_t infoMn; + if(mnodeman.GetMasternodeInfo(pubKeyMasternode, infoMn)) { if(infoMn.nProtocolVersion != PROTOCOL_VERSION) { nState = ACTIVE_MASTERNODE_NOT_CAPABLE; strNotCapableReason = "Invalid protocol version"; @@ -262,7 +262,7 @@ void CActiveMasternode::ManageStateRemote() } if(nState != ACTIVE_MASTERNODE_STARTED) { LogPrintf("CActiveMasternode::ManageStateRemote -- STARTED!\n"); - vin = infoMn.vin; + outpoint = infoMn.vin.prevout; service = infoMn.addr; fPingerEnabled = true; nState = ACTIVE_MASTERNODE_STARTED; @@ -286,8 +286,8 @@ void CActiveMasternode::ManageStateLocal() CPubKey pubKeyCollateral; CKey keyCollateral; - if(pwalletMain->GetMasternodeVinAndKeys(vin, pubKeyCollateral, keyCollateral)) { - int nPrevoutAge = GetUTXOConfirmations(vin.prevout); + if(pwalletMain->GetMasternodeOutpointAndKeys(outpoint, pubKeyCollateral, keyCollateral)) { + int nPrevoutAge = GetUTXOConfirmations(outpoint); if(nPrevoutAge < Params().GetConsensus().nMasternodeMinimumConfirmations){ nState = ACTIVE_MASTERNODE_INPUT_TOO_NEW; strNotCapableReason = strprintf(_("%s - %d confirmations"), GetStatus(), nPrevoutAge); @@ -297,12 +297,12 @@ void CActiveMasternode::ManageStateLocal() { LOCK(pwalletMain->cs_wallet); - pwalletMain->LockCoin(vin.prevout); + pwalletMain->LockCoin(outpoint); } CMasternodeBroadcast mnb; std::string strError; - if(!CMasternodeBroadcast::Create(vin, service, keyCollateral, pubKeyCollateral, keyMasternode, pubKeyMasternode, strError, mnb)) { + if(!CMasternodeBroadcast::Create(outpoint, service, keyCollateral, pubKeyCollateral, keyMasternode, pubKeyMasternode, strError, mnb)) { nState = ACTIVE_MASTERNODE_NOT_CAPABLE; strNotCapableReason = "Error creating mastenode broadcast: " + strError; LogPrintf("CActiveMasternode::ManageStateLocal -- %s: %s\n", GetStateString(), strNotCapableReason); @@ -318,7 +318,7 @@ void CActiveMasternode::ManageStateLocal() mnodeman.NotifyMasternodeUpdates(); //send to all peers - LogPrintf("CActiveMasternode::ManageStateLocal -- Relay broadcast, vin=%s\n", vin.ToString()); + LogPrintf("CActiveMasternode::ManageStateLocal -- Relay broadcast, collateral=%s\n", outpoint.ToStringShort()); mnb.Relay(); } } diff --git a/src/activemasternode.h b/src/activemasternode.h index 0c5058446..4b62fa4b0 100644 --- a/src/activemasternode.h +++ b/src/activemasternode.h @@ -50,7 +50,7 @@ public: CKey keyMasternode; // Initialized while registering Masternode - CTxIn vin; + COutPoint outpoint; CService service; int nState; // should be one of ACTIVE_MASTERNODE_XXXX @@ -62,7 +62,7 @@ public: fPingerEnabled(false), pubKeyMasternode(), keyMasternode(), - vin(), + outpoint(), service(), nState(ACTIVE_MASTERNODE_INITIAL) {} diff --git a/src/governance-object.cpp b/src/governance-object.cpp index 7af0ddeb5..ce56bb895 100644 --- a/src/governance-object.cpp +++ b/src/governance-object.cpp @@ -99,13 +99,13 @@ bool CGovernanceObject::ProcessVote(CNode* pfrom, const CGovernanceVote& vote, CGovernanceException& exception) { - if(!mnodeman.Has(vote.GetVinMasternode())) { + if(!mnodeman.Has(vote.GetMasternodeOutpoint())) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Masternode index not found"; exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_WARNING); - if(mapOrphanVotes.Insert(vote.GetVinMasternode(), vote_time_pair_t(vote, GetAdjustedTime() + GOVERNANCE_ORPHAN_EXPIRATION_TIME))) { + if(mapOrphanVotes.Insert(vote.GetMasternodeOutpoint(), vote_time_pair_t(vote, GetAdjustedTime() + GOVERNANCE_ORPHAN_EXPIRATION_TIME))) { if(pfrom) { - mnodeman.AskForMN(pfrom, vote.GetVinMasternode()); + mnodeman.AskForMN(pfrom, vote.GetMasternodeOutpoint()); } LogPrintf("%s\n", ostr.str()); } @@ -115,9 +115,9 @@ bool CGovernanceObject::ProcessVote(CNode* pfrom, return false; } - vote_m_it it = mapCurrentMNVotes.find(vote.GetVinMasternode()); + vote_m_it it = mapCurrentMNVotes.find(vote.GetMasternodeOutpoint()); if(it == mapCurrentMNVotes.end()) { - it = mapCurrentMNVotes.insert(vote_m_t::value_type(vote.GetVinMasternode(), vote_rec_t())).first; + it = mapCurrentMNVotes.insert(vote_m_t::value_type(vote.GetMasternodeOutpoint(), vote_rec_t())).first; } vote_rec_t& recVote = it->second; vote_signal_enum_t eSignal = vote.GetSignal(); @@ -157,7 +157,7 @@ bool CGovernanceObject::ProcessVote(CNode* pfrom, if(nTimeDelta < GOVERNANCE_UPDATE_MIN) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Masternode voting too often" - << ", MN outpoint = " << vote.GetVinMasternode().prevout.ToStringShort() + << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort() << ", governance object hash = " << GetHash().ToString() << ", time delta = " << nTimeDelta; LogPrint("gobject", "%s\n", ostr.str()); @@ -170,7 +170,7 @@ bool CGovernanceObject::ProcessVote(CNode* pfrom, if(!vote.IsValid(true)) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Invalid vote" - << ", MN outpoint = " << vote.GetVinMasternode().prevout.ToStringShort() + << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort() << ", governance object hash = " << GetHash().ToString() << ", vote hash = " << vote.GetHash().ToString(); LogPrintf("%s\n", ostr.str()); @@ -178,10 +178,10 @@ bool CGovernanceObject::ProcessVote(CNode* pfrom, governance.AddInvalidVote(vote); return false; } - if(!mnodeman.AddGovernanceVote(vote.GetVinMasternode(), vote.GetParentHash())) { + if(!mnodeman.AddGovernanceVote(vote.GetMasternodeOutpoint(), vote.GetParentHash())) { std::ostringstream ostr; ostr << "CGovernanceObject::ProcessVote -- Unable to add governance vote" - << ", MN outpoint = " << vote.GetVinMasternode().prevout.ToStringShort() + << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort() << ", governance object hash = " << GetHash().ToString(); LogPrint("gobject", "%s\n", ostr.str()); exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_PERMANENT_ERROR); @@ -222,9 +222,9 @@ std::string CGovernanceObject::GetSignatureMessage() const return strMessage; } -void CGovernanceObject::SetMasternodeInfo(const CTxIn& vin) +void CGovernanceObject::SetMasternodeVin(const COutPoint& outpoint) { - vinMasternode = vin; + vinMasternode = CTxIn(outpoint); } bool CGovernanceObject::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode) @@ -442,17 +442,17 @@ bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMast if(fCheckCollateral) { if((nObjectType == GOVERNANCE_OBJECT_TRIGGER) || (nObjectType == GOVERNANCE_OBJECT_WATCHDOG)) { std::string strOutpoint = vinMasternode.prevout.ToStringShort(); - masternode_info_t infoMn = mnodeman.GetMasternodeInfo(vinMasternode); - if(!infoMn.fInfoValid) { + masternode_info_t infoMn; + if(!mnodeman.GetMasternodeInfo(vinMasternode.prevout, infoMn)) { - CMasternode::CollateralStatus err = CMasternode::CheckCollateral(GetMasternodeVin()); + CMasternode::CollateralStatus err = CMasternode::CheckCollateral(vinMasternode.prevout); if (err == CMasternode::COLLATERAL_OK) { fMissingMasternode = true; strError = "Masternode not found: " + strOutpoint; } else if (err == CMasternode::COLLATERAL_UTXO_NOT_FOUND) { - strError = "Failed to find Masternode UTXO, missing masternode=" + GetMasternodeVin().prevout.ToStringShort() + "\n"; + strError = "Failed to find Masternode UTXO, missing masternode=" + strOutpoint + "\n"; } else if (err == CMasternode::COLLATERAL_INVALID_AMOUNT) { - strError = "Masternode UTXO should have 1000 DASH, missing masternode=" + GetMasternodeVin().prevout.ToStringShort() + "\n"; + strError = "Masternode UTXO should have 1000 DASH, missing masternode=" + strOutpoint + "\n"; } return false; @@ -638,7 +638,7 @@ int CGovernanceObject::GetAbstainCount(vote_signal_enum_t eVoteSignalIn) const return CountMatchingVotes(eVoteSignalIn, VOTE_OUTCOME_ABSTAIN); } -bool CGovernanceObject::GetCurrentMNVotes(const CTxIn& mnCollateralOutpoint, vote_rec_t& voteRecord) +bool CGovernanceObject::GetCurrentMNVotes(const COutPoint& mnCollateralOutpoint, vote_rec_t& voteRecord) { vote_m_it it = mapCurrentMNVotes.find(mnCollateralOutpoint); if (it == mapCurrentMNVotes.end()) { @@ -722,13 +722,13 @@ void CGovernanceObject::CheckOrphanVotes() vote_mcache_t::list_cit it = listVotes.begin(); while(it != listVotes.end()) { bool fRemove = false; - const CTxIn& key = it->key; + const COutPoint& key = it->key; const vote_time_pair_t& pairVote = it->value; const CGovernanceVote& vote = pairVote.first; if(pairVote.second < nNow) { fRemove = true; } - else if(!mnodeman.Has(vote.GetVinMasternode())) { + else if(!mnodeman.Has(vote.GetMasternodeOutpoint())) { ++it; continue; } diff --git a/src/governance-object.h b/src/governance-object.h index 59342563a..d66b9638b 100644 --- a/src/governance-object.h +++ b/src/governance-object.h @@ -116,13 +116,13 @@ class CGovernanceObject friend class CGovernanceTriggerManager; public: // Types - typedef std::map vote_m_t; + typedef std::map vote_m_t; typedef vote_m_t::iterator vote_m_it; typedef vote_m_t::const_iterator vote_m_cit; - typedef CacheMultiMap vote_mcache_t; + typedef CacheMultiMap vote_mcache_t; private: /// critical section to protect the inner data structures @@ -254,7 +254,7 @@ public: // Signature related functions - void SetMasternodeInfo(const CTxIn& vin); + void SetMasternodeVin(const COutPoint& outpoint); bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode); bool CheckSignature(CPubKey& pubKeyMasternode); @@ -293,7 +293,7 @@ public: int GetNoCount(vote_signal_enum_t eVoteSignalIn) const; int GetAbstainCount(vote_signal_enum_t eVoteSignalIn) const; - bool GetCurrentMNVotes(const CTxIn& mnCollateralOutpoint, vote_rec_t& voteRecord); + bool GetCurrentMNVotes(const COutPoint& mnCollateralOutpoint, vote_rec_t& voteRecord); // FUNCTIONS FOR DEALING WITH DATA STRING diff --git a/src/governance-vote.cpp b/src/governance-vote.cpp index e45fc6720..09cc7737c 100644 --- a/src/governance-vote.cpp +++ b/src/governance-vote.cpp @@ -212,11 +212,11 @@ CGovernanceVote::CGovernanceVote() vchSig() {} -CGovernanceVote::CGovernanceVote(CTxIn vinMasternodeIn, uint256 nParentHashIn, vote_signal_enum_t eVoteSignalIn, vote_outcome_enum_t eVoteOutcomeIn) +CGovernanceVote::CGovernanceVote(COutPoint outpointMasternodeIn, uint256 nParentHashIn, vote_signal_enum_t eVoteSignalIn, vote_outcome_enum_t eVoteOutcomeIn) : fValid(true), fSynced(false), nVoteSignal(eVoteSignalIn), - vinMasternode(vinMasternodeIn), + vinMasternode(outpointMasternodeIn), nParentHash(nParentHashIn), nVoteOutcome(eVoteOutcomeIn), nTime(GetAdjustedTime()), @@ -273,8 +273,8 @@ bool CGovernanceVote::IsValid(bool fSignatureCheck) const return false; } - masternode_info_t infoMn = mnodeman.GetMasternodeInfo(vinMasternode); - if(!infoMn.fInfoValid) { + masternode_info_t infoMn; + if(!mnodeman.GetMasternodeInfo(vinMasternode.prevout, infoMn)) { LogPrint("gobject", "CGovernanceVote::IsValid -- Unknown Masternode - %s\n", vinMasternode.prevout.ToStringShort()); return false; } diff --git a/src/governance-vote.h b/src/governance-vote.h index 5e1e50788..fd05c0c14 100644 --- a/src/governance-vote.h +++ b/src/governance-vote.h @@ -102,7 +102,7 @@ private: public: CGovernanceVote(); - CGovernanceVote(CTxIn vinMasternodeIn, uint256 nParentHashIn, vote_signal_enum_t eVoteSignalIn, vote_outcome_enum_t eVoteOutcomeIn); + CGovernanceVote(COutPoint outpointMasternodeIn, uint256 nParentHashIn, vote_signal_enum_t eVoteSignalIn, vote_outcome_enum_t eVoteOutcomeIn); bool IsValid() const { return fValid; } @@ -128,9 +128,7 @@ public: return CGovernanceVoting::ConvertOutcomeToString(GetOutcome()); } - CTxIn& GetVinMasternode() { return vinMasternode; } - - const CTxIn& GetVinMasternode() const { return vinMasternode; } + const COutPoint& GetMasternodeOutpoint() const { return vinMasternode.prevout; } /** * GetHash() diff --git a/src/governance-votedb.cpp b/src/governance-votedb.cpp index 0a817f966..615528733 100644 --- a/src/governance-votedb.cpp +++ b/src/governance-votedb.cpp @@ -53,11 +53,11 @@ std::vector CGovernanceObjectVoteFile::GetVotes() const return vecResult; } -void CGovernanceObjectVoteFile::RemoveVotesFromMasternode(const CTxIn& vinMasternode) +void CGovernanceObjectVoteFile::RemoveVotesFromMasternode(const COutPoint& outpointMasternode) { vote_l_it it = listVotes.begin(); while(it != listVotes.end()) { - if(it->GetVinMasternode() == vinMasternode) { + if(it->GetMasternodeOutpoint() == outpointMasternode) { --nMemoryVotes; mapVoteIndex.erase(it->GetHash()); listVotes.erase(it++); diff --git a/src/governance-votedb.h b/src/governance-votedb.h index 582f2e061..2a3abb013 100644 --- a/src/governance-votedb.h +++ b/src/governance-votedb.h @@ -72,7 +72,7 @@ public: CGovernanceObjectVoteFile& operator=(const CGovernanceObjectVoteFile& other); - void RemoveVotesFromMasternode(const CTxIn& vinMasternode); + void RemoveVotesFromMasternode(const COutPoint& outpointMasternode); ADD_SERIALIZE_METHODS; diff --git a/src/governance.cpp b/src/governance.cpp index 0cb9f129a..36f896eb3 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -580,7 +580,7 @@ std::vector CGovernanceManager::GetMatchingVotes(const uint256& return govobj.GetVoteFile().GetVotes(); } -std::vector CGovernanceManager::GetCurrentVotes(const uint256& nParentHash, const CTxIn& mnCollateralOutpointFilter) +std::vector CGovernanceManager::GetCurrentVotes(const uint256& nParentHash, const COutPoint& mnCollateralOutpointFilter) { LOCK(cs); std::vector vecResult; @@ -590,34 +590,27 @@ std::vector CGovernanceManager::GetCurrentVotes(const uint256& if(it == mapObjects.end()) return vecResult; CGovernanceObject& govobj = it->second; - // Compile a list of Masternode collateral outpoints for which to get votes - std::vector vecMNTxIn; - if (mnCollateralOutpointFilter == CTxIn()) { - std::vector mnlist = mnodeman.GetFullMasternodeVector(); - for (std::vector::iterator it = mnlist.begin(); it != mnlist.end(); ++it) - { - vecMNTxIn.push_back(it->vin); - } - } - else { - vecMNTxIn.push_back(mnCollateralOutpointFilter); + CMasternode mn; + std::map mapMasternodes; + if(mnCollateralOutpointFilter == COutPoint()) { + mapMasternodes = mnodeman.GetFullMasternodeMap(); + } else if (mnodeman.Get(mnCollateralOutpointFilter, mn)) { + mapMasternodes[mnCollateralOutpointFilter] = mn; } // Loop thru each MN collateral outpoint and get the votes for the `nParentHash` governance object - for (std::vector::iterator it = vecMNTxIn.begin(); it != vecMNTxIn.end(); ++it) + for (auto& mnpair : mapMasternodes) { - CTxIn &mnCollateralOutpoint = *it; - // get a vote_rec_t from the govobj vote_rec_t voteRecord; - if (!govobj.GetCurrentMNVotes(mnCollateralOutpoint, voteRecord)) continue; + if (!govobj.GetCurrentMNVotes(mnpair.first, voteRecord)) continue; for (vote_instance_m_it it3 = voteRecord.mapInstances.begin(); it3 != voteRecord.mapInstances.end(); ++it3) { int signal = (it3->first); int outcome = ((it3->second).eOutcome); int64_t nCreationTime = ((it3->second).nCreationTime); - CGovernanceVote vote = CGovernanceVote(mnCollateralOutpoint, nParentHash, (vote_signal_enum_t)signal, (vote_outcome_enum_t)outcome); + CGovernanceVote vote = CGovernanceVote(mnpair.first, nParentHash, (vote_signal_enum_t)signal, (vote_outcome_enum_t)outcome); vote.SetTime(nCreationTime); vecResult.push_back(vote); @@ -940,7 +933,7 @@ bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote, if(mapInvalidVotes.HasKey(nHashVote)) { std::ostringstream ostr; ostr << "CGovernanceManager::ProcessVote -- Old invalid vote " - << ", MN outpoint = " << vote.GetVinMasternode().prevout.ToStringShort() + << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort() << ", governance object hash = " << vote.GetParentHash().ToString(); LogPrintf("%s\n", ostr.str()); exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_PERMANENT_ERROR, 20); @@ -953,7 +946,7 @@ bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote, if(it == mapObjects.end()) { std::ostringstream ostr; ostr << "CGovernanceManager::ProcessVote -- Unknown parent object " - << ", MN outpoint = " << vote.GetVinMasternode().prevout.ToStringShort() + << ", MN outpoint = " << vote.GetMasternodeOutpoint().ToStringShort() << ", governance object hash = " << vote.GetParentHash().ToString(); exception = CGovernanceException(ostr.str(), GOVERNANCE_EXCEPTION_WARNING); if(mapOrphanVotes.Insert(nHashGovobj, vote_time_pair_t(vote, GetAdjustedTime() + GOVERNANCE_ORPHAN_EXPIRATION_TIME))) { @@ -981,7 +974,7 @@ bool CGovernanceManager::ProcessVote(CNode* pfrom, const CGovernanceVote& vote, mapVoteToObject.Insert(nHashVote, &govobj); if(govobj.GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG) { - mnodeman.UpdateWatchdogVoteTime(vote.GetVinMasternode()); + mnodeman.UpdateWatchdogVoteTime(vote.GetMasternodeOutpoint()); LogPrint("gobject", "CGovernanceObject::ProcessVote -- GOVERNANCE_OBJECT_WATCHDOG vote for %s\n", vote.GetParentHash().ToString()); } } diff --git a/src/governance.h b/src/governance.h index 87ba21fae..6028e452b 100644 --- a/src/governance.h +++ b/src/governance.h @@ -309,7 +309,7 @@ public: CGovernanceObject *FindGovernanceObject(const uint256& nHash); std::vector GetMatchingVotes(const uint256& nParentHash); - std::vector GetCurrentVotes(const uint256& nParentHash, const CTxIn& mnCollateralOutpointFilter); + std::vector GetCurrentVotes(const uint256& nParentHash, const COutPoint& mnCollateralOutpointFilter); std::vector GetAllNewerThan(int64_t nMoreThanTime); bool IsBudgetPaymentBlock(int nBlockHeight); diff --git a/src/instantx.cpp b/src/instantx.cpp index 24a328e5c..3af2cbaee 100644 --- a/src/instantx.cpp +++ b/src/instantx.cpp @@ -175,10 +175,10 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate) int nLockInputHeight = nPrevoutHeight + 4; - int n = mnodeman.GetMasternodeRank(activeMasternode.vin, nLockInputHeight, MIN_INSTANTSEND_PROTO_VERSION); + int n = mnodeman.GetMasternodeRank(activeMasternode.outpoint, nLockInputHeight, MIN_INSTANTSEND_PROTO_VERSION); if(n == -1) { - LogPrint("instantsend", "CInstantSend::Vote -- Can't calculate rank for masternode %s\n", activeMasternode.vin.prevout.ToStringShort()); + LogPrint("instantsend", "CInstantSend::Vote -- Can't calculate rank for masternode %s\n", activeMasternode.outpoint.ToStringShort()); ++itOutpointLock; continue; } @@ -200,7 +200,7 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate) if(itVoted != mapVotedOutpoints.end()) { BOOST_FOREACH(const uint256& hash, itVoted->second) { std::map::iterator it2 = mapTxLockCandidates.find(hash); - if(it2->second.HasMasternodeVoted(itOutpointLock->first, activeMasternode.vin.prevout)) { + if(it2->second.HasMasternodeVoted(itOutpointLock->first, activeMasternode.outpoint)) { // we already voted for this outpoint to be included either in the same tx or in a competing one, // skip it anyway fAlreadyVoted = true; @@ -216,7 +216,7 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate) } // we haven't voted for this outpoint yet, let's try to do this now - CTxLockVote vote(txHash, itOutpointLock->first, activeMasternode.vin.prevout); + CTxLockVote vote(txHash, itOutpointLock->first, activeMasternode.outpoint); if(!vote.Sign()) { LogPrintf("CInstantSend::Vote -- Failed to sign consensus vote\n"); @@ -993,9 +993,9 @@ bool CTxLockRequest::IsTimedOut() const bool CTxLockVote::IsValid(CNode* pnode) const { - if(!mnodeman.Has(CTxIn(outpointMasternode))) { + if(!mnodeman.Has(outpointMasternode)) { LogPrint("instantsend", "CTxLockVote::IsValid -- Unknown masternode %s\n", outpointMasternode.ToStringShort()); - mnodeman.AskForMN(pnode, CTxIn(outpointMasternode)); + mnodeman.AskForMN(pnode, outpointMasternode); return false; } @@ -1022,7 +1022,7 @@ bool CTxLockVote::IsValid(CNode* pnode) const int nLockInputHeight = nPrevoutHeight + 4; - int n = mnodeman.GetMasternodeRank(CTxIn(outpointMasternode), nLockInputHeight, MIN_INSTANTSEND_PROTO_VERSION); + int n = mnodeman.GetMasternodeRank(outpointMasternode, nLockInputHeight, MIN_INSTANTSEND_PROTO_VERSION); if(n == -1) { //can be caused by past versions trying to vote with an invalid protocol @@ -1060,9 +1060,9 @@ bool CTxLockVote::CheckSignature() const std::string strError; std::string strMessage = txHash.ToString() + outpoint.ToStringShort(); - masternode_info_t infoMn = mnodeman.GetMasternodeInfo(CTxIn(outpointMasternode)); + masternode_info_t infoMn; - if(!infoMn.fInfoValid) { + if(!mnodeman.GetMasternodeInfo(outpointMasternode, infoMn)) { LogPrintf("CTxLockVote::CheckSignature -- Unknown Masternode: masternode=%s\n", outpointMasternode.ToString()); return false; } diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index ba1f899d2..f94d2ee3a 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -271,14 +271,14 @@ void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int nBlockH if(!mnpayments.GetBlockPayee(nBlockHeight, payee)) { // no masternode detected... int nCount = 0; - CMasternode *winningNode = mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount); - if(!winningNode) { + masternode_info_t mnInfo; + if(!mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount, mnInfo)) { // ...and we can't calculate it on our own LogPrintf("CMasternodePayments::FillBlockPayee -- Failed to detect masternode to pay\n"); return; } // fill payee with locally calculated winner and hope for the best - payee = GetScriptForDestination(winningNode->pubKeyCollateralAddress.GetID()); + payee = GetScriptForDestination(mnInfo.pubKeyCollateralAddress.GetID()); } // GET MASTERNODE PAYMENT VARIABLES SETUP @@ -373,11 +373,11 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand, return; } - masternode_info_t mnInfo = mnodeman.GetMasternodeInfo(vote.vinMasternode); - if(!mnInfo.fInfoValid) { + masternode_info_t mnInfo; + if(!mnodeman.GetMasternodeInfo(vote.vinMasternode.prevout, mnInfo)) { // mn was not found, so we can't check vote, some info is probably missing LogPrintf("MASTERNODEPAYMENTVOTE -- masternode is missing %s\n", vote.vinMasternode.prevout.ToStringShort()); - mnodeman.AskForMN(pfrom, vote.vinMasternode); + mnodeman.AskForMN(pfrom, vote.vinMasternode.prevout); return; } @@ -392,7 +392,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand, } // Either our info or vote info could be outdated. // In case our info is outdated, ask for an update, - mnodeman.AskForMN(pfrom, vote.vinMasternode); + mnodeman.AskForMN(pfrom, vote.vinMasternode.prevout); // but there is nothing we can do if vote info itself is outdated // (i.e. it was signed by a mn which changed its key), // so just quit here. @@ -654,13 +654,13 @@ void CMasternodePayments::CheckAndRemove() bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::string& strError) { - CMasternode* pmn = mnodeman.Find(vinMasternode); + masternode_info_t mnInfo; - if(!pmn) { + if(!mnodeman.GetMasternodeInfo(vinMasternode.prevout, mnInfo)) { strError = strprintf("Unknown Masternode: prevout=%s", vinMasternode.prevout.ToStringShort()); // Only ask if we are already synced and still have no idea about that Masternode if(masternodeSync.IsMasternodeListSynced()) { - mnodeman.AskForMN(pnode, vinMasternode); + mnodeman.AskForMN(pnode, vinMasternode.prevout); } return false; @@ -675,8 +675,8 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s nMinRequiredProtocol = MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1; } - if(pmn->nProtocolVersion < nMinRequiredProtocol) { - strError = strprintf("Masternode protocol is too old: nProtocolVersion=%d, nMinRequiredProtocol=%d", pmn->nProtocolVersion, nMinRequiredProtocol); + if(mnInfo.nProtocolVersion < nMinRequiredProtocol) { + strError = strprintf("Masternode protocol is too old: nProtocolVersion=%d, nMinRequiredProtocol=%d", mnInfo.nProtocolVersion, nMinRequiredProtocol); return false; } @@ -684,7 +684,7 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s // Regular clients (miners included) need to verify masternode rank for future block votes only. if(!fMasterNode && nBlockHeight < nValidationHeight) return true; - int nRank = mnodeman.GetMasternodeRank(vinMasternode, nBlockHeight - 101, nMinRequiredProtocol, false); + int nRank = mnodeman.GetMasternodeRank(vinMasternode.prevout, nBlockHeight - 101, nMinRequiredProtocol, false); if(nRank == -1) { LogPrint("mnpayments", "CMasternodePaymentVote::IsValid -- Can't calculate rank for masternode %s\n", @@ -720,7 +720,7 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight) // if we have not enough data about masternodes. if(!masternodeSync.IsMasternodeListSynced()) return false; - int nRank = mnodeman.GetMasternodeRank(activeMasternode.vin, nBlockHeight - 101, GetMinMasternodePaymentsProto(), false); + int nRank = mnodeman.GetMasternodeRank(activeMasternode.outpoint, nBlockHeight - 101, GetMinMasternodePaymentsProto(), false); if (nRank == -1) { LogPrint("mnpayments", "CMasternodePayments::ProcessBlock -- Unknown Masternode\n"); @@ -735,23 +735,23 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight) // LOCATE THE NEXT MASTERNODE WHICH SHOULD BE PAID - LogPrintf("CMasternodePayments::ProcessBlock -- Start: nBlockHeight=%d, masternode=%s\n", nBlockHeight, activeMasternode.vin.prevout.ToStringShort()); + LogPrintf("CMasternodePayments::ProcessBlock -- Start: nBlockHeight=%d, masternode=%s\n", nBlockHeight, activeMasternode.outpoint.ToStringShort()); // pay to the oldest MN that still had no payment but its input is old enough and it was active long enough int nCount = 0; - CMasternode *pmn = mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount); + masternode_info_t mnInfo; - if (pmn == NULL) { + if (!mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount, mnInfo)) { LogPrintf("CMasternodePayments::ProcessBlock -- ERROR: Failed to find masternode to pay\n"); return false; } - LogPrintf("CMasternodePayments::ProcessBlock -- Masternode found by GetNextMasternodeInQueueForPayment(): %s\n", pmn->vin.prevout.ToStringShort()); + LogPrintf("CMasternodePayments::ProcessBlock -- Masternode found by GetNextMasternodeInQueueForPayment(): %s\n", mnInfo.vin.prevout.ToStringShort()); - CScript payee = GetScriptForDestination(pmn->pubKeyCollateralAddress.GetID()); + CScript payee = GetScriptForDestination(mnInfo.pubKeyCollateralAddress.GetID()); - CMasternodePaymentVote voteNew(activeMasternode.vin, nBlockHeight, payee); + CMasternodePaymentVote voteNew(activeMasternode.outpoint, nBlockHeight, payee); CTxDestination address1; ExtractDestination(payee, address1); diff --git a/src/masternode-payments.h b/src/masternode-payments.h index bb4417406..fdb0829fe 100644 --- a/src/masternode-payments.h +++ b/src/masternode-payments.h @@ -122,8 +122,8 @@ public: vchSig() {} - CMasternodePaymentVote(CTxIn vinMasternode, int nBlockHeight, CScript payee) : - vinMasternode(vinMasternode), + CMasternodePaymentVote(COutPoint outpointMasternode, int nBlockHeight, CScript payee) : + vinMasternode(outpointMasternode), nBlockHeight(nBlockHeight), payee(payee), vchSig() diff --git a/src/masternode.cpp b/src/masternode.cpp index b21668169..63e12f69e 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -20,9 +20,9 @@ CMasternode::CMasternode() : fAllowMixingTx(true) {} -CMasternode::CMasternode(CService addr, CTxIn vin, CPubKey pubKeyCollateralAddress, CPubKey pubKeyMasternode, int nProtocolVersionIn) : +CMasternode::CMasternode(CService addr, COutPoint outpoint, CPubKey pubKeyCollateralAddress, CPubKey pubKeyMasternode, int nProtocolVersionIn) : masternode_info_t{ MASTERNODE_ENABLED, nProtocolVersionIn, GetAdjustedTime(), - vin, addr, pubKeyCollateralAddress, pubKeyMasternode}, + outpoint, addr, pubKeyCollateralAddress, pubKeyMasternode}, fAllowMixingTx(true) {} @@ -40,7 +40,7 @@ CMasternode::CMasternode(const CMasternode& other) : CMasternode::CMasternode(const CMasternodeBroadcast& mnb) : masternode_info_t{ mnb.nActiveState, mnb.nProtocolVersion, mnb.sigTime, - mnb.vin, mnb.addr, mnb.pubKeyCollateralAddress, mnb.pubKeyMasternode, + mnb.vin.prevout, mnb.addr, mnb.pubKeyCollateralAddress, mnb.pubKeyMasternode, mnb.sigTime /*nTimeLastWatchdogVote*/}, lastPing(mnb.lastPing), vchSig(mnb.vchSig), @@ -104,26 +104,26 @@ arith_uint256 CMasternode::CalculateScore(const uint256& blockHash) return (hash3 > hash2 ? hash3 - hash2 : hash2 - hash3); } -CMasternode::CollateralStatus CMasternode::CheckCollateral(CTxIn vin) +CMasternode::CollateralStatus CMasternode::CheckCollateral(const COutPoint& outpoint) { int nHeight; - return CheckCollateral(vin, nHeight); + return CheckCollateral(outpoint, nHeight); } -CMasternode::CollateralStatus CMasternode::CheckCollateral(CTxIn vin, int& nHeight) +CMasternode::CollateralStatus CMasternode::CheckCollateral(const COutPoint& outpoint, int& nHeightRet) { AssertLockHeld(cs_main); CCoins coins; - if(!GetUTXOCoins(vin.prevout, coins)) { + if(!GetUTXOCoins(outpoint, coins)) { return COLLATERAL_UTXO_NOT_FOUND; } - if(coins.vout[vin.prevout.n].nValue != 1000 * COIN) { + if(coins.vout[outpoint.n].nValue != 1000 * COIN) { return COLLATERAL_INVALID_AMOUNT; } - nHeight = coins.nHeight; + nHeightRet = coins.nHeight; return COLLATERAL_OK; } @@ -146,7 +146,7 @@ void CMasternode::Check(bool fForce) TRY_LOCK(cs_main, lockMain); if(!lockMain) return; - CollateralStatus err = CheckCollateral(vin); + CollateralStatus err = CheckCollateral(vin.prevout); if (err == COLLATERAL_UTXO_NOT_FOUND) { nActiveState = MASTERNODE_OUTPOINT_SPENT; LogPrint("masternode", "CMasternode::Check -- Failed to find Masternode UTXO, masternode=%s\n", vin.prevout.ToStringShort()); @@ -349,7 +349,7 @@ void CMasternode::UpdateLastPaid(const CBlockIndex *pindex, int nMaxBlocksToScan bool CMasternodeBroadcast::Create(std::string strService, std::string strKeyMasternode, std::string strTxHash, std::string strOutputIndex, std::string& strErrorRet, CMasternodeBroadcast &mnbRet, bool fOffline) { - CTxIn txin; + COutPoint outpoint; CPubKey pubKeyCollateralAddressNew; CKey keyCollateralAddressNew; CPubKey pubKeyMasternodeNew; @@ -369,8 +369,8 @@ bool CMasternodeBroadcast::Create(std::string strService, std::string strKeyMast if (!CMessageSigner::GetKeysFromSecret(strKeyMasternode, keyMasternodeNew, pubKeyMasternodeNew)) return Log(strprintf("Invalid masternode key %s", strKeyMasternode)); - if (!pwalletMain->GetMasternodeVinAndKeys(txin, pubKeyCollateralAddressNew, keyCollateralAddressNew, strTxHash, strOutputIndex)) - return Log(strprintf("Could not allocate txin %s:%s for masternode %s", strTxHash, strOutputIndex, strService)); + if (!pwalletMain->GetMasternodeOutpointAndKeys(outpoint, pubKeyCollateralAddressNew, keyCollateralAddressNew, strTxHash, strOutputIndex)) + return Log(strprintf("Could not allocate outpoint %s:%s for masternode %s", strTxHash, strOutputIndex, strService)); CService service; if (!Lookup(strService.c_str(), service, 0, false)) @@ -382,10 +382,10 @@ bool CMasternodeBroadcast::Create(std::string strService, std::string strKeyMast } else if (service.GetPort() == mainnetDefaultPort) return Log(strprintf("Invalid port %u for masternode %s, %d is the only supported on mainnet.", service.GetPort(), strService, mainnetDefaultPort)); - return Create(txin, service, keyCollateralAddressNew, pubKeyCollateralAddressNew, keyMasternodeNew, pubKeyMasternodeNew, strErrorRet, mnbRet); + return Create(outpoint, service, keyCollateralAddressNew, pubKeyCollateralAddressNew, keyMasternodeNew, pubKeyMasternodeNew, strErrorRet, mnbRet); } -bool CMasternodeBroadcast::Create(CTxIn txin, CService service, CKey keyCollateralAddressNew, CPubKey pubKeyCollateralAddressNew, CKey keyMasternodeNew, CPubKey pubKeyMasternodeNew, std::string &strErrorRet, CMasternodeBroadcast &mnbRet) +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) { // wait for reindex and/or import to finish if (fImporting || fReindex) return false; @@ -402,18 +402,18 @@ bool CMasternodeBroadcast::Create(CTxIn txin, CService service, CKey keyCollater return false; }; - CMasternodePing mnp(txin); + CMasternodePing mnp(outpoint); if (!mnp.Sign(keyMasternodeNew, pubKeyMasternodeNew)) - return Log(strprintf("Failed to sign ping, masternode=%s", txin.prevout.ToStringShort())); + return Log(strprintf("Failed to sign ping, masternode=%s", outpoint.ToStringShort())); - mnbRet = CMasternodeBroadcast(service, txin, pubKeyCollateralAddressNew, pubKeyMasternodeNew, PROTOCOL_VERSION); + mnbRet = CMasternodeBroadcast(service, outpoint, pubKeyCollateralAddressNew, pubKeyMasternodeNew, PROTOCOL_VERSION); if (!mnbRet.IsValidNetAddr()) - return Log(strprintf("Invalid IP address, masternode=%s", txin.prevout.ToStringShort())); + return Log(strprintf("Invalid IP address, masternode=%s", outpoint.ToStringShort())); mnbRet.lastPing = mnp; if (!mnbRet.Sign(keyCollateralAddressNew)) - return Log(strprintf("Failed to sign broadcast, masternode=%s", txin.prevout.ToStringShort())); + return Log(strprintf("Failed to sign broadcast, masternode=%s", outpoint.ToStringShort())); return true; } @@ -535,7 +535,7 @@ bool CMasternodeBroadcast::CheckOutpoint(int& nDos) { // we are a masternode with the same vin (i.e. already activated) and this mnb is ours (matches our Masternode privkey) // so nothing to do here for us - if(fMasterNode && vin.prevout == activeMasternode.vin.prevout && pubKeyMasternode == activeMasternode.pubKeyMasternode) { + if(fMasterNode && vin.prevout == activeMasternode.outpoint && pubKeyMasternode == activeMasternode.pubKeyMasternode) { return false; } @@ -554,7 +554,7 @@ bool CMasternodeBroadcast::CheckOutpoint(int& nDos) } int nHeight; - CollateralStatus err = CheckCollateral(vin, nHeight); + CollateralStatus err = CheckCollateral(vin.prevout, nHeight); if (err == COLLATERAL_UTXO_NOT_FOUND) { LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Failed to find Masternode UTXO, masternode=%s\n", vin.prevout.ToStringShort()); return false; @@ -606,7 +606,7 @@ bool CMasternodeBroadcast::CheckOutpoint(int& nDos) return true; } -bool CMasternodeBroadcast::Sign(CKey& keyCollateralAddress) +bool CMasternodeBroadcast::Sign(const CKey& keyCollateralAddress) { std::string strError; std::string strMessage; @@ -657,17 +657,17 @@ void CMasternodeBroadcast::Relay() g_connman->RelayInv(inv); } -CMasternodePing::CMasternodePing(CTxIn& vinNew) +CMasternodePing::CMasternodePing(const COutPoint& outpoint) { LOCK(cs_main); if (!chainActive.Tip() || chainActive.Height() < 12) return; - vin = vinNew; + vin = CTxIn(outpoint); blockHash = chainActive[chainActive.Height() - 12]->GetBlockHash(); sigTime = GetAdjustedTime(); } -bool CMasternodePing::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode) +bool CMasternodePing::Sign(const CKey& keyMasternode, const CPubKey& pubKeyMasternode) { std::string strError; std::string strMasterNodeSignMessage; diff --git a/src/masternode.h b/src/masternode.h index d0c973a9c..4c059f635 100644 --- a/src/masternode.h +++ b/src/masternode.h @@ -41,7 +41,7 @@ public: CMasternodePing() = default; - CMasternodePing(CTxIn& vinNew); + CMasternodePing(const COutPoint& outpoint); ADD_SERIALIZE_METHODS; @@ -71,7 +71,7 @@ public: bool IsExpired() const { return GetAdjustedTime() - sigTime > MASTERNODE_NEW_START_REQUIRED_SECONDS; } - bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode); + bool Sign(const CKey& keyMasternode, const CPubKey& pubKeyMasternode); bool CheckSignature(CPubKey& pubKeyMasternode, int &nDos); bool SimpleCheck(int& nDos); bool CheckAndUpdate(CMasternode* pmn, bool fFromNewBroadcast, int& nDos); @@ -98,11 +98,11 @@ struct masternode_info_t nActiveState{activeState}, nProtocolVersion{protoVer}, sigTime{sTime} {} masternode_info_t(int activeState, int protoVer, int64_t sTime, - CTxIn const& vin, CService const& addr, + COutPoint const& outpoint, CService const& addr, CPubKey const& pkCollAddr, CPubKey const& pkMN, int64_t tWatchdogV = 0) : nActiveState{activeState}, nProtocolVersion{protoVer}, sigTime{sTime}, - vin{vin}, addr{addr}, + vin{outpoint}, addr{addr}, pubKeyCollateralAddress{pkCollAddr}, pubKeyMasternode{pkMN}, nTimeLastWatchdogVote{tWatchdogV} {} @@ -168,7 +168,7 @@ public: CMasternode(); CMasternode(const CMasternode& other); CMasternode(const CMasternodeBroadcast& mnb); - CMasternode(CService addrNew, CTxIn vinNew, CPubKey pubKeyCollateralAddressNew, CPubKey pubKeyMasternodeNew, int nProtocolVersionIn); + CMasternode(CService addrNew, COutPoint outpointNew, CPubKey pubKeyCollateralAddressNew, CPubKey pubKeyMasternodeNew, int nProtocolVersionIn); ADD_SERIALIZE_METHODS; @@ -202,8 +202,8 @@ public: bool UpdateFromNewBroadcast(CMasternodeBroadcast& mnb); - static CollateralStatus CheckCollateral(CTxIn vin); - static CollateralStatus CheckCollateral(CTxIn vin, int& nHeight); + static CollateralStatus CheckCollateral(const COutPoint& outpoint); + static CollateralStatus CheckCollateral(const COutPoint& outpoint, int& nHeightRet); void Check(bool fForce = false); bool IsBroadcastedWithin(int nSeconds) { return GetAdjustedTime() - sigTime < nSeconds; } @@ -316,8 +316,8 @@ public: CMasternodeBroadcast() : CMasternode(), fRecovery(false) {} CMasternodeBroadcast(const CMasternode& mn) : CMasternode(mn), fRecovery(false) {} - CMasternodeBroadcast(CService addrNew, CTxIn vinNew, CPubKey pubKeyCollateralAddressNew, CPubKey pubKeyMasternodeNew, int nProtocolVersionIn) : - CMasternode(addrNew, vinNew, pubKeyCollateralAddressNew, pubKeyMasternodeNew, nProtocolVersionIn), fRecovery(false) {} + CMasternodeBroadcast(CService addrNew, COutPoint outpointNew, CPubKey pubKeyCollateralAddressNew, CPubKey pubKeyMasternodeNew, int nProtocolVersionIn) : + CMasternode(addrNew, outpointNew, pubKeyCollateralAddressNew, pubKeyMasternodeNew, nProtocolVersionIn), fRecovery(false) {} ADD_SERIALIZE_METHODS; @@ -343,14 +343,14 @@ public: } /// Create Masternode broadcast, needs to be relayed manually after that - static bool Create(CTxIn vin, CService service, CKey keyCollateralAddressNew, CPubKey pubKeyCollateralAddressNew, CKey keyMasternodeNew, CPubKey pubKeyMasternodeNew, std::string &strErrorRet, CMasternodeBroadcast &mnbRet); + 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); static bool Create(std::string strService, std::string strKey, std::string strTxHash, std::string strOutputIndex, std::string& strErrorRet, CMasternodeBroadcast &mnbRet, bool fOffline = false); bool SimpleCheck(int& nDos); bool Update(CMasternode* pmn, int& nDos); bool CheckOutpoint(int& nDos); - bool Sign(CKey& keyCollateralAddress); + bool Sign(const CKey& keyCollateralAddress); bool CheckSignature(int& nDos); void Relay(); }; diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index 068a874e5..7cd3f77f0 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -16,7 +16,7 @@ /** Masternode manager */ CMasternodeMan mnodeman; -const std::string CMasternodeMan::SERIALIZATION_VERSION_STRING = "CMasternodeMan-Version-5"; +const std::string CMasternodeMan::SERIALIZATION_VERSION_STRING = "CMasternodeMan-Version-6"; struct CompareLastPaidBlock { @@ -48,7 +48,7 @@ struct CompareByAddr CMasternodeMan::CMasternodeMan() : cs(), - vMasternodes(), + mapMasternodes(), mAskedUsForMasternodeList(), mWeAskedForMasternodeList(), mWeAskedForMasternodeListEntry(), @@ -69,21 +69,21 @@ bool CMasternodeMan::Add(CMasternode &mn) { LOCK(cs); - if (Has(mn.vin)) return false; + if (Has(mn.vin.prevout)) return false; LogPrint("masternode", "CMasternodeMan::Add -- Adding new Masternode: addr=%s, %i now\n", mn.addr.ToString(), size() + 1); - vMasternodes.push_back(mn); + mapMasternodes[mn.vin.prevout] = mn; fMasternodesAdded = true; return true; } -void CMasternodeMan::AskForMN(CNode* pnode, const CTxIn &vin) +void CMasternodeMan::AskForMN(CNode* pnode, const COutPoint& outpoint) { if(!pnode) return; LOCK(cs); - std::map >::iterator it1 = mWeAskedForMasternodeListEntry.find(vin.prevout); + std::map >::iterator it1 = mWeAskedForMasternodeListEntry.find(outpoint); if (it1 != mWeAskedForMasternodeListEntry.end()) { std::map::iterator it2 = it1->second.find(pnode->addr); if (it2 != it1->second.end()) { @@ -92,18 +92,44 @@ void CMasternodeMan::AskForMN(CNode* pnode, const CTxIn &vin) return; } // we asked this node for this outpoint but it's ok to ask again already - LogPrintf("CMasternodeMan::AskForMN -- Asking same peer %s for missing masternode entry again: %s\n", pnode->addr.ToString(), vin.prevout.ToStringShort()); + LogPrintf("CMasternodeMan::AskForMN -- Asking same peer %s for missing masternode entry again: %s\n", pnode->addr.ToString(), outpoint.ToStringShort()); } else { // we already asked for this outpoint but not this node - LogPrintf("CMasternodeMan::AskForMN -- Asking new peer %s for missing masternode entry: %s\n", pnode->addr.ToString(), vin.prevout.ToStringShort()); + LogPrintf("CMasternodeMan::AskForMN -- Asking new peer %s for missing masternode entry: %s\n", pnode->addr.ToString(), outpoint.ToStringShort()); } } else { // we never asked any node for this outpoint - LogPrintf("CMasternodeMan::AskForMN -- Asking peer %s for missing masternode entry for the first time: %s\n", pnode->addr.ToString(), vin.prevout.ToStringShort()); + LogPrintf("CMasternodeMan::AskForMN -- Asking peer %s for missing masternode entry for the first time: %s\n", pnode->addr.ToString(), outpoint.ToStringShort()); } - mWeAskedForMasternodeListEntry[vin.prevout][pnode->addr] = GetTime() + DSEG_UPDATE_SECONDS; + mWeAskedForMasternodeListEntry[outpoint][pnode->addr] = GetTime() + DSEG_UPDATE_SECONDS; - g_connman->PushMessage(pnode, NetMsgType::DSEG, vin); + g_connman->PushMessage(pnode, NetMsgType::DSEG, CTxIn(outpoint)); +} + +bool CMasternodeMan::AllowMixing(const COutPoint &outpoint) +{ + LOCK(cs); + CMasternode* pmn = Find(outpoint); + if (!pmn) { + return false; + } + nDsqCount++; + pmn->nLastDsq = nDsqCount; + pmn->fAllowMixingTx = true; + + return true; +} + +bool CMasternodeMan::DisallowMixing(const COutPoint &outpoint) +{ + LOCK(cs); + CMasternode* pmn = Find(outpoint); + if (!pmn) { + return false; + } + pmn->fAllowMixingTx = false; + + return true; } void CMasternodeMan::Check() @@ -112,8 +138,8 @@ void CMasternodeMan::Check() LogPrint("masternode", "CMasternodeMan::Check -- nLastWatchdogVoteTime=%d, IsWatchdogActive()=%d\n", nLastWatchdogVoteTime, IsWatchdogActive()); - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - mn.Check(); + for (auto& mnpair : mapMasternodes) { + mnpair.second.Check(); } } @@ -131,29 +157,29 @@ void CMasternodeMan::CheckAndRemove() Check(); // Remove spent masternodes, prepare structures and make requests to reasure the state of inactive ones - std::vector::iterator it = vMasternodes.begin(); std::vector > vecMasternodeRanks; // ask for up to MNB_RECOVERY_MAX_ASK_ENTRIES masternode entries at a time int nAskForMnbRecovery = MNB_RECOVERY_MAX_ASK_ENTRIES; - while(it != vMasternodes.end()) { - CMasternodeBroadcast mnb = CMasternodeBroadcast(*it); + std::map::iterator it = mapMasternodes.begin(); + while (it != mapMasternodes.end()) { + CMasternodeBroadcast mnb = CMasternodeBroadcast(it->second); uint256 hash = mnb.GetHash(); // If collateral was spent ... - if ((*it).IsOutpointSpent()) { - LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- Removing Masternode: %s addr=%s %i now\n", (*it).GetStateString(), (*it).addr.ToString(), size() - 1); + if (it->second.IsOutpointSpent()) { + LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- Removing Masternode: %s addr=%s %i now\n", it->second.GetStateString(), it->second.addr.ToString(), size() - 1); // erase all of the broadcasts we've seen from this txin, ... mapSeenMasternodeBroadcast.erase(hash); - mWeAskedForMasternodeListEntry.erase((*it).vin.prevout); + mWeAskedForMasternodeListEntry.erase(it->first); // and finally remove it from the list - it->FlagGovernanceItemsAsDirty(); - it = vMasternodes.erase(it); + it->second.FlagGovernanceItemsAsDirty(); + mapMasternodes.erase(it++); fMasternodesRemoved = true; } else { bool fAsk = (nAskForMnbRecovery > 0) && masternodeSync.IsSynced() && - it->IsNewStartRequired() && + it->second.IsNewStartRequired() && !IsMnbRecoveryRequested(hash); if(fAsk) { // this mn is in a non-recoverable state and we haven't asked other nodes yet @@ -167,7 +193,7 @@ void CMasternodeMan::CheckAndRemove() // ask first MNB_RECOVERY_QUORUM_TOTAL masternodes we can connect to and we haven't asked recently for(int i = 0; setRequested.size() < MNB_RECOVERY_QUORUM_TOTAL && i < (int)vecMasternodeRanks.size(); i++) { // avoid banning - if(mWeAskedForMasternodeListEntry.count(it->vin.prevout) && mWeAskedForMasternodeListEntry[it->vin.prevout].count(vecMasternodeRanks[i].second.addr)) continue; + if(mWeAskedForMasternodeListEntry.count(it->first) && mWeAskedForMasternodeListEntry[it->first].count(vecMasternodeRanks[i].second.addr)) continue; // didn't ask recently, ok to ask now CService addr = vecMasternodeRanks[i].second.addr; setRequested.insert(addr); @@ -175,7 +201,7 @@ void CMasternodeMan::CheckAndRemove() fAskedForMnbRecovery = true; } if(fAskedForMnbRecovery) { - LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- Recovery initiated, masternode=%s\n", it->vin.prevout.ToStringShort()); + LogPrint("masternode", "CMasternodeMan::CheckAndRemove -- Recovery initiated, masternode=%s\n", it->first.ToStringShort()); nAskForMnbRecovery--; } // wait for mnb recovery replies for MNB_RECOVERY_WAIT_SECONDS seconds @@ -303,7 +329,7 @@ void CMasternodeMan::CheckAndRemove() void CMasternodeMan::Clear() { LOCK(cs); - vMasternodes.clear(); + mapMasternodes.clear(); mAskedUsForMasternodeList.clear(); mWeAskedForMasternodeList.clear(); mWeAskedForMasternodeListEntry.clear(); @@ -319,8 +345,8 @@ int CMasternodeMan::CountMasternodes(int nProtocolVersion) int nCount = 0; nProtocolVersion = nProtocolVersion == -1 ? mnpayments.GetMinMasternodePaymentsProto() : nProtocolVersion; - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - if(mn.nProtocolVersion < nProtocolVersion) continue; + for (auto& mnpair : mapMasternodes) { + if(mnpair.second.nProtocolVersion < nProtocolVersion) continue; nCount++; } @@ -333,8 +359,8 @@ int CMasternodeMan::CountEnabled(int nProtocolVersion) int nCount = 0; nProtocolVersion = nProtocolVersion == -1 ? mnpayments.GetMinMasternodePaymentsProto() : nProtocolVersion; - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - if(mn.nProtocolVersion < nProtocolVersion || !mn.IsEnabled()) continue; + for (auto& mnpair : mapMasternodes) { + if(mnpair.second.nProtocolVersion < nProtocolVersion || !mnpair.second.IsEnabled()) continue; nCount++; } @@ -347,10 +373,10 @@ int CMasternodeMan::CountByIP(int nNetworkType) LOCK(cs); int nNodeCount = 0; - BOOST_FOREACH(CMasternode& mn, vMasternodes) - if ((nNetworkType == NET_IPV4 && mn.addr.IsIPv4()) || - (nNetworkType == NET_TOR && mn.addr.IsTor()) || - (nNetworkType == NET_IPV6 && mn.addr.IsIPv6())) { + for (auto& mnpair : mapMasternodes) + if ((nNetworkType == NET_IPV4 && mnpair.second.addr.IsIPv4()) || + (nNetworkType == NET_TOR && mnpair.second.addr.IsTor()) || + (nNetworkType == NET_IPV6 && mnpair.second.addr.IsIPv6())) { nNodeCount++; } @@ -379,117 +405,76 @@ void CMasternodeMan::DsegUpdate(CNode* pnode) LogPrint("masternode", "CMasternodeMan::DsegUpdate -- asked %s for the list\n", pnode->addr.ToString()); } -CMasternode* CMasternodeMan::Find(const CScript &payee) +CMasternode* CMasternodeMan::Find(const COutPoint &outpoint) { LOCK(cs); - - BOOST_FOREACH(CMasternode& mn, vMasternodes) - { - if(GetScriptForDestination(mn.pubKeyCollateralAddress.GetID()) == payee) - return &mn; - } - return NULL; + auto it = mapMasternodes.find(outpoint); + return it == mapMasternodes.end() ? NULL : &(it->second); } -CMasternode* CMasternodeMan::Find(const CTxIn &vin) -{ - LOCK(cs); - - BOOST_FOREACH(CMasternode& mn, vMasternodes) - { - if(mn.vin.prevout == vin.prevout) - return &mn; - } - return NULL; -} - -CMasternode* CMasternodeMan::Find(const CPubKey &pubKeyMasternode) -{ - LOCK(cs); - - BOOST_FOREACH(CMasternode& mn, vMasternodes) - { - if(mn.pubKeyMasternode == pubKeyMasternode) - return &mn; - } - return NULL; -} - -bool CMasternodeMan::Get(const CPubKey& pubKeyMasternode, CMasternode& masternode) +bool CMasternodeMan::Get(const COutPoint& outpoint, CMasternode& masternodeRet) { // Theses mutexes are recursive so double locking by the same thread is safe. LOCK(cs); - CMasternode* pMN = Find(pubKeyMasternode); - if(!pMN) { + auto it = mapMasternodes.find(outpoint); + if (it == mapMasternodes.end()) { return false; } - masternode = *pMN; + + masternodeRet = it->second; return true; } -bool CMasternodeMan::Get(const CTxIn& vin, CMasternode& masternode) +bool CMasternodeMan::GetMasternodeInfo(const COutPoint& outpoint, masternode_info_t& mnInfoRet) { - // Theses mutexes are recursive so double locking by the same thread is safe. LOCK(cs); - CMasternode* pMN = Find(vin); - if(!pMN) { + auto it = mapMasternodes.find(outpoint); + if (it == mapMasternodes.end()) { return false; } - masternode = *pMN; + mnInfoRet = it->second.GetInfo(); return true; } -masternode_info_t CMasternodeMan::GetMasternodeInfo(const CTxIn& vin) +bool CMasternodeMan::GetMasternodeInfo(const CPubKey& pubKeyMasternode, masternode_info_t& mnInfoRet) { - masternode_info_t info; LOCK(cs); - CMasternode* pMN = Find(vin); - if(!pMN) { - return info; + for (auto& mnpair : mapMasternodes) { + if (mnpair.second.pubKeyMasternode == pubKeyMasternode) { + mnInfoRet = mnpair.second.GetInfo(); + return true; + } } - info = pMN->GetInfo(); - return info; + return false; } -masternode_info_t CMasternodeMan::GetMasternodeInfo(const CPubKey& pubKeyMasternode) -{ - masternode_info_t info; - LOCK(cs); - CMasternode* pMN = Find(pubKeyMasternode); - if(!pMN) { - return info; - } - info = pMN->GetInfo(); - return info; -} - -bool CMasternodeMan::Has(const CTxIn& vin) +bool CMasternodeMan::Has(const COutPoint& outpoint) { LOCK(cs); - CMasternode* pMN = Find(vin); - return (pMN != NULL); + return mapMasternodes.find(outpoint) != mapMasternodes.end(); } // // Deterministically select the oldest/best masternode to pay on the network // -CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(bool fFilterSigTime, int& nCount) +bool CMasternodeMan::GetNextMasternodeInQueueForPayment(bool fFilterSigTime, int& nCountRet, masternode_info_t& mnInfoRet) { - return GetNextMasternodeInQueueForPayment(nCachedBlockHeight, fFilterSigTime, nCount); + return GetNextMasternodeInQueueForPayment(nCachedBlockHeight, fFilterSigTime, nCountRet, mnInfoRet); } -CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int& nCount) +bool CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int& nCountRet, masternode_info_t& mnInfoRet) { + mnInfoRet = masternode_info_t(); + nCountRet = 0; + if (!masternodeSync.IsWinnersListSynced()) { // without winner list we can't reliably find the next winner anyway - nCount = 0; - return NULL; + return false; } // Need LOCK2 here to ensure consistent locking order because the GetBlockHash call below locks cs_main LOCK2(cs_main,cs); - CMasternode *pBestMasternode = NULL; std::vector > vecMasternodeLastPaid; /* @@ -497,29 +482,30 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight */ int nMnCount = CountEnabled(); - BOOST_FOREACH(CMasternode &mn, vMasternodes) - { - if(!mn.IsValidForPayment()) continue; + + for (auto& mnpair : mapMasternodes) { + if(!mnpair.second.IsValidForPayment()) continue; //check protocol version - if(mn.nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto()) continue; + if(mnpair.second.nProtocolVersion < mnpayments.GetMinMasternodePaymentsProto()) continue; //it's in the list (up to 8 entries ahead of current block to allow propagation) -- so let's skip it - if(mnpayments.IsScheduled(mn, nBlockHeight)) continue; + if(mnpayments.IsScheduled(mnpair.second, nBlockHeight)) continue; //it's too new, wait for a cycle - if(fFilterSigTime && mn.sigTime + (nMnCount*2.6*60) > GetAdjustedTime()) continue; + if(fFilterSigTime && mnpair.second.sigTime + (nMnCount*2.6*60) > GetAdjustedTime()) continue; //make sure it has at least as many confirmations as there are masternodes - if(GetUTXOConfirmations(mn.vin.prevout) < nMnCount) continue; + if(GetUTXOConfirmations(mnpair.first) < nMnCount) continue; - vecMasternodeLastPaid.push_back(std::make_pair(mn.GetLastPaidBlock(), &mn)); + vecMasternodeLastPaid.push_back(std::make_pair(mnpair.second.GetLastPaidBlock(), &mnpair.second)); } - nCount = (int)vecMasternodeLastPaid.size(); + nCountRet = (int)vecMasternodeLastPaid.size(); //when the network is in the process of upgrading, don't penalize nodes that recently restarted - if(fFilterSigTime && nCount < nMnCount/3) return GetNextMasternodeInQueueForPayment(nBlockHeight, false, nCount); + if(fFilterSigTime && nCountRet < nMnCount/3) + return GetNextMasternodeInQueueForPayment(nBlockHeight, false, nCountRet, mnInfoRet); // Sort them low to high sort(vecMasternodeLastPaid.begin(), vecMasternodeLastPaid.end(), CompareLastPaidBlock()); @@ -527,7 +513,7 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight uint256 blockHash; if(!GetBlockHash(blockHash, nBlockHeight - 101)) { LogPrintf("CMasternode::GetNextMasternodeInQueueForPayment -- ERROR: GetBlockHash() failed at nBlockHeight %d\n", nBlockHeight - 101); - return NULL; + return false; } // Look at 1/10 of the oldest nodes (by last payment), calculate their scores and pay the best one // -- This doesn't look at who is being paid in the +8-10 blocks, allowing for double payments very rarely @@ -536,6 +522,7 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight int nTenthNetwork = nMnCount/10; int nCountTenth = 0; arith_uint256 nHighest = 0; + CMasternode *pBestMasternode = NULL; BOOST_FOREACH (PAIRTYPE(int, CMasternode*)& s, vecMasternodeLastPaid){ arith_uint256 nScore = s.second->CalculateScore(blockHash); if(nScore > nHighest){ @@ -545,10 +532,13 @@ CMasternode* CMasternodeMan::GetNextMasternodeInQueueForPayment(int nBlockHeight nCountTenth++; if(nCountTenth >= nTenthNetwork) break; } - return pBestMasternode; + if (pBestMasternode) { + mnInfoRet = pBestMasternode->GetInfo(); + } + return mnInfoRet.fInfoValid; } -masternode_info_t CMasternodeMan::FindRandomNotInVec(const std::vector &vecToExclude, int nProtocolVersion) +masternode_info_t CMasternodeMan::FindRandomNotInVec(const std::vector &vecToExclude, int nProtocolVersion) { LOCK(cs); @@ -562,8 +552,8 @@ masternode_info_t CMasternodeMan::FindRandomNotInVec(const std::vector &v // fill a vector of pointers std::vector vpMasternodesShuffled; - BOOST_FOREACH(CMasternode &mn, vMasternodes) { - vpMasternodesShuffled.push_back(&mn); + for (auto& mnpair : mapMasternodes) { + vpMasternodesShuffled.push_back(&mnpair.second); } InsecureRand insecureRand; @@ -575,8 +565,8 @@ masternode_info_t CMasternodeMan::FindRandomNotInVec(const std::vector &v BOOST_FOREACH(CMasternode* pmn, vpMasternodesShuffled) { if(pmn->nProtocolVersion < nProtocolVersion || !pmn->IsEnabled()) continue; fExclude = false; - BOOST_FOREACH(const CTxIn &txinToExclude, vecToExclude) { - if(pmn->vin.prevout == txinToExclude.prevout) { + BOOST_FOREACH(const COutPoint &outpointToExclude, vecToExclude) { + if(pmn->vin.prevout == outpointToExclude) { fExclude = true; break; } @@ -591,7 +581,7 @@ masternode_info_t CMasternodeMan::FindRandomNotInVec(const std::vector &v return masternode_info_t(); } -int CMasternodeMan::GetMasternodeRank(const CTxIn& vin, int nBlockHeight, int nMinProtocol, bool fOnlyActive) +int CMasternodeMan::GetMasternodeRank(const COutPoint& outpoint, int nBlockHeight, int nMinProtocol, bool fOnlyActive) { std::vector > vecMasternodeScores; @@ -602,17 +592,17 @@ int CMasternodeMan::GetMasternodeRank(const CTxIn& vin, int nBlockHeight, int nM LOCK(cs); // scan for winner - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - if(mn.nProtocolVersion < nMinProtocol) continue; + for (auto& mnpair : mapMasternodes) { + if(mnpair.second.nProtocolVersion < nMinProtocol) continue; if(fOnlyActive) { - if(!mn.IsEnabled()) continue; + if(!mnpair.second.IsEnabled()) continue; } else { - if(!mn.IsValidForPayment()) continue; + if(!mnpair.second.IsValidForPayment()) continue; } - int64_t nScore = mn.CalculateScore(blockHash).GetCompact(false); + int64_t nScore = mnpair.second.CalculateScore(blockHash).GetCompact(false); - vecMasternodeScores.push_back(std::make_pair(nScore, &mn)); + vecMasternodeScores.push_back(std::make_pair(nScore, &mnpair.second)); } sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareScoreMN()); @@ -620,7 +610,7 @@ int CMasternodeMan::GetMasternodeRank(const CTxIn& vin, int nBlockHeight, int nM int nRank = 0; BOOST_FOREACH (PAIRTYPE(int64_t, CMasternode*)& scorePair, vecMasternodeScores) { nRank++; - if(scorePair.second->vin.prevout == vin.prevout) return nRank; + if(scorePair.second->vin.prevout == outpoint) return nRank; } return -1; @@ -638,13 +628,13 @@ std::vector > CMasternodeMan::GetMasternodeRanks(int LOCK(cs); // scan for winner - BOOST_FOREACH(CMasternode& mn, vMasternodes) { + for (auto& mnpair : mapMasternodes) { - if(mn.nProtocolVersion < nMinProtocol || !mn.IsEnabled()) continue; + if(mnpair.second.nProtocolVersion < nMinProtocol || !mnpair.second.IsEnabled()) continue; - int64_t nScore = mn.CalculateScore(blockHash).GetCompact(false); + int64_t nScore = mnpair.second.CalculateScore(blockHash).GetCompact(false); - vecMasternodeScores.push_back(std::make_pair(nScore, &mn)); + vecMasternodeScores.push_back(std::make_pair(nScore, &mnpair.second)); } sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareScoreMN()); @@ -671,14 +661,14 @@ bool CMasternodeMan::GetMasternodeByRank(int nRank, int nBlockHeight, int nMinPr } // Fill scores - BOOST_FOREACH(CMasternode& mn, vMasternodes) { + for (auto& mnpair : mapMasternodes) { - if(mn.nProtocolVersion < nMinProtocol) continue; - if(fOnlyActive && !mn.IsEnabled()) continue; + if(mnpair.second.nProtocolVersion < nMinProtocol) continue; + if(fOnlyActive && !mnpair.second.IsEnabled()) continue; - int64_t nScore = mn.CalculateScore(blockHash).GetCompact(false); + int64_t nScore = mnpair.second.CalculateScore(blockHash).GetCompact(false); - vecMasternodeScores.push_back(std::make_pair(nScore, &mn)); + vecMasternodeScores.push_back(std::make_pair(nScore, &mnpair.second)); } sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareScoreMN()); @@ -702,7 +692,8 @@ void CMasternodeMan::ProcessMasternodeConnections() g_connman->ForEachNode(CConnman::AllNodes, [](CNode* pnode) { if(pnode->fMasternode) { - if(privateSendClient.infoMixingMasternode.fInfoValid && pnode->addr == privateSendClient.infoMixingMasternode.addr) return true; + if(privateSendClient.infoMixingMasternode.fInfoValid && pnode->addr == privateSendClient.infoMixingMasternode.addr) + return; LogPrintf("Closing Masternode connection: peer=%d, addr=%s\n", pnode->id, pnode->addr.ToString()); pnode->fDisconnect = true; } @@ -783,7 +774,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData LogPrint("masternode", "MNPING -- Masternode ping, masternode=%s new\n", mnp.vin.prevout.ToStringShort()); // see if we have this Masternode - CMasternode* pmn = mnodeman.Find(mnp.vin); + CMasternode* pmn = Find(mnp.vin.prevout); // if masternode uses sentinel ping instead of watchdog // we shoud update nTimeLastWatchdogVote here if sentinel @@ -807,7 +798,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData // something significant is broken or mn is unknown, // we might have to ask for a masternode entry once - AskForMN(pfrom, mnp.vin); + AskForMN(pfrom, mnp.vin.prevout); } else if (strCommand == NetMsgType::DSEG) { //Get Masternode list or specific entry // Ignore such requests until we are fully synced. @@ -840,23 +831,23 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData int nInvCount = 0; - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - if (vin != CTxIn() && vin != mn.vin) continue; // asked for specific vin but we are not there yet - if (mn.addr.IsRFC1918() || mn.addr.IsLocal()) continue; // do not send local network masternode - if (mn.IsUpdateRequired()) continue; // do not send outdated masternodes + for (auto& mnpair : mapMasternodes) { + if (vin != CTxIn() && vin != mnpair.second.vin) continue; // asked for specific vin but we are not there yet + if (mnpair.second.addr.IsRFC1918() || mnpair.second.addr.IsLocal()) continue; // do not send local network masternode + if (mnpair.second.IsUpdateRequired()) continue; // do not send outdated masternodes - LogPrint("masternode", "DSEG -- Sending Masternode entry: masternode=%s addr=%s\n", mn.vin.prevout.ToStringShort(), mn.addr.ToString()); - CMasternodeBroadcast mnb = CMasternodeBroadcast(mn); + LogPrint("masternode", "DSEG -- Sending Masternode entry: masternode=%s addr=%s\n", mnpair.first.ToStringShort(), mnpair.second.addr.ToString()); + CMasternodeBroadcast mnb = CMasternodeBroadcast(mnpair.second); uint256 hash = mnb.GetHash(); pfrom->PushInventory(CInv(MSG_MASTERNODE_ANNOUNCE, hash)); - pfrom->PushInventory(CInv(MSG_MASTERNODE_PING, mn.lastPing.GetHash())); + pfrom->PushInventory(CInv(MSG_MASTERNODE_PING, mnpair.second.lastPing.GetHash())); nInvCount++; if (!mapSeenMasternodeBroadcast.count(hash)) { mapSeenMasternodeBroadcast.insert(std::make_pair(hash, std::make_pair(GetTime(), mnb))); } - if (vin == mn.vin) { + if (vin.prevout == mnpair.first) { LogPrintf("DSEG -- Sent 1 Masternode inv to peer %d\n", pfrom->id); return; } @@ -895,7 +886,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData void CMasternodeMan::DoFullVerificationStep() { - if(activeMasternode.vin == CTxIn()) return; + if(activeMasternode.outpoint == COutPoint()) return; if(!masternodeSync.IsSynced()) return; std::vector > vecMasternodeRanks = GetMasternodeRanks(nCachedBlockHeight - 1, MIN_POSE_PROTO_VERSION); @@ -917,7 +908,7 @@ void CMasternodeMan::DoFullVerificationStep() (int)MAX_POSE_RANK); return; } - if(it->second.vin == activeMasternode.vin) { + if(it->second.vin.prevout == activeMasternode.outpoint) { nMyRank = it->first; LogPrint("masternode", "CMasternodeMan::DoFullVerificationStep -- Found self at rank %d/%d, verifying up to %d masternodes\n", nMyRank, nRanksTotal, (int)MAX_POSE_CONNECTIONS); @@ -935,8 +926,8 @@ void CMasternodeMan::DoFullVerificationStep() if(nOffset >= (int)vecMasternodeRanks.size()) return; std::vector vSortedByAddr; - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - vSortedByAddr.push_back(&mn); + for (auto& mnpair : mapMasternodes) { + vSortedByAddr.push_back(&mnpair.second); } sort(vSortedByAddr.begin(), vSortedByAddr.end(), CompareByAddr()); @@ -975,7 +966,7 @@ void CMasternodeMan::DoFullVerificationStep() void CMasternodeMan::CheckSameAddr() { - if(!masternodeSync.IsSynced() || vMasternodes.empty()) return; + if(!masternodeSync.IsSynced() || mapMasternodes.empty()) return; std::vector vBan; std::vector vSortedByAddr; @@ -986,8 +977,8 @@ void CMasternodeMan::CheckSameAddr() CMasternode* pprevMasternode = NULL; CMasternode* pverifiedMasternode = NULL; - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - vSortedByAddr.push_back(&mn); + for (auto& mnpair : mapMasternodes) { + vSortedByAddr.push_back(&mnpair.second); } sort(vSortedByAddr.begin(), vSortedByAddr.end(), CompareByAddr()); @@ -1137,24 +1128,23 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m CMasternode* prealMasternode = NULL; std::vector vpMasternodesToBan; - std::vector::iterator it = vMasternodes.begin(); std::string strMessage1 = strprintf("%s%d%s", pnode->addr.ToString(false), mnv.nonce, blockHash.ToString()); - while(it != vMasternodes.end()) { - if(CAddress(it->addr, NODE_NETWORK) == pnode->addr) { - if(CMessageSigner::VerifyMessage(it->pubKeyMasternode, mnv.vchSig1, strMessage1, strError)) { + for (auto& mnpair : mapMasternodes) { + if(CAddress(mnpair.second.addr, NODE_NETWORK) == pnode->addr) { + if(CMessageSigner::VerifyMessage(mnpair.second.pubKeyMasternode, mnv.vchSig1, strMessage1, strError)) { // found it! - prealMasternode = &(*it); - if(!it->IsPoSeVerified()) { - it->DecreasePoSeBanScore(); + prealMasternode = &mnpair.second; + if(!mnpair.second.IsPoSeVerified()) { + mnpair.second.DecreasePoSeBanScore(); } netfulfilledman.AddFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-done"); // we can only broadcast it if we are an activated masternode - if(activeMasternode.vin == CTxIn()) continue; + if(activeMasternode.outpoint == COutPoint()) continue; // update ... - mnv.addr = it->addr; - mnv.vin1 = it->vin; - mnv.vin2 = activeMasternode.vin; + mnv.addr = mnpair.second.addr; + mnv.vin1 = mnpair.second.vin; + mnv.vin2 = CTxIn(activeMasternode.outpoint); std::string strMessage2 = strprintf("%s%d%s%s%s", mnv.addr.ToString(false), mnv.nonce, blockHash.ToString(), mnv.vin1.prevout.ToStringShort(), mnv.vin2.prevout.ToStringShort()); // ... and sign it @@ -1174,10 +1164,9 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m mnv.Relay(); } else { - vpMasternodesToBan.push_back(&(*it)); + vpMasternodesToBan.push_back(&mnpair.second); } } - ++it; } // no real masternode found?... if(!prealMasternode) { @@ -1233,7 +1222,7 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif return; } - int nRank = GetMasternodeRank(mnv.vin2, mnv.nBlockHeight, MIN_POSE_PROTO_VERSION); + int nRank = GetMasternodeRank(mnv.vin2.prevout, mnv.nBlockHeight, MIN_POSE_PROTO_VERSION); if (nRank == -1) { LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- Can't calculate rank for masternode %s\n", @@ -1254,13 +1243,13 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif std::string strMessage2 = strprintf("%s%d%s%s%s", mnv.addr.ToString(false), mnv.nonce, blockHash.ToString(), mnv.vin1.prevout.ToStringShort(), mnv.vin2.prevout.ToStringShort()); - CMasternode* pmn1 = Find(mnv.vin1); + CMasternode* pmn1 = Find(mnv.vin1.prevout); if(!pmn1) { LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- can't find masternode1 %s\n", mnv.vin1.prevout.ToStringShort()); return; } - CMasternode* pmn2 = Find(mnv.vin2); + CMasternode* pmn2 = Find(mnv.vin2.prevout); if(!pmn2) { LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- can't find masternode2 %s\n", mnv.vin2.prevout.ToStringShort()); return; @@ -1291,12 +1280,12 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif // increase ban score for everyone else with the same addr int nCount = 0; - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - if(mn.addr != mnv.addr || mn.vin.prevout == mnv.vin1.prevout) continue; - mn.IncreasePoSeBanScore(); + for (auto& mnpair : mapMasternodes) { + if(mnpair.second.addr != mnv.addr || mnpair.first == mnv.vin1.prevout) continue; + mnpair.second.IncreasePoSeBanScore(); nCount++; LogPrint("masternode", "CMasternodeMan::ProcessVerifyBroadcast -- increased PoSe ban score for %s addr %s, new score %d\n", - mn.vin.prevout.ToStringShort(), mn.addr.ToString(), mn.nPoSeBanScore); + mnpair.first.ToStringShort(), mnpair.second.addr.ToString(), mnpair.second.nPoSeBanScore); } LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- PoSe score incresed for %d fake masternodes, addr %s\n", nCount, pnode->addr.ToString()); @@ -1307,7 +1296,7 @@ std::string CMasternodeMan::ToString() const { std::ostringstream info; - info << "Masternodes: " << (int)vMasternodes.size() << + info << "Masternodes: " << (int)mapMasternodes.size() << ", peers who asked us for Masternode list: " << (int)mAskedUsForMasternodeList.size() << ", peers we asked for Masternode list: " << (int)mWeAskedForMasternodeList.size() << ", entries in Masternode list we asked for: " << (int)mWeAskedForMasternodeListEntry.size() << @@ -1324,7 +1313,7 @@ void CMasternodeMan::UpdateMasternodeList(CMasternodeBroadcast mnb) LogPrintf("CMasternodeMan::UpdateMasternodeList -- masternode=%s addr=%s\n", mnb.vin.prevout.ToStringShort(), mnb.addr.ToString()); - CMasternode* pmn = Find(mnb.vin); + CMasternode* pmn = Find(mnb.vin.prevout); if(pmn == NULL) { if(Add(mnb)) { masternodeSync.BumpAssetLastTime("CMasternodeMan::UpdateMasternodeList - new"); @@ -1390,7 +1379,7 @@ bool CMasternodeMan::CheckMnbAndUpdateMasternodeList(CNode* pfrom, CMasternodeBr } // search Masternode list - CMasternode* pmn = Find(mnb.vin); + CMasternode* pmn = Find(mnb.vin.prevout); if(pmn) { CMasternodeBroadcast mnbOld = mapSeenMasternodeBroadcast[CMasternodeBroadcast(*pmn).GetHash()].second; if(!mnb.Update(pmn, nDos)) { @@ -1435,7 +1424,7 @@ void CMasternodeMan::UpdateLastPaid(const CBlockIndex* pindex) { LOCK(cs); - if(fLiteMode || !masternodeSync.IsWinnersListSynced() || vMasternodes.empty()) return; + if(fLiteMode || !masternodeSync.IsWinnersListSynced() || mapMasternodes.empty()) return; static bool IsFirstRun = true; // Do full scan on first run or if we are not a masternode @@ -1445,34 +1434,21 @@ void CMasternodeMan::UpdateLastPaid(const CBlockIndex* pindex) // LogPrint("mnpayments", "CMasternodeMan::UpdateLastPaid -- nHeight=%d, nMaxBlocksToScanBack=%d, IsFirstRun=%s\n", // nCachedBlockHeight, nMaxBlocksToScanBack, IsFirstRun ? "true" : "false"); - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - mn.UpdateLastPaid(pindex, nMaxBlocksToScanBack); + for (auto& mnpair: mapMasternodes) { + mnpair.second.UpdateLastPaid(pindex, nMaxBlocksToScanBack); } IsFirstRun = false; } -bool CMasternodeMan::UpdateLastDsq(const CTxIn& vin) -{ - masternode_info_t info; - LOCK(cs); - CMasternode* pMN = Find(vin); - if(!pMN) - return false; - pMN->nLastDsq = nDsqCount; - pMN->fAllowMixingTx = true; - return true; -} - - -void CMasternodeMan::UpdateWatchdogVoteTime(const CTxIn& vin) +void CMasternodeMan::UpdateWatchdogVoteTime(const COutPoint& outpoint) { LOCK(cs); - CMasternode* pMN = Find(vin); - if(!pMN) { + CMasternode* pmn = Find(outpoint); + if(!pmn) { return; } - pMN->UpdateWatchdogVoteTime(); + pmn->UpdateWatchdogVoteTime(); nLastWatchdogVoteTime = GetTime(); } @@ -1483,91 +1459,60 @@ bool CMasternodeMan::IsWatchdogActive() return (GetTime() - nLastWatchdogVoteTime) <= MASTERNODE_WATCHDOG_MAX_SECONDS; } -bool CMasternodeMan::AddGovernanceVote(const CTxIn& vin, uint256 nGovernanceObjectHash) +bool CMasternodeMan::AddGovernanceVote(const COutPoint& outpoint, uint256 nGovernanceObjectHash) { LOCK(cs); - CMasternode* pMN = Find(vin); - if(!pMN) { + CMasternode* pmn = Find(outpoint); + if(!pmn) { return false; } - pMN->AddGovernanceVote(nGovernanceObjectHash); + pmn->AddGovernanceVote(nGovernanceObjectHash); return true; } void CMasternodeMan::RemoveGovernanceObject(uint256 nGovernanceObjectHash) { LOCK(cs); - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - mn.RemoveGovernanceObject(nGovernanceObjectHash); + for(auto& mnpair : mapMasternodes) { + mnpair.second.RemoveGovernanceObject(nGovernanceObjectHash); } } -void CMasternodeMan::CheckMasternode(const CTxIn& vin, bool fForce) -{ - LOCK(cs); - CMasternode* pMN = Find(vin); - if(!pMN) { - return; - } - pMN->Check(fForce); -} - void CMasternodeMan::CheckMasternode(const CPubKey& pubKeyMasternode, bool fForce) { LOCK(cs); - CMasternode* pMN = Find(pubKeyMasternode); - if(!pMN) { + for (auto& mnpair : mapMasternodes) { + if (mnpair.second.pubKeyMasternode == pubKeyMasternode) { + mnpair.second.Check(fForce); + return; + } + } +} + +bool CMasternodeMan::IsMasternodePingedWithin(const COutPoint& outpoint, int nSeconds, int64_t nTimeToCheckAt) +{ + LOCK(cs); + CMasternode* pmn = Find(outpoint); + return pmn ? pmn->IsPingedWithin(nSeconds, nTimeToCheckAt) : false; +} + +void CMasternodeMan::SetMasternodeLastPing(const COutPoint& outpoint, const CMasternodePing& mnp) +{ + LOCK(cs); + CMasternode* pmn = Find(outpoint); + if(!pmn) { return; } - pMN->Check(fForce); -} - -int CMasternodeMan::GetMasternodeState(const CTxIn& vin) -{ - LOCK(cs); - CMasternode* pMN = Find(vin); - if(!pMN) { - return CMasternode::MASTERNODE_NEW_START_REQUIRED; - } - return pMN->nActiveState; -} - -int CMasternodeMan::GetMasternodeState(const CPubKey& pubKeyMasternode) -{ - LOCK(cs); - CMasternode* pMN = Find(pubKeyMasternode); - if(!pMN) { - return CMasternode::MASTERNODE_NEW_START_REQUIRED; - } - return pMN->nActiveState; -} - -bool CMasternodeMan::IsMasternodePingedWithin(const CTxIn& vin, int nSeconds, int64_t nTimeToCheckAt) -{ - LOCK(cs); - CMasternode* pMN = Find(vin); - if(!pMN) { - return false; - } - return pMN->IsPingedWithin(nSeconds, nTimeToCheckAt); -} - -void CMasternodeMan::SetMasternodeLastPing(const CTxIn& vin, const CMasternodePing& mnp) -{ - LOCK(cs); - CMasternode* pMN = Find(vin); - if(!pMN) { - return; - } - pMN->lastPing = mnp; + pmn->lastPing = mnp; // if masternode uses sentinel ping instead of watchdog // we shoud update nTimeLastWatchdogVote here if sentinel // ping flag is actual - if(mnp.fSentinelIsCurrent) - pMN->UpdateWatchdogVoteTime(mnp.sigTime); + if(mnp.fSentinelIsCurrent) { + pmn->UpdateWatchdogVoteTime(mnp.sigTime); + } mapSeenMasternodePing.insert(std::make_pair(mnp.GetHash(), mnp)); - CMasternodeBroadcast mnb(*pMN); + CMasternodeBroadcast mnb(*pmn); uint256 hash = mnb.GetHash(); if(mapSeenMasternodeBroadcast.count(hash)) { mapSeenMasternodeBroadcast[hash].second.lastPing = mnp; diff --git a/src/masternodeman.h b/src/masternodeman.h index b98886b0e..89371d57e 100644 --- a/src/masternodeman.h +++ b/src/masternodeman.h @@ -44,7 +44,7 @@ private: int nCachedBlockHeight; // map to hold all MNs - std::vector vMasternodes; + std::map mapMasternodes; // who's asked for the Masternode list and the last time std::map mAskedUsForMasternodeList; // who we asked for the Masternode list and the last time @@ -70,6 +70,8 @@ private: int64_t nLastWatchdogVoteTime; friend class CMasternodeSync; + /// Find an entry + CMasternode* Find(const COutPoint& outpoint); public: // Keep track of all broadcasts I've seen @@ -96,7 +98,7 @@ public: READWRITE(strVersion); } - READWRITE(vMasternodes); + READWRITE(mapMasternodes); READWRITE(mAskedUsForMasternodeList); READWRITE(mWeAskedForMasternodeList); READWRITE(mWeAskedForMasternodeListEntry); @@ -118,9 +120,13 @@ public: bool Add(CMasternode &mn); /// Ask (source) node for mnb - void AskForMN(CNode *pnode, const CTxIn &vin); + void AskForMN(CNode *pnode, const COutPoint& outpoint); void AskForMnb(CNode *pnode, const uint256 &hash); + bool PoSeBan(const COutPoint &outpoint); + bool AllowMixing(const COutPoint &outpoint); + bool DisallowMixing(const COutPoint &outpoint); + /// Check all Masternodes void Check(); @@ -142,32 +148,26 @@ public: void DsegUpdate(CNode* pnode); - /// Find an entry - CMasternode* Find(const CScript &payee); - CMasternode* Find(const CTxIn& vin); - CMasternode* Find(const CPubKey& pubKeyMasternode); - /// Versions of Find that are safe to use from outside the class - bool Get(const CPubKey& pubKeyMasternode, CMasternode& masternode); - bool Get(const CTxIn& vin, CMasternode& masternode); - bool Has(const CTxIn& vin); + bool Get(const COutPoint& outpoint, CMasternode& masternodeRet); + bool Has(const COutPoint& outpoint); - masternode_info_t GetMasternodeInfo(const CTxIn& vin); + bool GetMasternodeInfo(const COutPoint& outpoint, masternode_info_t& mnInfoRet); - masternode_info_t GetMasternodeInfo(const CPubKey& pubKeyMasternode); + bool GetMasternodeInfo(const CPubKey& pubKeyMasternode, masternode_info_t& mnInfoRet); /// Find an entry in the masternode list that is next to be paid - CMasternode* GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int& nCount); + bool GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int& nCountRet, masternode_info_t& mnInfoRet); /// Same as above but use current block height - CMasternode* GetNextMasternodeInQueueForPayment(bool fFilterSigTime, int& nCount); + 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); + masternode_info_t FindRandomNotInVec(const std::vector &vecToExclude, int nProtocolVersion = -1); - std::vector GetFullMasternodeVector() { return vMasternodes; } + std::map GetFullMasternodeMap() { return mapMasternodes; } std::vector > GetMasternodeRanks(int nBlockHeight = -1, int nMinProtocol=0); - int GetMasternodeRank(const CTxIn &vin, int nBlockHeight, int nMinProtocol=0, bool fOnlyActive=true); + int GetMasternodeRank(const COutPoint &outpoint, int nBlockHeight, int nMinProtocol=0, bool fOnlyActive=true); bool GetMasternodeByRank(int nRank, int nBlockHeight, int nMinProtocol, bool fOnlyActive, masternode_info_t& mnInfoRet); void ProcessMasternodeConnections(); @@ -183,7 +183,7 @@ public: void ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerification& mnv); /// Return the number of (unique) Masternodes - int size() { return vMasternodes.size(); } + int size() { return mapMasternodes.size(); } std::string ToString() const; @@ -194,7 +194,6 @@ public: bool IsMnbRecoveryRequested(const uint256& hash) { return mMnbRecoveryRequests.count(hash); } void UpdateLastPaid(const CBlockIndex* pindex); - bool UpdateLastDsq(const CTxIn& vin); void AddDirtyGovernanceObjectHash(const uint256& nHash) { @@ -211,18 +210,14 @@ public: } bool IsWatchdogActive(); - void UpdateWatchdogVoteTime(const CTxIn& vin); - bool AddGovernanceVote(const CTxIn& vin, uint256 nGovernanceObjectHash); + void UpdateWatchdogVoteTime(const COutPoint& outpoint); + bool AddGovernanceVote(const COutPoint& outpoint, uint256 nGovernanceObjectHash); void RemoveGovernanceObject(uint256 nGovernanceObjectHash); - void CheckMasternode(const CTxIn& vin, bool fForce = false); - void CheckMasternode(const CPubKey& pubKeyMasternode, bool fForce = false); + void CheckMasternode(const CPubKey& pubKeyMasternode, bool fForce); - int GetMasternodeState(const CTxIn& vin); - int GetMasternodeState(const CPubKey& pubKeyMasternode); - - bool IsMasternodePingedWithin(const CTxIn& vin, int nSeconds, int64_t nTimeToCheckAt = -1); - void SetMasternodeLastPing(const CTxIn& vin, const CMasternodePing& mnp); + bool IsMasternodePingedWithin(const COutPoint& outpoint, int nSeconds, int64_t nTimeToCheckAt = -1); + void SetMasternodeLastPing(const COutPoint& outpoint, const CMasternodePing& mnp); void UpdatedBlockTip(const CBlockIndex *pindex); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 24c93ddc2..670d915a4 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1590,27 +1590,28 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, return true; // not an error } - CMasternode* pmn = mnodeman.Find(dstx.vin); - if(pmn == NULL) { + CMasternode mn; + + if(!mnodeman.Get(dstx.vin.prevout, mn)) { LogPrint("privatesend", "DSTX -- Can't find masternode %s to verify %s\n", dstx.vin.prevout.ToStringShort(), hashTx.ToString()); return false; } - if(!pmn->fAllowMixingTx) { + if(!mn.fAllowMixingTx) { LogPrint("privatesend", "DSTX -- Masternode %s is sending too many transactions %s\n", dstx.vin.prevout.ToStringShort(), hashTx.ToString()); return true; // TODO: Not an error? Could it be that someone is relaying old DSTXes // we have no idea about (e.g we were offline)? How to handle them? } - if(!dstx.CheckSignature(pmn->pubKeyMasternode)) { + if(!dstx.CheckSignature(mn.pubKeyMasternode)) { LogPrint("privatesend", "DSTX -- CheckSignature() failed for %s\n", hashTx.ToString()); return false; } LogPrintf("DSTX -- Got Masternode transaction %s\n", hashTx.ToString()); mempool.PrioritiseTransaction(hashTx, hashTx.ToString(), 1000, 0.1*COIN); - pmn->fAllowMixingTx = false; + mnodeman.DisallowMixing(dstx.vin.prevout); } LOCK(cs_main); diff --git a/src/privatesend-client.cpp b/src/privatesend-client.cpp index f95cfe109..ebf09647a 100644 --- a/src/privatesend-client.cpp +++ b/src/privatesend-client.cpp @@ -48,12 +48,12 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, std::string& strCommand, C if(dsq.IsExpired()) return; - masternode_info_t infoMn = mnodeman.GetMasternodeInfo(dsq.vin); - if(!infoMn.fInfoValid) return; + masternode_info_t infoMn; + if(!mnodeman.GetMasternodeInfo(dsq.vin.prevout, infoMn)) return; if(!dsq.CheckSignature(infoMn.pubKeyMasternode)) { // we probably have outdated info - mnodeman.AskForMN(pfrom, dsq.vin); + mnodeman.AskForMN(pfrom, dsq.vin.prevout); return; } @@ -85,9 +85,8 @@ void CPrivateSendClient::ProcessMessage(CNode* pfrom, std::string& strCommand, C LogPrint("privatesend", "DSQUEUE -- Masternode %s is sending too many dsq messages\n", infoMn.addr.ToString()); return; } - mnodeman.nDsqCount++; - if(!mnodeman.UpdateLastDsq(dsq.vin)) return; + if(!mnodeman.AllowMixing(dsq.vin.prevout)) return; LogPrint("privatesend", "DSQUEUE -- new PrivateSend queue (%s) from masternode %s\n", dsq.ToString(), infoMn.addr.ToString()); if(infoMixingMasternode.fInfoValid && infoMixingMasternode.vin.prevout == dsq.vin.prevout) { @@ -826,9 +825,9 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized) if(dsq.IsExpired()) continue; - masternode_info_t infoMn = mnodeman.GetMasternodeInfo(dsq.vin); + masternode_info_t infoMn; - if(!infoMn.fInfoValid) { + if(!mnodeman.GetMasternodeInfo(dsq.vin.prevout, infoMn)) { LogPrintf("CPrivateSendClient::JoinExistingQueue -- dsq masternode is not in masternode list, masternode=%s\n", dsq.vin.prevout.ToStringShort()); continue; } @@ -857,7 +856,7 @@ bool CPrivateSendClient::JoinExistingQueue(CAmount nBalanceNeedsAnonymized) continue; } - vecMasternodesUsed.push_back(dsq.vin); + vecMasternodesUsed.push_back(dsq.vin.prevout); CNode* pnodeFound = NULL; bool fDisconnect = false; @@ -923,7 +922,7 @@ bool CPrivateSendClient::StartNewQueue(CAmount nValueMin, CAmount nBalanceNeedsA strAutoDenomResult = _("Can't find random Masternode."); return false; } - vecMasternodesUsed.push_back(infoMn.vin); + vecMasternodesUsed.push_back(infoMn.vin.prevout); if(infoMn.nLastDsq != 0 && infoMn.nLastDsq + nMnCountEnabled/5 > mnodeman.nDsqCount) { LogPrintf("CPrivateSendClient::StartNewQueue -- Too early to mix on this masternode!" diff --git a/src/privatesend-client.h b/src/privatesend-client.h index 19aa23ac5..bfc1aab55 100644 --- a/src/privatesend-client.h +++ b/src/privatesend-client.h @@ -36,7 +36,7 @@ private: mutable CCriticalSection cs_darksend; // Keep track of the used Masternodes - std::vector vecMasternodesUsed; + std::vector vecMasternodesUsed; std::vector vecDenominationsSkipped; std::vector vecOutPointLocked; diff --git a/src/privatesend-server.cpp b/src/privatesend-server.cpp index a6e03f090..a262d55c6 100644 --- a/src/privatesend-server.cpp +++ b/src/privatesend-server.cpp @@ -42,14 +42,14 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, std::string& strCommand, C LogPrint("privatesend", "DSACCEPT -- nDenom %d (%s) txCollateral %s", nDenom, CPrivateSend::GetDenominationsToString(nDenom), txCollateral.ToString()); - CMasternode* pmn = mnodeman.Find(activeMasternode.vin); - if(pmn == NULL) { + masternode_info_t mnInfo; + if(!mnodeman.GetMasternodeInfo(activeMasternode.outpoint, mnInfo)) { PushStatus(pfrom, STATUS_REJECTED, ERR_MN_LIST); return; } - if(vecSessionCollaterals.size() == 0 && pmn->nLastDsq != 0 && - pmn->nLastDsq + mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION)/5 > mnodeman.nDsqCount) + if(vecSessionCollaterals.size() == 0 && mnInfo.nLastDsq != 0 && + mnInfo.nLastDsq + mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION)/5 > mnodeman.nDsqCount) { LogPrintf("DSACCEPT -- last dsq too recent, must wait: addr=%s\n", pfrom->addr.ToString()); PushStatus(pfrom, STATUS_REJECTED, ERR_RECENT); @@ -94,12 +94,12 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, std::string& strCommand, C if(dsq.IsExpired()) return; - CMasternode* pmn = mnodeman.Find(dsq.vin); - if(pmn == NULL) return; + masternode_info_t mnInfo; + if(!mnodeman.GetMasternodeInfo(dsq.vin.prevout, mnInfo)) return; - if(!dsq.CheckSignature(pmn->pubKeyMasternode)) { + if(!dsq.CheckSignature(mnInfo.pubKeyMasternode)) { // we probably have outdated info - mnodeman.AskForMN(pfrom, dsq.vin); + mnodeman.AskForMN(pfrom, dsq.vin.prevout); return; } @@ -107,23 +107,21 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, std::string& strCommand, C BOOST_FOREACH(CDarksendQueue q, vecDarksendQueue) { if(q.vin == dsq.vin) { // no way same mn can send another "not yet ready" dsq this soon - LogPrint("privatesend", "DSQUEUE -- Masternode %s is sending WAY too many dsq messages\n", pmn->addr.ToString()); + LogPrint("privatesend", "DSQUEUE -- Masternode %s is sending WAY too many dsq messages\n", mnInfo.addr.ToString()); return; } } - int nThreshold = pmn->nLastDsq + mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION)/5; - LogPrint("privatesend", "DSQUEUE -- nLastDsq: %d threshold: %d nDsqCount: %d\n", pmn->nLastDsq, nThreshold, mnodeman.nDsqCount); + int nThreshold = mnInfo.nLastDsq + mnodeman.CountEnabled(MIN_PRIVATESEND_PEER_PROTO_VERSION)/5; + LogPrint("privatesend", "DSQUEUE -- nLastDsq: %d threshold: %d nDsqCount: %d\n", mnInfo.nLastDsq, nThreshold, mnodeman.nDsqCount); //don't allow a few nodes to dominate the queuing process - if(pmn->nLastDsq != 0 && nThreshold > mnodeman.nDsqCount) { - LogPrint("privatesend", "DSQUEUE -- Masternode %s is sending too many dsq messages\n", pmn->addr.ToString()); + if(mnInfo.nLastDsq != 0 && nThreshold > mnodeman.nDsqCount) { + LogPrint("privatesend", "DSQUEUE -- Masternode %s is sending too many dsq messages\n", mnInfo.addr.ToString()); return; } - mnodeman.nDsqCount++; - pmn->nLastDsq = mnodeman.nDsqCount; - pmn->fAllowMixingTx = true; + mnodeman.AllowMixing(dsq.vin.prevout); - LogPrint("privatesend", "DSQUEUE -- new PrivateSend queue (%s) from masternode %s\n", dsq.ToString(), pmn->addr.ToString()); + LogPrint("privatesend", "DSQUEUE -- new PrivateSend queue (%s) from masternode %s\n", dsq.ToString(), mnInfo.addr.ToString()); vecDarksendQueue.push_back(dsq); dsq.Relay(); } @@ -358,7 +356,7 @@ void CPrivateSendServer::CommitFinalTransaction() // create and sign masternode dstx transaction if(!CPrivateSend::GetDSTX(hashTx)) { - CDarksendBroadcastTx dstxNew(finalTransaction, activeMasternode.vin, GetAdjustedTime()); + CDarksendBroadcastTx dstxNew(finalTransaction, activeMasternode.outpoint, GetAdjustedTime()); dstxNew.Sign(); CPrivateSend::AddDSTX(dstxNew); } @@ -537,7 +535,7 @@ void CPrivateSendServer::CheckForCompleteQueue() if(nState == POOL_STATE_QUEUE && IsSessionReady()) { SetState(POOL_STATE_ACCEPTING_ENTRIES); - CDarksendQueue dsq(nSessionDenom, activeMasternode.vin, GetAdjustedTime(), true); + CDarksendQueue dsq(nSessionDenom, activeMasternode.outpoint, GetAdjustedTime(), true); LogPrint("privatesend", "CPrivateSendServer::CheckForCompleteQueue -- queue is ready, signing and relaying (%s)\n", dsq.ToString()); dsq.Sign(); dsq.Relay(); @@ -744,7 +742,7 @@ bool CPrivateSendServer::CreateNewSession(int nDenom, CTransaction txCollateral, if(!fUnitTest) { //broadcast that I'm accepting entries, only if it's the first entry through - CDarksendQueue dsq(nDenom, activeMasternode.vin, GetAdjustedTime(), false); + CDarksendQueue dsq(nDenom, activeMasternode.outpoint, GetAdjustedTime(), false); LogPrint("privatesend", "CPrivateSendServer::CreateNewSession -- signing and relaying new queue: %s\n", dsq.ToString()); dsq.Sign(); dsq.Relay(); diff --git a/src/privatesend.h b/src/privatesend.h index 3892267f4..d57054985 100644 --- a/src/privatesend.h +++ b/src/privatesend.h @@ -165,9 +165,9 @@ public: fTried(false) {} - CDarksendQueue(int nDenom, CTxIn vin, int64_t nTime, bool fReady) : + CDarksendQueue(int nDenom, COutPoint outpoint, int64_t nTime, bool fReady) : nDenom(nDenom), - vin(vin), + vin(CTxIn(outpoint)), nTime(nTime), fReady(fReady), vchSig(std::vector()), @@ -236,10 +236,10 @@ public: sigTime(0) {} - CDarksendBroadcastTx(CTransaction tx, CTxIn vin, int64_t sigTime) : + CDarksendBroadcastTx(CTransaction tx, COutPoint outpoint, int64_t sigTime) : nConfirmedHeight(-1), tx(tx), - vin(vin), + vin(CTxIn(outpoint)), vchSig(), sigTime(sigTime) {} diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 33a652d4f..7caf1376a 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -438,8 +438,7 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) item->setCheckState(COLUMN_CHECKBOX, Qt::Unchecked); else { coinControl->Select(outpt); - CTxIn txin = CTxIn(outpt); - int nRounds = pwalletMain->GetInputPrivateSendRounds(txin); + int nRounds = pwalletMain->GetOutpointPrivateSendRounds(outpt); if (coinControl->fUsePrivateSend && nRounds < privateSendClient.nPrivateSendRounds) { QMessageBox::warning(this, windowTitle(), tr("Non-anonymized input selected. PrivateSend will be disabled.

If you still want to use PrivateSend, please deselect all non-nonymized inputs first and then check PrivateSend checkbox again."), @@ -788,8 +787,8 @@ void CoinControlDialog::updateView() // PrivateSend rounds - CTxIn txin = CTxIn(out.tx->GetHash(), out.i); - int nRounds = pwalletMain->GetInputPrivateSendRounds(txin); + COutPoint outpoint = COutPoint(out.tx->GetHash(), out.i); + int nRounds = pwalletMain->GetOutpointPrivateSendRounds(outpoint); if (nRounds >= 0 || fDebug) itemOutput->setText(COLUMN_PRIVATESEND_ROUNDS, strPad(QString::number(nRounds), 11, " ")); else itemOutput->setText(COLUMN_PRIVATESEND_ROUNDS, strPad(QString(tr("n/a")), 11, " ")); diff --git a/src/qt/masternodelist.cpp b/src/qt/masternodelist.cpp index 42313c4ac..7b8372167 100644 --- a/src/qt/masternodelist.cpp +++ b/src/qt/masternodelist.cpp @@ -135,9 +135,9 @@ void MasternodeList::StartAll(std::string strCommand) continue; } - CTxIn txin = CTxIn(uint256S(mne.getTxHash()), nOutputIndex); + COutPoint outpoint = COutPoint(uint256S(mne.getTxHash()), nOutputIndex); - if(strCommand == "start-missing" && mnodeman.Has(txin)) continue; + if(strCommand == "start-missing" && mnodeman.Has(outpoint)) continue; bool fSuccess = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb); @@ -166,7 +166,7 @@ void MasternodeList::StartAll(std::string strCommand) updateMyNodeList(true); } -void MasternodeList::updateMyMasternodeInfo(QString strAlias, QString strAddr, masternode_info_t& infoMn) +void MasternodeList::updateMyMasternodeInfo(QString strAlias, QString strAddr, const COutPoint& outpoint) { bool fOldRowFound = false; int nNewRow = 0; @@ -184,14 +184,17 @@ void MasternodeList::updateMyMasternodeInfo(QString strAlias, QString strAddr, m ui->tableWidgetMyMasternodes->insertRow(nNewRow); } + masternode_info_t infoMn; + bool fFound = mnodeman.GetMasternodeInfo(outpoint, infoMn); + QTableWidgetItem *aliasItem = new QTableWidgetItem(strAlias); - QTableWidgetItem *addrItem = new QTableWidgetItem(infoMn.fInfoValid ? QString::fromStdString(infoMn.addr.ToString()) : strAddr); - QTableWidgetItem *protocolItem = new QTableWidgetItem(QString::number(infoMn.fInfoValid ? infoMn.nProtocolVersion : -1)); - QTableWidgetItem *statusItem = new QTableWidgetItem(QString::fromStdString(infoMn.fInfoValid ? CMasternode::StateToString(infoMn.nActiveState) : "MISSING")); - QTableWidgetItem *activeSecondsItem = new QTableWidgetItem(QString::fromStdString(DurationToDHMS(infoMn.fInfoValid ? (infoMn.nTimeLastPing - infoMn.sigTime) : 0))); + QTableWidgetItem *addrItem = new QTableWidgetItem(fFound ? QString::fromStdString(infoMn.addr.ToString()) : strAddr); + QTableWidgetItem *protocolItem = new QTableWidgetItem(QString::number(fFound ? infoMn.nProtocolVersion : -1)); + QTableWidgetItem *statusItem = new QTableWidgetItem(QString::fromStdString(fFound ? CMasternode::StateToString(infoMn.nActiveState) : "MISSING")); + QTableWidgetItem *activeSecondsItem = new QTableWidgetItem(QString::fromStdString(DurationToDHMS(fFound ? (infoMn.nTimeLastPing - infoMn.sigTime) : 0))); QTableWidgetItem *lastSeenItem = new QTableWidgetItem(QString::fromStdString(DateTimeStrFormat("%Y-%m-%d %H:%M", - infoMn.fInfoValid ? infoMn.nTimeLastPing + QDateTime::currentDateTime().offsetFromUtc() : 0))); - QTableWidgetItem *pubkeyItem = new QTableWidgetItem(QString::fromStdString(infoMn.fInfoValid ? CBitcoinAddress(infoMn.pubKeyCollateralAddress.GetID()).ToString() : "")); + fFound ? infoMn.nTimeLastPing + QDateTime::currentDateTime().offsetFromUtc() : 0))); + QTableWidgetItem *pubkeyItem = new QTableWidgetItem(QString::fromStdString(fFound ? CBitcoinAddress(infoMn.pubKeyCollateralAddress.GetID()).ToString() : "")); ui->tableWidgetMyMasternodes->setItem(nNewRow, 0, aliasItem); ui->tableWidgetMyMasternodes->setItem(nNewRow, 1, addrItem); @@ -225,11 +228,7 @@ void MasternodeList::updateMyNodeList(bool fForce) continue; } - CTxIn txin = CTxIn(uint256S(mne.getTxHash()), nOutputIndex); - - masternode_info_t infoMn = mnodeman.GetMasternodeInfo(txin); - - updateMyMasternodeInfo(QString::fromStdString(mne.getAlias()), QString::fromStdString(mne.getIp()), infoMn); + updateMyMasternodeInfo(QString::fromStdString(mne.getAlias()), QString::fromStdString(mne.getIp()), COutPoint(uint256S(mne.getTxHash()), nOutputIndex)); } ui->tableWidgetMasternodes->setSortingEnabled(true); @@ -263,10 +262,11 @@ void MasternodeList::updateNodeList() ui->tableWidgetMasternodes->setSortingEnabled(false); ui->tableWidgetMasternodes->clearContents(); ui->tableWidgetMasternodes->setRowCount(0); - std::vector vMasternodes = mnodeman.GetFullMasternodeVector(); + std::map mapMasternodes = mnodeman.GetFullMasternodeMap(); - BOOST_FOREACH(CMasternode& mn, vMasternodes) + for(auto& mnpair : mapMasternodes) { + CMasternode mn = mnpair.second; // populate list // Address, Protocol, Status, Active Seconds, Last Seen, Pub Key QTableWidgetItem *addressItem = new QTableWidgetItem(QString::fromStdString(mn.addr.ToString())); diff --git a/src/qt/masternodelist.h b/src/qt/masternodelist.h index 41882b44f..cae9d044e 100644 --- a/src/qt/masternodelist.h +++ b/src/qt/masternodelist.h @@ -1,7 +1,7 @@ #ifndef MASTERNODELIST_H #define MASTERNODELIST_H -#include "masternode.h" +#include "primitives/transaction.h" #include "platformstyle.h" #include "sync.h" #include "util.h" @@ -45,7 +45,7 @@ private: bool fFilterUpdated; public Q_SLOTS: - void updateMyMasternodeInfo(QString strAlias, QString strAddr, masternode_info_t& infoMn); + void updateMyMasternodeInfo(QString strAlias, QString strAddr, const COutPoint& outpoint); void updateMyNodeList(bool fForce = false); void updateNodeList(); diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index d711111a0..30a93d491 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -92,7 +92,7 @@ QList TransactionRecord::decomposeTransaction(const CWallet * BOOST_FOREACH(const CTxIn& txin, wtx.vin) { if(wallet->IsMine(txin)) { - fAllFromMeDenom = fAllFromMeDenom && wallet->IsDenominated(txin); + fAllFromMeDenom = fAllFromMeDenom && wallet->IsDenominated(txin.prevout); nFromMe++; } isminetype mine = wallet->IsMine(txin); diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index 0138932a4..f436c22bb 100644 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -190,11 +190,10 @@ UniValue gobject(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Must wait for client to sync with masternode network. Try again in a minute or so."); } - CMasternode mn; - bool fMnFound = mnodeman.Get(activeMasternode.vin, mn); + bool fMnFound = mnodeman.Has(activeMasternode.outpoint); DBG( cout << "gobject: submit activeMasternode.pubKeyMasternode = " << activeMasternode.pubKeyMasternode.GetHash().ToString() - << ", vin = " << activeMasternode.vin.prevout.ToStringShort() + << ", outpoint = " << activeMasternode.outpoint.ToStringShort() << ", params.size() = " << params.size() << ", fMnFound = " << fMnFound << endl; ); @@ -239,7 +238,7 @@ UniValue gobject(const UniValue& params, bool fHelp) if((govobj.GetObjectType() == GOVERNANCE_OBJECT_TRIGGER) || (govobj.GetObjectType() == GOVERNANCE_OBJECT_WATCHDOG)) { if(fMnFound) { - govobj.SetMasternodeInfo(mn.vin); + govobj.SetMasternodeVin(activeMasternode.outpoint); govobj.Sign(activeMasternode.keyMasternode, activeMasternode.pubKeyMasternode); } else { @@ -322,7 +321,7 @@ UniValue gobject(const UniValue& params, bool fHelp) UniValue returnObj(UniValue::VOBJ); CMasternode mn; - bool fMnFound = mnodeman.Get(activeMasternode.vin, mn); + bool fMnFound = mnodeman.Get(activeMasternode.outpoint, mn); if(!fMnFound) { nFailed++; @@ -334,7 +333,7 @@ UniValue gobject(const UniValue& params, bool fHelp) return returnObj; } - CGovernanceVote vote(mn.vin, hash, eVoteSignal, eVoteOutcome); + CGovernanceVote vote(mn.vin.prevout, hash, eVoteSignal, eVoteOutcome); if(!vote.Sign(activeMasternode.keyMasternode, activeMasternode.pubKeyMasternode)) { nFailed++; statusObj.push_back(Pair("result", "failed")); @@ -425,10 +424,10 @@ UniValue gobject(const UniValue& params, bool fHelp) continue; } - CTxIn vin(COutPoint(nTxHash, nOutputIndex)); + COutPoint outpoint(nTxHash, nOutputIndex); CMasternode mn; - bool fMnFound = mnodeman.Get(vin, mn); + bool fMnFound = mnodeman.Get(outpoint, mn); if(!fMnFound) { nFailed++; @@ -438,7 +437,7 @@ UniValue gobject(const UniValue& params, bool fHelp) continue; } - CGovernanceVote vote(mn.vin, hash, eVoteSignal, eVoteOutcome); + CGovernanceVote vote(mn.vin.prevout, hash, eVoteSignal, eVoteOutcome); if(!vote.Sign(keyMasternode, pubKeyMasternode)){ nFailed++; statusObj.push_back(Pair("result", "failed")); @@ -546,10 +545,10 @@ UniValue gobject(const UniValue& params, bool fHelp) continue; } - CTxIn vin(COutPoint(nTxHash, nOutputIndex)); + COutPoint outpoint(nTxHash, nOutputIndex); CMasternode mn; - bool fMnFound = mnodeman.Get(vin, mn); + bool fMnFound = mnodeman.Get(outpoint, mn); if(!fMnFound) { nFailed++; @@ -561,7 +560,7 @@ UniValue gobject(const UniValue& params, bool fHelp) // CREATE NEW GOVERNANCE OBJECT VOTE WITH OUTCOME/SIGNAL - CGovernanceVote vote(vin, hash, eVoteSignal, eVoteOutcome); + CGovernanceVote vote(outpoint, hash, eVoteSignal, eVoteOutcome); if(!vote.Sign(keyMasternode, pubKeyMasternode)) { nFailed++; statusObj.push_back(Pair("result", "failed")); @@ -799,12 +798,12 @@ UniValue gobject(const UniValue& params, bool fHelp) uint256 hash = ParseHashV(params[1], "Governance hash"); - CTxIn mnCollateralOutpoint; + COutPoint mnCollateralOutpoint; if (params.size() == 4) { uint256 txid = ParseHashV(params[2], "Masternode Collateral hash"); std::string strVout = params[3].get_str(); uint32_t vout = boost::lexical_cast(strVout); - mnCollateralOutpoint = CTxIn(txid, vout); + mnCollateralOutpoint = COutPoint(txid, vout); } // FIND OBJECT USER IS LOOKING FOR @@ -844,7 +843,7 @@ UniValue voteraw(const UniValue& params, bool fHelp) uint256 hashMnTx = ParseHashV(params[0], "mn tx hash"); int nMnTxIndex = params[1].get_int(); - CTxIn vin = CTxIn(hashMnTx, nMnTxIndex); + COutPoint outpoint = COutPoint(hashMnTx, nMnTxIndex); uint256 hashGovObj = ParseHashV(params[2], "Governance hash"); std::string strVoteSignal = params[3].get_str(); @@ -872,13 +871,13 @@ UniValue voteraw(const UniValue& params, bool fHelp) } CMasternode mn; - bool fMnFound = mnodeman.Get(vin, mn); + bool fMnFound = mnodeman.Get(outpoint, mn); if(!fMnFound) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Failure to find masternode in list : " + vin.prevout.ToStringShort()); + throw JSONRPCError(RPC_INTERNAL_ERROR, "Failure to find masternode in list : " + outpoint.ToStringShort()); } - CGovernanceVote vote(vin, hashGovObj, eVoteSignal, eVoteOutcome); + CGovernanceVote vote(outpoint, hashGovObj, eVoteSignal, eVoteOutcome); vote.SetTime(nTime); vote.SetSignature(vchSig); diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 27c769ae2..69f6357a0 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -175,7 +175,8 @@ UniValue masternode(const UniValue& params, bool fHelp) return mnodeman.CountEnabled(); int nCount; - mnodeman.GetNextMasternodeInQueueForPayment(true, nCount); + masternode_info_t mnInfo; + mnodeman.GetNextMasternodeInQueueForPayment(true, nCount, mnInfo); if (strMode == "qualify") return nCount; @@ -190,7 +191,7 @@ UniValue masternode(const UniValue& params, bool fHelp) { int nCount; int nHeight; - CMasternode* winner = NULL; + masternode_info_t mnInfo; CBlockIndex* pindex = NULL; { LOCK(cs_main); @@ -198,20 +199,19 @@ UniValue masternode(const UniValue& params, bool fHelp) } nHeight = pindex->nHeight + (strCommand == "current" ? 1 : 10); mnodeman.UpdateLastPaid(pindex); - winner = mnodeman.GetNextMasternodeInQueueForPayment(nHeight, true, nCount); - if(!winner) return "unknown"; + + if(!mnodeman.GetNextMasternodeInQueueForPayment(nHeight, true, nCount, mnInfo)) + return "unknown"; UniValue obj(UniValue::VOBJ); obj.push_back(Pair("height", nHeight)); - obj.push_back(Pair("IP:port", winner->addr.ToString())); - obj.push_back(Pair("protocol", (int64_t)winner->nProtocolVersion)); - obj.push_back(Pair("vin", winner->vin.prevout.ToStringShort())); - obj.push_back(Pair("payee", CBitcoinAddress(winner->pubKeyCollateralAddress.GetID()).ToString())); - obj.push_back(Pair("lastseen", (winner->lastPing == CMasternodePing()) ? winner->sigTime : - winner->lastPing.sigTime)); - obj.push_back(Pair("activeseconds", (winner->lastPing == CMasternodePing()) ? 0 : - (winner->lastPing.sigTime - winner->sigTime))); + obj.push_back(Pair("IP:port", mnInfo.addr.ToString())); + obj.push_back(Pair("protocol", (int64_t)mnInfo.nProtocolVersion)); + obj.push_back(Pair("outpoint", mnInfo.vin.prevout.ToStringShort())); + obj.push_back(Pair("payee", CBitcoinAddress(mnInfo.pubKeyCollateralAddress.GetID()).ToString())); + obj.push_back(Pair("lastseen", mnInfo.nTimeLastPing)); + obj.push_back(Pair("activeseconds", mnInfo.nTimeLastPing - mnInfo.sigTime)); return obj; } @@ -220,11 +220,11 @@ UniValue masternode(const UniValue& params, bool fHelp) if(activeMasternode.nState != ACTIVE_MASTERNODE_INITIAL || !masternodeSync.IsBlockchainSynced()) return activeMasternode.GetStatus(); - CTxIn vin; + COutPoint outpoint; CPubKey pubkey; CKey key; - if(!pwalletMain || !pwalletMain->GetMasternodeVinAndKeys(vin, pubkey, key)) + if(!pwalletMain || !pwalletMain->GetMasternodeOutpointAndKeys(outpoint, pubkey, key)) throw JSONRPCError(RPC_INVALID_PARAMETER, "Missing masternode input, please look at the documentation for instructions on masternode creation"); return activeMasternode.GetStatus(); @@ -313,12 +313,13 @@ UniValue masternode(const UniValue& params, bool fHelp) BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { std::string strError; - CTxIn vin = CTxIn(uint256S(mne.getTxHash()), uint32_t(atoi(mne.getOutputIndex().c_str()))); - CMasternode *pmn = mnodeman.Find(vin); + COutPoint outpoint = COutPoint(uint256S(mne.getTxHash()), uint32_t(atoi(mne.getOutputIndex().c_str()))); + CMasternode mn; + bool fFound = mnodeman.Get(outpoint, mn); CMasternodeBroadcast mnb; - if(strCommand == "start-missing" && pmn) continue; - if(strCommand == "start-disabled" && pmn && pmn->IsEnabled()) continue; + if(strCommand == "start-missing" && fFound) continue; + if(strCommand == "start-disabled" && fFound && mn.IsEnabled()) continue; bool fResult = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), strError, mnb); @@ -359,10 +360,11 @@ UniValue masternode(const UniValue& params, bool fHelp) UniValue resultObj(UniValue::VOBJ); BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { - CTxIn vin = CTxIn(uint256S(mne.getTxHash()), uint32_t(atoi(mne.getOutputIndex().c_str()))); - CMasternode *pmn = mnodeman.Find(vin); + COutPoint outpoint = COutPoint(uint256S(mne.getTxHash()), uint32_t(atoi(mne.getOutputIndex().c_str()))); + CMasternode mn; + bool fFound = mnodeman.Get(outpoint, mn); - std::string strStatus = pmn ? pmn->GetStatus() : "MISSING"; + std::string strStatus = fFound ? mn.GetStatus() : "MISSING"; UniValue mnObj(UniValue::VOBJ); mnObj.push_back(Pair("alias", mne.getAlias())); @@ -398,11 +400,11 @@ UniValue masternode(const UniValue& params, bool fHelp) UniValue mnObj(UniValue::VOBJ); - mnObj.push_back(Pair("vin", activeMasternode.vin.ToString())); + mnObj.push_back(Pair("vin", activeMasternode.outpoint.ToStringShort())); mnObj.push_back(Pair("service", activeMasternode.service.ToString())); CMasternode mn; - if(mnodeman.Get(activeMasternode.vin, mn)) { + if(mnodeman.Get(activeMasternode.outpoint, mn)) { mnObj.push_back(Pair("payee", CBitcoinAddress(mn.pubKeyCollateralAddress.GetID()).ToString())); } @@ -509,9 +511,10 @@ UniValue masternodelist(const UniValue& params, bool fHelp) obj.push_back(Pair(strOutpoint, s.first)); } } else { - std::vector vMasternodes = mnodeman.GetFullMasternodeVector(); - BOOST_FOREACH(CMasternode& mn, vMasternodes) { - std::string strOutpoint = mn.vin.prevout.ToStringShort(); + std::map mapMasternodes = mnodeman.GetFullMasternodeMap(); + for (auto& mnpair : mapMasternodes) { + CMasternode mn = mnpair.second; + std::string strOutpoint = mnpair.first.ToStringShort(); if (strMode == "activeseconds") { if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) continue; obj.push_back(Pair(strOutpoint, (int64_t)(mn.lastPing.sigTime - mn.sigTime))); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 53fd54491..6258234c5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2632,7 +2632,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) } entry.push_back(Pair("amount",ValueFromAmount(nValue))); entry.push_back(Pair("confirmations",out.nDepth)); - entry.push_back(Pair("ps_rounds", pwalletMain->GetInputPrivateSendRounds(CTxIn(out.tx->GetHash(), out.i)))); + entry.push_back(Pair("ps_rounds", pwalletMain->GetOutpointPrivateSendRounds(COutPoint(out.tx->GetHash(), out.i)))); entry.push_back(Pair("spendable", out.fSpendable)); entry.push_back(Pair("solvable", out.fSolvable)); results.push_back(entry); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8db058f8e..7c5c3ed76 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1233,14 +1233,14 @@ CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const } // Recursively determine the rounds of a given input (How deep is the PrivateSend chain for a given input) -int CWallet::GetRealInputPrivateSendRounds(CTxIn txin, int nRounds) const +int CWallet::GetRealOutpointPrivateSendRounds(const COutPoint& outpoint, int nRounds) const { static std::map mDenomWtxes; if(nRounds >= 16) return 15; // 16 rounds max - uint256 hash = txin.prevout.hash; - unsigned int nout = txin.prevout.n; + uint256 hash = outpoint.hash; + unsigned int nout = outpoint.n; const CWalletTx* wtx = GetWalletTx(hash); if(wtx != NULL) @@ -1248,7 +1248,7 @@ int CWallet::GetRealInputPrivateSendRounds(CTxIn txin, int nRounds) const std::map::const_iterator mdwi = mDenomWtxes.find(hash); if (mdwi == mDenomWtxes.end()) { // not known yet, let's add it - LogPrint("privatesend", "GetRealInputPrivateSendRounds INSERTING %s\n", hash.ToString()); + LogPrint("privatesend", "GetRealOutpointPrivateSendRounds INSERTING %s\n", hash.ToString()); mDenomWtxes[hash] = CMutableTransaction(*wtx); } else if(mDenomWtxes[hash].vout[nout].nRounds != -10) { // found and it's not an initial value, just return it @@ -1259,20 +1259,20 @@ int CWallet::GetRealInputPrivateSendRounds(CTxIn txin, int nRounds) const // bounds check if (nout >= wtx->vout.size()) { // should never actually hit this - LogPrint("privatesend", "GetRealInputPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, -4); + LogPrint("privatesend", "GetRealOutpointPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, -4); return -4; } if (IsCollateralAmount(wtx->vout[nout].nValue)) { mDenomWtxes[hash].vout[nout].nRounds = -3; - LogPrint("privatesend", "GetRealInputPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds); + LogPrint("privatesend", "GetRealOutpointPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds); return mDenomWtxes[hash].vout[nout].nRounds; } //make sure the final output is non-denominate if (!IsDenominatedAmount(wtx->vout[nout].nValue)) { //NOT DENOM mDenomWtxes[hash].vout[nout].nRounds = -2; - LogPrint("privatesend", "GetRealInputPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds); + LogPrint("privatesend", "GetRealOutpointPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds); return mDenomWtxes[hash].vout[nout].nRounds; } @@ -1284,7 +1284,7 @@ int CWallet::GetRealInputPrivateSendRounds(CTxIn txin, int nRounds) const // this one is denominated but there is another non-denominated output found in the same tx if (!fAllDenoms) { mDenomWtxes[hash].vout[nout].nRounds = 0; - LogPrint("privatesend", "GetRealInputPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds); + LogPrint("privatesend", "GetRealOutpointPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds); return mDenomWtxes[hash].vout[nout].nRounds; } @@ -1293,7 +1293,7 @@ int CWallet::GetRealInputPrivateSendRounds(CTxIn txin, int nRounds) const // only denoms here so let's look up BOOST_FOREACH(CTxIn txinNext, wtx->vin) { if (IsMine(txinNext)) { - int n = GetRealInputPrivateSendRounds(txinNext, nRounds + 1); + int n = GetRealOutpointPrivateSendRounds(txinNext.prevout, nRounds + 1); // denom found, find the shortest chain or initially assign nShortest with the first found value if(n >= 0 && (n < nShortest || nShortest == -10)) { nShortest = n; @@ -1304,7 +1304,7 @@ int CWallet::GetRealInputPrivateSendRounds(CTxIn txin, int nRounds) const mDenomWtxes[hash].vout[nout].nRounds = fDenomFound ? (nShortest >= 15 ? 16 : nShortest + 1) // good, we a +1 to the shortest one but only 16 rounds max allowed : 0; // too bad, we are the fist one in that chain - LogPrint("privatesend", "GetRealInputPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds); + LogPrint("privatesend", "GetRealOutpointPrivateSendRounds UPDATED %s %3d %3d\n", hash.ToString(), nout, mDenomWtxes[hash].vout[nout].nRounds); return mDenomWtxes[hash].vout[nout].nRounds; } @@ -1312,22 +1312,22 @@ int CWallet::GetRealInputPrivateSendRounds(CTxIn txin, int nRounds) const } // respect current settings -int CWallet::GetInputPrivateSendRounds(CTxIn txin) const +int CWallet::GetOutpointPrivateSendRounds(const COutPoint& outpoint) const { LOCK(cs_wallet); - int realPrivateSendRounds = GetRealInputPrivateSendRounds(txin, 0); + int realPrivateSendRounds = GetRealOutpointPrivateSendRounds(outpoint, 0); return realPrivateSendRounds > privateSendClient.nPrivateSendRounds ? privateSendClient.nPrivateSendRounds : realPrivateSendRounds; } -bool CWallet::IsDenominated(const CTxIn &txin) const +bool CWallet::IsDenominated(const COutPoint& outpoint) const { LOCK(cs_wallet); - map::const_iterator mi = mapWallet.find(txin.prevout.hash); + map::const_iterator mi = mapWallet.find(outpoint.hash); if (mi != mapWallet.end()) { const CWalletTx& prev = (*mi).second; - if (txin.prevout.n < prev.vout.size()) { - return IsDenominatedAmount(prev.vout[txin.prevout.n].nValue); + if (outpoint.n < prev.vout.size()) { + return IsDenominatedAmount(prev.vout[outpoint.n].nValue); } } @@ -1952,11 +1952,11 @@ CAmount CWalletTx::GetAnonymizedCredit(bool fUseCache) const for (unsigned int i = 0; i < vout.size(); i++) { const CTxOut &txout = vout[i]; - const CTxIn txin = CTxIn(hashTx, i); + const COutPoint outpoint = COutPoint(hashTx, i); - if(pwallet->IsSpent(hashTx, i) || !pwallet->IsDenominated(txin)) continue; + if(pwallet->IsSpent(hashTx, i) || !pwallet->IsDenominated(outpoint)) continue; - const int nRounds = pwallet->GetInputPrivateSendRounds(txin); + const int nRounds = pwallet->GetOutpointPrivateSendRounds(outpoint); if(nRounds >= privateSendClient.nPrivateSendRounds){ nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE); if (!MoneyRange(nCredit)) @@ -2206,11 +2206,11 @@ float CWallet::GetAverageAnonymizedRounds() const for (unsigned int i = 0; i < pcoin->vout.size(); i++) { - CTxIn txin = CTxIn(hash, i); + COutPoint outpoint = COutPoint(hash, i); - if(IsSpent(hash, i) || IsMine(pcoin->vout[i]) != ISMINE_SPENDABLE || !IsDenominated(txin)) continue; + if(IsSpent(hash, i) || IsMine(pcoin->vout[i]) != ISMINE_SPENDABLE || !IsDenominated(outpoint)) continue; - nTotal += GetInputPrivateSendRounds(txin); + nTotal += GetOutpointPrivateSendRounds(outpoint); nCount++; } } @@ -2239,12 +2239,12 @@ CAmount CWallet::GetNormalizedAnonymizedBalance() const for (unsigned int i = 0; i < pcoin->vout.size(); i++) { - CTxIn txin = CTxIn(hash, i); + COutPoint outpoint = COutPoint(hash, i); - if(IsSpent(hash, i) || IsMine(pcoin->vout[i]) != ISMINE_SPENDABLE || !IsDenominated(txin)) continue; + if(IsSpent(hash, i) || IsMine(pcoin->vout[i]) != ISMINE_SPENDABLE || !IsDenominated(outpoint)) continue; if (pcoin->GetDepthInMainChain() < 0) continue; - int nRounds = GetInputPrivateSendRounds(txin); + int nRounds = GetOutpointPrivateSendRounds(outpoint); nTotal += pcoin->vout[i].nValue * nRounds / privateSendClient.nPrivateSendRounds; } } @@ -2643,8 +2643,8 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, setGetHash(),out.i); - int nRounds = GetInputPrivateSendRounds(txin); + COutPoint outpoint = COutPoint(out.tx->GetHash(),out.i); + int nRounds = GetOutpointPrivateSendRounds(outpoint); // make sure it's actually anonymized if(nRounds < privateSendClient.nPrivateSendRounds) continue; } @@ -2666,8 +2666,8 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, setvout[out.i].nValue == nDenom && nValueRet + nDenom < nTargetValue + nSmallestDenom) { - CTxIn txin = CTxIn(out.tx->GetHash(),out.i); - int nRounds = GetInputPrivateSendRounds(txin); + COutPoint outpoint = COutPoint(out.tx->GetHash(),out.i); + int nRounds = GetOutpointPrivateSendRounds(outpoint); // make sure it's actually anonymized if(nRounds < privateSendClient.nPrivateSendRounds) continue; nValueRet += nDenom; @@ -2800,7 +2800,7 @@ bool CWallet::SelectCoinsByDenominations(int nDenom, CAmount nValueMin, CAmount CTxIn txin = CTxIn(out.tx->GetHash(), out.i); - int nRounds = GetInputPrivateSendRounds(txin); + int nRounds = GetOutpointPrivateSendRounds(txin.prevout); if(nRounds >= nPrivateSendRoundsMax) continue; if(nRounds < nPrivateSendRoundsMin) continue; @@ -2884,7 +2884,7 @@ bool CWallet::SelectCoinsGrouppedByAddresses(std::vector& vecT // otherwise they will just lead to higher fee / lower priority if(wtx.vout[i].nValue <= nSmallestDenom/10) continue; // ignore anonymized - if(GetInputPrivateSendRounds(CTxIn(wtx.GetHash(), i)) >= privateSendClient.nPrivateSendRounds) continue; + if(GetOutpointPrivateSendRounds(COutPoint(wtx.GetHash(), i)) >= privateSendClient.nPrivateSendRounds) continue; } CompactTallyItem& item = mapTally[address]; @@ -2948,7 +2948,7 @@ bool CWallet::SelectCoinsDark(CAmount nValueMin, CAmount nValueMax, std::vector< if(nValueRet + out.tx->vout[out.i].nValue <= nValueMax){ CTxIn txin = CTxIn(out.tx->GetHash(),out.i); - int nRounds = GetInputPrivateSendRounds(txin); + int nRounds = GetOutpointPrivateSendRounds(txin.prevout); if(nRounds >= nPrivateSendRoundsMax) continue; if(nRounds < nPrivateSendRoundsMin) continue; @@ -2981,7 +2981,7 @@ bool CWallet::GetCollateralTxIn(CTxIn& txinRet, CAmount& nValueRet) const return false; } -bool CWallet::GetMasternodeVinAndKeys(CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet, std::string strTxHash, std::string strOutputIndex) +bool CWallet::GetMasternodeOutpointAndKeys(COutPoint& outpointRet, CPubKey& pubKeyRet, CKey& keyRet, std::string strTxHash, std::string strOutputIndex) { // wait for reindex and/or import to finish if (fImporting || fReindex) return false; @@ -2990,12 +2990,12 @@ bool CWallet::GetMasternodeVinAndKeys(CTxIn& txinRet, CPubKey& pubKeyRet, CKey& std::vector vPossibleCoins; AvailableCoins(vPossibleCoins, true, NULL, false, ONLY_1000); if(vPossibleCoins.empty()) { - LogPrintf("CWallet::GetMasternodeVinAndKeys -- Could not locate any valid masternode vin\n"); + LogPrintf("CWallet::GetMasternodeOutpointAndKeys -- Could not locate any valid masternode vin\n"); return false; } if(strTxHash.empty()) // No output specified, select the first one - return GetVinAndKeysFromOutput(vPossibleCoins[0], txinRet, pubKeyRet, keyRet); + return GetOutpointAndKeysFromOutput(vPossibleCoins[0], outpointRet, pubKeyRet, keyRet); // Find specific vin uint256 txHash = uint256S(strTxHash); @@ -3003,20 +3003,20 @@ bool CWallet::GetMasternodeVinAndKeys(CTxIn& txinRet, CPubKey& pubKeyRet, CKey& BOOST_FOREACH(COutput& out, vPossibleCoins) if(out.tx->GetHash() == txHash && out.i == nOutputIndex) // found it! - return GetVinAndKeysFromOutput(out, txinRet, pubKeyRet, keyRet); + return GetOutpointAndKeysFromOutput(out, outpointRet, pubKeyRet, keyRet); - LogPrintf("CWallet::GetMasternodeVinAndKeys -- Could not locate specified masternode vin\n"); + LogPrintf("CWallet::GetMasternodeOutpointAndKeys -- Could not locate specified masternode vin\n"); return false; } -bool CWallet::GetVinAndKeysFromOutput(COutput out, CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet) +bool CWallet::GetOutpointAndKeysFromOutput(const COutput& out, COutPoint& outpointRet, CPubKey& pubKeyRet, CKey& keyRet) { // wait for reindex and/or import to finish if (fImporting || fReindex) return false; CScript pubScript; - txinRet = CTxIn(out.tx->GetHash(), out.i); + outpointRet = COutPoint(out.tx->GetHash(), out.i); pubScript = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey CTxDestination address1; @@ -3025,12 +3025,12 @@ bool CWallet::GetVinAndKeysFromOutput(COutput out, CTxIn& txinRet, CPubKey& pubK CKeyID keyID; if (!address2.GetKeyID(keyID)) { - LogPrintf("CWallet::GetVinAndKeysFromOutput -- Address does not refer to a key\n"); + LogPrintf("CWallet::GetOutpointAndKeysFromOutput -- Address does not refer to a key\n"); return false; } if (!GetKey(keyID, keyRet)) { - LogPrintf ("CWallet::GetVinAndKeysFromOutput -- Private key for address is not known\n"); + LogPrintf ("CWallet::GetOutpointAndKeysFromOutput -- Private key for address is not known\n"); return false; } @@ -3051,11 +3051,11 @@ int CWallet::CountInputsWithAmount(CAmount nInputAmount) for (unsigned int i = 0; i < pcoin->vout.size(); i++) { COutput out = COutput(pcoin, i, nDepth, true, true); - CTxIn txin = CTxIn(out.tx->GetHash(), out.i); + COutPoint outpoint = COutPoint(out.tx->GetHash(), out.i); if(out.tx->vout[out.i].nValue != nInputAmount) continue; if(!IsDenominatedAmount(pcoin->vout[i].nValue)) continue; - if(IsSpent(out.tx->GetHash(), i) || IsMine(pcoin->vout[i]) != ISMINE_SPENDABLE || !IsDenominated(txin)) continue; + if(IsSpent(out.tx->GetHash(), i) || IsMine(pcoin->vout[i]) != ISMINE_SPENDABLE || !IsDenominated(outpoint)) continue; nTotal++; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 6c9f77393..8c8349053 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -775,20 +775,20 @@ public: bool SelectCoinsGrouppedByAddresses(std::vector& vecTallyRet, bool fSkipDenominated = true, bool fAnonymizable = true, bool fSkipUnconfirmed = true) const; /// Get 1000DASH output and keys which can be used for the Masternode - bool GetMasternodeVinAndKeys(CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet, std::string strTxHash = "", std::string strOutputIndex = ""); + bool GetMasternodeOutpointAndKeys(COutPoint& outpointRet, CPubKey& pubKeyRet, CKey& keyRet, std::string strTxHash = "", std::string strOutputIndex = ""); /// Extract txin information and keys from output - bool GetVinAndKeysFromOutput(COutput out, CTxIn& txinRet, CPubKey& pubKeyRet, CKey& keyRet); + bool GetOutpointAndKeysFromOutput(const COutput& out, COutPoint& outpointRet, CPubKey& pubKeyRet, CKey& keyRet); bool HasCollateralInputs(bool fOnlyConfirmed = true) const; bool IsCollateralAmount(CAmount nInputAmount) const; int CountInputsWithAmount(CAmount nInputAmount); // get the PrivateSend chain depth for a given input - int GetRealInputPrivateSendRounds(CTxIn txin, int nRounds) const; + int GetRealOutpointPrivateSendRounds(const COutPoint& outpoint, int nRounds) const; // respect current settings - int GetInputPrivateSendRounds(CTxIn txin) const; + int GetOutpointPrivateSendRounds(const COutPoint& outpoint) const; - bool IsDenominated(const CTxIn &txin) const; + bool IsDenominated(const COutPoint& outpoint) const; bool IsDenominatedAmount(CAmount nInputAmount) const; bool IsSpent(const uint256& hash, unsigned int n) const;