2016-12-20 14:26:45 +01:00
|
|
|
// Copyright (c) 2014-2017 The Dash Core developers
|
2015-02-23 21:01:21 +01:00
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2015-02-24 15:02:22 +01:00
|
|
|
|
2015-02-23 21:01:21 +01:00
|
|
|
#ifndef MASTERNODEMAN_H
|
|
|
|
#define MASTERNODEMAN_H
|
|
|
|
|
|
|
|
#include "masternode.h"
|
2016-10-20 23:11:30 +02:00
|
|
|
#include "sync.h"
|
2015-02-23 21:01:21 +01:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
class CMasternodeMan;
|
2016-10-20 23:11:30 +02:00
|
|
|
|
2015-02-23 21:01:21 +01:00
|
|
|
extern CMasternodeMan mnodeman;
|
|
|
|
|
2016-11-13 18:52:34 +01:00
|
|
|
/**
|
|
|
|
* Provides a forward and reverse index between MN vin's and integers.
|
|
|
|
*
|
|
|
|
* This mapping is normally add-only and is expected to be permanent
|
|
|
|
* It is only rebuilt if the size of the index exceeds the expected maximum number
|
|
|
|
* of MN's and the current number of known MN's.
|
|
|
|
*
|
|
|
|
* The external interface to this index is provided via delegation by CMasternodeMan
|
|
|
|
*/
|
|
|
|
class CMasternodeIndex
|
|
|
|
{
|
|
|
|
public: // Types
|
|
|
|
typedef std::map<CTxIn,int> index_m_t;
|
|
|
|
|
|
|
|
typedef index_m_t::iterator index_m_it;
|
|
|
|
|
|
|
|
typedef index_m_t::const_iterator index_m_cit;
|
|
|
|
|
|
|
|
typedef std::map<int,CTxIn> rindex_m_t;
|
|
|
|
|
|
|
|
typedef rindex_m_t::iterator rindex_m_it;
|
|
|
|
|
|
|
|
typedef rindex_m_t::const_iterator rindex_m_cit;
|
|
|
|
|
|
|
|
private:
|
|
|
|
int nSize;
|
|
|
|
|
|
|
|
index_m_t mapIndex;
|
|
|
|
|
|
|
|
rindex_m_t mapReverseIndex;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CMasternodeIndex();
|
|
|
|
|
|
|
|
int GetSize() const {
|
|
|
|
return nSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Retrieve masternode vin by index
|
|
|
|
bool Get(int nIndex, CTxIn& vinMasternode) const;
|
|
|
|
|
|
|
|
/// Get index of a masternode vin
|
|
|
|
int GetMasternodeIndex(const CTxIn& vinMasternode) const;
|
|
|
|
|
|
|
|
void AddMasternodeVIN(const CTxIn& vinMasternode);
|
|
|
|
|
|
|
|
void Clear();
|
|
|
|
|
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
|
|
|
|
{
|
|
|
|
READWRITE(mapIndex);
|
|
|
|
if(ser_action.ForRead()) {
|
|
|
|
RebuildIndex();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void RebuildIndex();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2015-02-23 21:01:21 +01:00
|
|
|
class CMasternodeMan
|
|
|
|
{
|
2016-11-13 18:52:34 +01:00
|
|
|
public:
|
|
|
|
typedef std::map<CTxIn,int> index_m_t;
|
|
|
|
|
|
|
|
typedef index_m_t::iterator index_m_it;
|
|
|
|
|
|
|
|
typedef index_m_t::const_iterator index_m_cit;
|
|
|
|
|
2015-02-23 21:01:21 +01:00
|
|
|
private:
|
2016-11-13 18:52:34 +01:00
|
|
|
static const int MAX_EXPECTED_INDEX_SIZE = 30000;
|
|
|
|
|
|
|
|
/// Only allow 1 index rebuild per hour
|
|
|
|
static const int64_t MIN_INDEX_REBUILD_TIME = 3600;
|
|
|
|
|
2016-10-17 20:54:28 +02:00
|
|
|
static const std::string SERIALIZATION_VERSION_STRING;
|
|
|
|
|
2016-10-20 23:11:30 +02:00
|
|
|
static const int DSEG_UPDATE_SECONDS = 3 * 60 * 60;
|
|
|
|
|
|
|
|
static const int LAST_PAID_SCAN_BLOCKS = 100;
|
|
|
|
|
|
|
|
static const int MIN_POSE_PROTO_VERSION = 70203;
|
|
|
|
static const int MAX_POSE_RANK = 10;
|
|
|
|
static const int MAX_POSE_BLOCKS = 10;
|
|
|
|
|
2016-09-13 01:21:59 +02:00
|
|
|
|
2015-02-23 21:01:21 +01:00
|
|
|
// critical section to protect the inner data structures
|
|
|
|
mutable CCriticalSection cs;
|
|
|
|
|
2016-10-20 23:11:30 +02:00
|
|
|
// Keep track of current block index
|
|
|
|
const CBlockIndex *pCurrentBlockIndex;
|
2015-07-14 07:25:07 +02:00
|
|
|
|
2015-02-23 21:01:21 +01:00
|
|
|
// map to hold all MNs
|
|
|
|
std::vector<CMasternode> vMasternodes;
|
2015-03-05 09:10:15 +01:00
|
|
|
// who's asked for the Masternode list and the last time
|
2015-02-26 00:21:28 +01:00
|
|
|
std::map<CNetAddr, int64_t> mAskedUsForMasternodeList;
|
2015-03-05 09:10:15 +01:00
|
|
|
// who we asked for the Masternode list and the last time
|
2015-02-26 00:21:28 +01:00
|
|
|
std::map<CNetAddr, int64_t> mWeAskedForMasternodeList;
|
2015-03-05 09:10:15 +01:00
|
|
|
// which Masternodes we've asked for
|
2016-12-21 00:55:55 +01:00
|
|
|
std::map<COutPoint, std::map<CNetAddr, int64_t> > mWeAskedForMasternodeListEntry;
|
2016-10-20 23:11:30 +02:00
|
|
|
// who we asked for the masternode verification
|
|
|
|
std::map<CNetAddr, CMasternodeVerification> mWeAskedForVerification;
|
2015-02-24 11:39:29 +01:00
|
|
|
|
2016-11-13 18:52:34 +01:00
|
|
|
int64_t nLastIndexRebuildTime;
|
|
|
|
|
|
|
|
CMasternodeIndex indexMasternodes;
|
|
|
|
|
|
|
|
CMasternodeIndex indexMasternodesOld;
|
|
|
|
|
|
|
|
/// Set when index has been rebuilt, clear when read
|
|
|
|
bool fIndexRebuilt;
|
|
|
|
|
|
|
|
/// Set when masternodes are added, cleared when CGovernanceManager is notified
|
|
|
|
bool fMasternodesAdded;
|
|
|
|
|
|
|
|
/// Set when masternodes are removed, cleared when CGovernanceManager is notified
|
|
|
|
bool fMasternodesRemoved;
|
|
|
|
|
2016-10-17 20:54:28 +02:00
|
|
|
std::vector<uint256> vecDirtyGovernanceObjectHashes;
|
|
|
|
|
|
|
|
int64_t nLastWatchdogVoteTime;
|
|
|
|
|
2016-10-30 20:40:30 +01:00
|
|
|
friend class CMasternodeSync;
|
|
|
|
|
2015-02-23 21:01:21 +01:00
|
|
|
public:
|
2015-07-25 21:07:30 +02:00
|
|
|
// Keep track of all broadcasts I've seen
|
2016-10-20 23:11:30 +02:00
|
|
|
std::map<uint256, CMasternodeBroadcast> mapSeenMasternodeBroadcast;
|
2015-07-25 21:07:30 +02:00
|
|
|
// Keep track of all pings I've seen
|
2016-10-20 23:11:30 +02:00
|
|
|
std::map<uint256, CMasternodePing> mapSeenMasternodePing;
|
|
|
|
// Keep track of all verifications I've seen
|
|
|
|
std::map<uint256, CMasternodeVerification> mapSeenMasternodeVerification;
|
2015-03-06 18:25:48 +01:00
|
|
|
// keep track of dsq count to prevent masternodes from gaming darksend queue
|
|
|
|
int64_t nDsqCount;
|
2015-02-23 21:01:21 +01:00
|
|
|
|
2016-05-30 08:22:08 +02:00
|
|
|
|
2015-04-03 00:51:08 +02:00
|
|
|
ADD_SERIALIZE_METHODS;
|
|
|
|
|
|
|
|
template <typename Stream, typename Operation>
|
|
|
|
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
2015-07-25 21:07:30 +02:00
|
|
|
LOCK(cs);
|
2016-10-17 20:54:28 +02:00
|
|
|
std::string strVersion;
|
|
|
|
if(ser_action.ForRead()) {
|
|
|
|
READWRITE(strVersion);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
strVersion = SERIALIZATION_VERSION_STRING;
|
|
|
|
READWRITE(strVersion);
|
|
|
|
}
|
|
|
|
|
2015-07-25 21:07:30 +02:00
|
|
|
READWRITE(vMasternodes);
|
|
|
|
READWRITE(mAskedUsForMasternodeList);
|
|
|
|
READWRITE(mWeAskedForMasternodeList);
|
|
|
|
READWRITE(mWeAskedForMasternodeListEntry);
|
2016-10-17 20:54:28 +02:00
|
|
|
READWRITE(nLastWatchdogVoteTime);
|
2015-07-25 21:07:30 +02:00
|
|
|
READWRITE(nDsqCount);
|
|
|
|
|
|
|
|
READWRITE(mapSeenMasternodeBroadcast);
|
|
|
|
READWRITE(mapSeenMasternodePing);
|
2016-11-13 18:52:34 +01:00
|
|
|
READWRITE(indexMasternodes);
|
2016-10-17 20:54:28 +02:00
|
|
|
if(ser_action.ForRead() && (strVersion != SERIALIZATION_VERSION_STRING)) {
|
|
|
|
Clear();
|
|
|
|
}
|
2015-04-03 00:51:08 +02:00
|
|
|
}
|
2015-02-23 21:01:21 +01:00
|
|
|
|
2016-11-13 18:52:34 +01:00
|
|
|
CMasternodeMan();
|
|
|
|
|
2015-03-05 09:10:15 +01:00
|
|
|
/// Add an entry
|
2015-02-23 21:01:21 +01:00
|
|
|
bool Add(CMasternode &mn);
|
|
|
|
|
2015-08-07 05:07:40 +02:00
|
|
|
/// Ask (source) node for mnb
|
2016-11-13 18:52:34 +01:00
|
|
|
void AskForMN(CNode *pnode, const CTxIn &vin);
|
2015-08-07 05:07:40 +02:00
|
|
|
|
2015-03-05 09:10:15 +01:00
|
|
|
/// Check all Masternodes
|
2015-02-23 21:01:21 +01:00
|
|
|
void Check();
|
|
|
|
|
2015-03-05 09:10:15 +01:00
|
|
|
/// Check all Masternodes and remove inactive
|
2016-11-16 03:09:37 +01:00
|
|
|
void CheckAndRemove();
|
2015-02-23 21:01:21 +01:00
|
|
|
|
2015-03-05 09:10:15 +01:00
|
|
|
/// Clear Masternode vector
|
2015-03-01 01:04:17 +01:00
|
|
|
void Clear();
|
2015-02-23 21:01:21 +01:00
|
|
|
|
2016-10-22 18:52:14 +02:00
|
|
|
/// Count Masternodes filtered by nProtocolVersion.
|
|
|
|
/// Masternode nProtocolVersion should match or be above the one specified in param here.
|
|
|
|
int CountMasternodes(int nProtocolVersion = -1);
|
|
|
|
/// Count enabled Masternodes filtered by nProtocolVersion.
|
|
|
|
/// Masternode nProtocolVersion should match or be above the one specified in param here.
|
|
|
|
int CountEnabled(int nProtocolVersion = -1);
|
2016-08-12 07:58:55 +02:00
|
|
|
|
|
|
|
/// Count Masternodes by network type - NET_IPV4, NET_IPV6, NET_TOR
|
2016-10-22 18:52:14 +02:00
|
|
|
// int CountByIP(int nNetworkType);
|
2015-02-23 21:01:21 +01:00
|
|
|
|
2015-02-26 00:21:28 +01:00
|
|
|
void DsegUpdate(CNode* pnode);
|
2015-02-23 21:01:21 +01:00
|
|
|
|
2015-03-05 09:10:15 +01:00
|
|
|
/// Find an entry
|
2015-05-28 19:45:31 +02:00
|
|
|
CMasternode* Find(const CScript &payee);
|
2015-02-26 00:21:28 +01:00
|
|
|
CMasternode* Find(const CTxIn& vin);
|
2015-04-07 21:59:30 +02:00
|
|
|
CMasternode* Find(const CPubKey& pubKeyMasternode);
|
2015-02-23 21:01:21 +01:00
|
|
|
|
2016-09-15 08:49:24 +02:00
|
|
|
/// Versions of Find that are safe to use from outside the class
|
2016-09-05 01:44:10 +02:00
|
|
|
bool Get(const CPubKey& pubKeyMasternode, CMasternode& masternode);
|
2016-09-15 08:49:24 +02:00
|
|
|
bool Get(const CTxIn& vin, CMasternode& masternode);
|
2016-09-05 01:44:10 +02:00
|
|
|
|
2016-11-13 18:52:34 +01:00
|
|
|
/// Retrieve masternode vin by index
|
|
|
|
bool Get(int nIndex, CTxIn& vinMasternode, bool& fIndexRebuiltOut) {
|
|
|
|
LOCK(cs);
|
|
|
|
fIndexRebuiltOut = fIndexRebuilt;
|
|
|
|
return indexMasternodes.Get(nIndex, vinMasternode);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetIndexRebuiltFlag() {
|
|
|
|
LOCK(cs);
|
|
|
|
return fIndexRebuilt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get index of a masternode vin
|
|
|
|
int GetMasternodeIndex(const CTxIn& vinMasternode) {
|
|
|
|
LOCK(cs);
|
|
|
|
return indexMasternodes.GetMasternodeIndex(vinMasternode);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get old index of a masternode vin
|
|
|
|
int GetMasternodeIndexOld(const CTxIn& vinMasternode) {
|
|
|
|
LOCK(cs);
|
|
|
|
return indexMasternodesOld.GetMasternodeIndex(vinMasternode);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get masternode VIN for an old index value
|
|
|
|
bool GetMasternodeVinForIndexOld(int nMasternodeIndex, CTxIn& vinMasternodeOut) {
|
|
|
|
LOCK(cs);
|
|
|
|
return indexMasternodesOld.Get(nMasternodeIndex, vinMasternodeOut);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get index of a masternode vin, returning rebuild flag
|
|
|
|
int GetMasternodeIndex(const CTxIn& vinMasternode, bool& fIndexRebuiltOut) {
|
|
|
|
LOCK(cs);
|
|
|
|
fIndexRebuiltOut = fIndexRebuilt;
|
|
|
|
return indexMasternodes.GetMasternodeIndex(vinMasternode);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClearOldMasternodeIndex() {
|
|
|
|
LOCK(cs);
|
|
|
|
indexMasternodesOld.Clear();
|
|
|
|
fIndexRebuilt = false;
|
|
|
|
}
|
|
|
|
|
2016-10-17 20:54:28 +02:00
|
|
|
bool Has(const CTxIn& vin);
|
|
|
|
|
|
|
|
masternode_info_t GetMasternodeInfo(const CTxIn& vin);
|
|
|
|
|
|
|
|
masternode_info_t GetMasternodeInfo(const CPubKey& pubKeyMasternode);
|
|
|
|
|
2015-05-04 17:04:09 +02:00
|
|
|
/// Find an entry in the masternode list that is next to be paid
|
2015-08-20 17:36:44 +02:00
|
|
|
CMasternode* GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int& nCount);
|
2016-11-28 15:21:50 +01:00
|
|
|
/// Same as above but use current block height
|
|
|
|
CMasternode* GetNextMasternodeInQueueForPayment(bool fFilterSigTime, int& nCount);
|
2015-02-26 00:21:28 +01:00
|
|
|
|
2015-03-05 09:10:15 +01:00
|
|
|
/// Find a random entry
|
2016-10-22 18:52:14 +02:00
|
|
|
CMasternode* FindRandomNotInVec(const std::vector<CTxIn> &vecToExclude, int nProtocolVersion = -1);
|
2015-02-26 00:21:28 +01:00
|
|
|
|
2016-11-28 15:21:50 +01:00
|
|
|
std::vector<CMasternode> GetFullMasternodeVector() { return vMasternodes; }
|
2015-02-23 21:01:21 +01:00
|
|
|
|
2016-10-22 18:52:14 +02:00
|
|
|
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);
|
|
|
|
CMasternode* GetMasternodeByRank(int nRank, int nBlockHeight, int nMinProtocol=0, bool fOnlyActive=true);
|
2016-05-30 08:22:08 +02:00
|
|
|
|
2015-03-02 00:09:33 +01:00
|
|
|
void ProcessMasternodeConnections();
|
|
|
|
|
2015-04-08 04:07:25 +02:00
|
|
|
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
|
|
|
|
|
2016-10-20 23:11:30 +02:00
|
|
|
void DoFullVerificationStep();
|
|
|
|
void CheckSameAddr();
|
|
|
|
bool SendVerifyRequest(const CAddress& addr, const std::vector<CMasternode*>& vSortedByAddr);
|
|
|
|
void SendVerifyReply(CNode* pnode, CMasternodeVerification& mnv);
|
|
|
|
void ProcessVerifyReply(CNode* pnode, CMasternodeVerification& mnv);
|
|
|
|
void ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerification& mnv);
|
|
|
|
|
2015-03-05 09:10:15 +01:00
|
|
|
/// Return the number of (unique) Masternodes
|
2015-02-26 00:21:28 +01:00
|
|
|
int size() { return vMasternodes.size(); }
|
2015-02-24 11:39:29 +01:00
|
|
|
|
2015-03-05 00:46:50 +01:00
|
|
|
std::string ToString() const;
|
2015-03-01 00:56:52 +01:00
|
|
|
|
2016-02-04 20:29:09 +01:00
|
|
|
int GetEstimatedMasternodes(int nBlock);
|
|
|
|
|
2016-03-16 16:30:22 +01:00
|
|
|
/// Update masternode list and maps using provided CMasternodeBroadcast
|
|
|
|
void UpdateMasternodeList(CMasternodeBroadcast mnb);
|
2016-03-18 00:37:48 +01:00
|
|
|
/// Perform complete check and only then update list and maps
|
|
|
|
bool CheckMnbAndUpdateMasternodeList(CMasternodeBroadcast mnb, int& nDos);
|
2016-03-16 16:30:22 +01:00
|
|
|
|
2016-11-28 15:21:50 +01:00
|
|
|
void UpdateLastPaid();
|
2016-10-17 20:54:28 +02:00
|
|
|
|
2016-11-13 18:52:34 +01:00
|
|
|
void CheckAndRebuildMasternodeIndex();
|
|
|
|
|
2016-10-17 20:54:28 +02:00
|
|
|
void AddDirtyGovernanceObjectHash(const uint256& nHash)
|
|
|
|
{
|
|
|
|
LOCK(cs);
|
|
|
|
vecDirtyGovernanceObjectHashes.push_back(nHash);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<uint256> GetAndClearDirtyGovernanceObjectHashes()
|
|
|
|
{
|
|
|
|
LOCK(cs);
|
|
|
|
std::vector<uint256> vecTmp = vecDirtyGovernanceObjectHashes;
|
|
|
|
vecDirtyGovernanceObjectHashes.clear();
|
|
|
|
return vecTmp;;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsWatchdogActive();
|
|
|
|
void UpdateWatchdogVoteTime(const CTxIn& vin);
|
|
|
|
void AddGovernanceVote(const CTxIn& vin, uint256 nGovernanceObjectHash);
|
|
|
|
void RemoveGovernanceObject(uint256 nGovernanceObjectHash);
|
|
|
|
|
|
|
|
void CheckMasternode(const CTxIn& vin, bool fForce = false);
|
|
|
|
void CheckMasternode(const CPubKey& pubKeyMasternode, bool fForce = false);
|
|
|
|
|
|
|
|
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);
|
2016-10-20 23:11:30 +02:00
|
|
|
|
|
|
|
void UpdatedBlockTip(const CBlockIndex *pindex);
|
2016-11-13 18:52:34 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Called to notify CGovernanceManager that the masternode index has been updated.
|
|
|
|
* Must be called while not holding the CMasternodeMan::cs mutex
|
|
|
|
*/
|
|
|
|
void NotifyMasternodeUpdates();
|
|
|
|
|
2015-02-23 21:01:21 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|