Refactor masternode management (#1611)
* Store masternodes in a map instead of a vector, drop unused functions in CMasternodeMan * CTxIn vin -> COutPoint outpoint * do not use CMasternodeMan::Find outside of the class * update GetMasternodeInfo * safe version of GetNextMasternodeInQueueForPayment * fix ProcessMasternodeConnections * bump CMasternodeMan::SERIALIZATION_VERSION_STRING
This commit is contained in:
parent
cd262bf641
commit
05da4557d0
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -116,13 +116,13 @@ class CGovernanceObject
|
||||
friend class CGovernanceTriggerManager;
|
||||
|
||||
public: // Types
|
||||
typedef std::map<CTxIn, vote_rec_t> vote_m_t;
|
||||
typedef std::map<COutPoint, vote_rec_t> vote_m_t;
|
||||
|
||||
typedef vote_m_t::iterator vote_m_it;
|
||||
|
||||
typedef vote_m_t::const_iterator vote_m_cit;
|
||||
|
||||
typedef CacheMultiMap<CTxIn, vote_time_pair_t> vote_mcache_t;
|
||||
typedef CacheMultiMap<COutPoint, vote_time_pair_t> 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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -53,11 +53,11 @@ std::vector<CGovernanceVote> 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++);
|
||||
|
@ -72,7 +72,7 @@ public:
|
||||
|
||||
CGovernanceObjectVoteFile& operator=(const CGovernanceObjectVoteFile& other);
|
||||
|
||||
void RemoveVotesFromMasternode(const CTxIn& vinMasternode);
|
||||
void RemoveVotesFromMasternode(const COutPoint& outpointMasternode);
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
|
@ -580,7 +580,7 @@ std::vector<CGovernanceVote> CGovernanceManager::GetMatchingVotes(const uint256&
|
||||
return govobj.GetVoteFile().GetVotes();
|
||||
}
|
||||
|
||||
std::vector<CGovernanceVote> CGovernanceManager::GetCurrentVotes(const uint256& nParentHash, const CTxIn& mnCollateralOutpointFilter)
|
||||
std::vector<CGovernanceVote> CGovernanceManager::GetCurrentVotes(const uint256& nParentHash, const COutPoint& mnCollateralOutpointFilter)
|
||||
{
|
||||
LOCK(cs);
|
||||
std::vector<CGovernanceVote> vecResult;
|
||||
@ -590,34 +590,27 @@ std::vector<CGovernanceVote> 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<CTxIn> vecMNTxIn;
|
||||
if (mnCollateralOutpointFilter == CTxIn()) {
|
||||
std::vector<CMasternode> mnlist = mnodeman.GetFullMasternodeVector();
|
||||
for (std::vector<CMasternode>::iterator it = mnlist.begin(); it != mnlist.end(); ++it)
|
||||
{
|
||||
vecMNTxIn.push_back(it->vin);
|
||||
}
|
||||
}
|
||||
else {
|
||||
vecMNTxIn.push_back(mnCollateralOutpointFilter);
|
||||
CMasternode mn;
|
||||
std::map<COutPoint, CMasternode> 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<CTxIn>::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());
|
||||
}
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ public:
|
||||
CGovernanceObject *FindGovernanceObject(const uint256& nHash);
|
||||
|
||||
std::vector<CGovernanceVote> GetMatchingVotes(const uint256& nParentHash);
|
||||
std::vector<CGovernanceVote> GetCurrentVotes(const uint256& nParentHash, const CTxIn& mnCollateralOutpointFilter);
|
||||
std::vector<CGovernanceVote> GetCurrentVotes(const uint256& nParentHash, const COutPoint& mnCollateralOutpointFilter);
|
||||
std::vector<CGovernanceObject*> GetAllNewerThan(int64_t nMoreThanTime);
|
||||
|
||||
bool IsBudgetPaymentBlock(int nBlockHeight);
|
||||
|
@ -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<uint256, CTxLockCandidate>::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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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<COutPoint, std::map<CNetAddr, int64_t> >::iterator it1 = mWeAskedForMasternodeListEntry.find(vin.prevout);
|
||||
std::map<COutPoint, std::map<CNetAddr, int64_t> >::iterator it1 = mWeAskedForMasternodeListEntry.find(outpoint);
|
||||
if (it1 != mWeAskedForMasternodeListEntry.end()) {
|
||||
std::map<CNetAddr, int64_t>::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<CMasternode>::iterator it = vMasternodes.begin();
|
||||
std::vector<std::pair<int, CMasternode> > 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<COutPoint, CMasternode>::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<std::pair<int, CMasternode*> > 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<CTxIn> &vecToExclude, int nProtocolVersion)
|
||||
masternode_info_t CMasternodeMan::FindRandomNotInVec(const std::vector<COutPoint> &vecToExclude, int nProtocolVersion)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
@ -562,8 +552,8 @@ masternode_info_t CMasternodeMan::FindRandomNotInVec(const std::vector<CTxIn> &v
|
||||
|
||||
// fill a vector of pointers
|
||||
std::vector<CMasternode*> 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<CTxIn> &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<CTxIn> &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<std::pair<int64_t, CMasternode*> > 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<std::pair<int, CMasternode> > 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<std::pair<int, CMasternode> > 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<CMasternode*> 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<CMasternode*> vBan;
|
||||
std::vector<CMasternode*> 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<CMasternode*> vpMasternodesToBan;
|
||||
std::vector<CMasternode>::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;
|
||||
|
@ -44,7 +44,7 @@ private:
|
||||
int nCachedBlockHeight;
|
||||
|
||||
// map to hold all MNs
|
||||
std::vector<CMasternode> vMasternodes;
|
||||
std::map<COutPoint, CMasternode> mapMasternodes;
|
||||
// who's asked for the Masternode list and the last time
|
||||
std::map<CNetAddr, int64_t> 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<CTxIn> &vecToExclude, int nProtocolVersion = -1);
|
||||
masternode_info_t FindRandomNotInVec(const std::vector<COutPoint> &vecToExclude, int nProtocolVersion = -1);
|
||||
|
||||
std::vector<CMasternode> GetFullMasternodeVector() { return vMasternodes; }
|
||||
std::map<COutPoint, CMasternode> GetFullMasternodeMap() { return mapMasternodes; }
|
||||
|
||||
std::vector<std::pair<int, CMasternode> > 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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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!"
|
||||
|
@ -36,7 +36,7 @@ private:
|
||||
mutable CCriticalSection cs_darksend;
|
||||
|
||||
// Keep track of the used Masternodes
|
||||
std::vector<CTxIn> vecMasternodesUsed;
|
||||
std::vector<COutPoint> vecMasternodesUsed;
|
||||
|
||||
std::vector<CAmount> vecDenominationsSkipped;
|
||||
std::vector<COutPoint> vecOutPointLocked;
|
||||
|
@ -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();
|
||||
|
@ -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<unsigned char>()),
|
||||
@ -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)
|
||||
{}
|
||||
|
@ -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. <b>PrivateSend will be disabled.</b><br><br>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, " "));
|
||||
|
@ -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<CMasternode> vMasternodes = mnodeman.GetFullMasternodeVector();
|
||||
std::map<COutPoint, CMasternode> 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()));
|
||||
|
@ -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();
|
||||
|
||||
|
@ -92,7 +92,7 @@ QList<TransactionRecord> 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);
|
||||
|
@ -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<uint32_t>(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);
|
||||
|
||||
|
@ -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<CMasternode> vMasternodes = mnodeman.GetFullMasternodeVector();
|
||||
BOOST_FOREACH(CMasternode& mn, vMasternodes) {
|
||||
std::string strOutpoint = mn.vin.prevout.ToStringShort();
|
||||
std::map<COutPoint, CMasternode> 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)));
|
||||
|
@ -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);
|
||||
|
@ -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<uint256, CMutableTransaction> 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<uint256, CMutableTransaction>::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<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
|
||||
map<uint256, CWalletTx>::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, set<pair<const CWalletTx*
|
||||
continue;
|
||||
|
||||
if(nCoinType == ONLY_DENOMINATED) {
|
||||
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;
|
||||
}
|
||||
@ -2666,8 +2666,8 @@ bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*
|
||||
{
|
||||
//make sure it's the denom we're looking for, round the amount up to smallest denom
|
||||
if(out.tx->vout[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<CompactTallyItem>& 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<COutput> 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++;
|
||||
}
|
||||
|
@ -775,20 +775,20 @@ public:
|
||||
bool SelectCoinsGrouppedByAddresses(std::vector<CompactTallyItem>& 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;
|
||||
|
Loading…
Reference in New Issue
Block a user