LCOV - code coverage report
Current view: top level - src - masternodeman.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 14 14 100.0 %
Date: 2025-02-23 09:33:43 Functions: 3 4 75.0 %

          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

Generated by: LCOV version 1.14