Line data Source code
1 : // Copyright (c) 2014-2015 The Dash developers 2 : // Copyright (c) 2015-2021 The PIVX Core developers 3 : // Distributed under the MIT/X11 software license, see the accompanying 4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 : 6 : #ifndef PIVX_MASTERNODEMAN_H 7 : #define PIVX_MASTERNODEMAN_H 8 : 9 : #include "activemasternode.h" 10 : #include "cyclingvector.h" 11 : #include "key.h" 12 : #include "key_io.h" 13 : #include "masternode.h" 14 : #include "net.h" 15 : #include "sync.h" 16 : #include "util/system.h" 17 : 18 : #define MASTERNODES_REQUEST_SECONDS (60 * 60) // One hour. 19 : 20 : /** Maximum number of block hashes to cache */ 21 : static const unsigned int CACHED_BLOCK_HASHES = 200; 22 : 23 : class CMasternodeMan; 24 : class CActiveMasternode; 25 : 26 : extern CMasternodeMan mnodeman; 27 : extern CActiveMasternode activeMasternode; 28 : 29 : void DumpMasternodes(); 30 : 31 : /** Access to the MN database (mncache.dat) 32 : */ 33 : class CMasternodeDB 34 : { 35 : private: 36 : fs::path pathMN; 37 : std::string strMagicMessage; 38 : 39 : public: 40 : enum ReadResult { 41 : Ok, 42 : FileError, 43 : HashReadError, 44 : IncorrectHash, 45 : IncorrectMagicMessage, 46 : IncorrectMagicNumber, 47 : IncorrectFormat 48 : }; 49 : 50 : CMasternodeDB(); 51 : bool Write(const CMasternodeMan& mnodemanToSave); 52 : ReadResult Read(CMasternodeMan& mnodemanToLoad); 53 : }; 54 : 55 : 56 : class CMasternodeMan 57 : { 58 : private: 59 : // critical section to protect the inner data structures 60 : mutable RecursiveMutex cs; 61 : 62 : // critical section to protect the inner data structures specifically on messaging 63 : mutable RecursiveMutex cs_process_message; 64 : 65 : // map to hold all MNs (indexed by collateral outpoint) 66 : std::map<COutPoint, MasternodeRef> mapMasternodes; 67 : // who's asked for the Masternode list and the last time 68 : std::map<CNetAddr, int64_t> mAskedUsForMasternodeList; 69 : // who we asked for the Masternode list and the last time 70 : std::map<CNetAddr, int64_t> mWeAskedForMasternodeList; 71 : // which Masternodes we've asked for 72 : std::map<COutPoint, int64_t> mWeAskedForMasternodeListEntry; 73 : 74 : // Memory Only. Updated in NewBlock (blocks arrive in order) 75 : std::atomic<int> nBestHeight; 76 : 77 : // Memory Only. Cache last block hashes. Used to verify mn pings and winners. 78 : CyclingVector<uint256> cvLastBlockHashes; 79 : 80 : // Return the banning score (0 if no ban score increase is needed). 81 : int ProcessMNBroadcast(CNode* pfrom, CMasternodeBroadcast& mnb); 82 : int ProcessMNPing(CNode* pfrom, CMasternodePing& mnp); 83 : int ProcessMessageInner(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); 84 : 85 : // Relay a MN 86 : void BroadcastInvMN(CMasternode* mn, CNode* pfrom); 87 : 88 : // Validation 89 : bool CheckInputs(CMasternodeBroadcast& mnb, int nChainHeight, int& nDoS); 90 : 91 : public: 92 : // Keep track of all broadcasts I've seen 93 : std::map<uint256, CMasternodeBroadcast> mapSeenMasternodeBroadcast; 94 : // Keep track of all pings I've seen 95 : std::map<uint256, CMasternodePing> mapSeenMasternodePing; 96 : 97 : // keep track of dsq count to prevent masternodes from gaming obfuscation queue 98 : // TODO: Remove this from serialization 99 : int64_t nDsqCount; 100 : 101 920 : SERIALIZE_METHODS(CMasternodeMan, obj) 102 : { 103 460 : LOCK(obj.cs); 104 460 : READWRITE(obj.mapMasternodes); 105 460 : READWRITE(obj.mAskedUsForMasternodeList); 106 460 : READWRITE(obj.mWeAskedForMasternodeList); 107 460 : READWRITE(obj.mWeAskedForMasternodeListEntry); 108 460 : READWRITE(obj.nDsqCount); 109 : 110 460 : READWRITE(obj.mapSeenMasternodeBroadcast); 111 920 : READWRITE(obj.mapSeenMasternodePing); 112 460 : } 113 : 114 : CMasternodeMan(); 115 : 116 : /// Add an entry 117 : bool Add(CMasternode& mn); 118 : 119 : /// Ask (source) node for mnb 120 : void AskForMN(CNode* pnode, const CTxIn& vin); 121 : 122 : /// Check all Masternodes and remove inactive. Return the total masternode count. 123 : int CheckAndRemove(bool forceExpiredRemoval = false); 124 : 125 : /// Clear Masternode vector 126 : void Clear(); 127 : 128 41962 : void SetBestHeight(int height) { nBestHeight.store(height, std::memory_order_release); }; 129 163754 : int GetBestHeight() const { return nBestHeight.load(std::memory_order_acquire); } 130 : 131 : int CountEnabled(bool only_legacy = false) const; 132 : 133 : bool RequestMnList(CNode* pnode); 134 : 135 : /// Find an entry 136 : CMasternode* Find(const COutPoint& collateralOut); 137 : const CMasternode* Find(const COutPoint& collateralOut) const; 138 : CMasternode* Find(const CPubKey& pubKeyMasternode); 139 : 140 : /// Check all transactions in a block, for spent masternode collateral outpoints (marking them as spent) 141 : void CheckSpentCollaterals(const std::vector<CTransactionRef>& vtx); 142 : 143 : /// Find an entry in the masternode list that is next to be paid 144 : MasternodeRef GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int& nCount, const CBlockIndex* pChainTip = nullptr) const; 145 : 146 : /// Get the winner for this block hash 147 : MasternodeRef GetCurrentMasterNode(const uint256& hash) const; 148 : 149 : /// vector of pairs <masternode winner, height> 150 : std::vector<std::pair<MasternodeRef, int>> GetMnScores(int nLast) const; 151 : 152 : // Retrieve the known masternodes ordered by scoring without checking them. (Only used for listmasternodes RPC call) 153 : std::vector<std::pair<int64_t, MasternodeRef>> GetMasternodeRanks(int nBlockHeight) const; 154 : int GetMasternodeRank(const CTxIn& vin, int64_t nBlockHeight) const; 155 : 156 : bool ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, int& dosScore); 157 : 158 : // Process GETMNLIST message, returning the banning score (if 0, no ban score increase is needed) 159 : int ProcessGetMNList(CNode* pfrom, CTxIn& vin); 160 : 161 : struct MNsInfo { 162 : // All the known MNs 163 : int total{0}; 164 : // enabled MNs eligible for payments. Older than 8000 seconds. 165 : int stableSize{0}; 166 : // MNs enabled. 167 : int enabledSize{0}; 168 : 169 : // Networks 170 : int ipv4{0}; 171 : int ipv6{0}; 172 : int onion{0}; 173 : }; 174 : 175 : // Return an overall status of the MNs list 176 : CMasternodeMan::MNsInfo getMNsInfo() const; 177 : 178 : std::string ToString() const; 179 : 180 : void Remove(const COutPoint& collateralOut); 181 : 182 : /// Update masternode list and maps using provided CMasternodeBroadcast 183 : void UpdateMasternodeList(CMasternodeBroadcast& mnb); 184 : 185 : /// Get the time a masternode was last paid 186 : int64_t GetLastPaid(const MasternodeRef& mn, int count_enabled, const CBlockIndex* BlockReading) const; 187 : int64_t SecondsSincePayment(const MasternodeRef& mn, int count_enabled, const CBlockIndex* BlockReading) const; 188 : 189 : // Block hashes cycling vector management 190 : void CacheBlockHash(const CBlockIndex* pindex); 191 : void UncacheBlockHash(const CBlockIndex* pindex); 192 : uint256 GetHashAtHeight(int nHeight) const; 193 : bool IsWithinDepth(const uint256& nHash, int depth) const; 194 585 : uint256 GetBlockHashToPing() const { return GetHashAtHeight(GetBestHeight() - MNPING_DEPTH); } 195 6 : std::vector<uint256> GetCachedBlocks() const { return cvLastBlockHashes.GetCache(); } 196 : }; 197 : 198 : void ThreadCheckMasternodes(); 199 : 200 : #endif // PIVX_MASTERNODEMAN_H