// Copyright (c) 2014-2016 The Dash Core developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef GOVERNANCE_H #define GOVERNANCE_H //#define ENABLE_DASH_DEBUG #include "util.h" #include "main.h" #include "sync.h" #include "net.h" #include "key.h" #include "util.h" #include "base58.h" #include "governance-object.h" #include "masternode.h" #include "governance-exceptions.h" #include "governance-vote.h" #include "governance-votedb.h" #include "masternodeman.h" #include #include "init.h" #include #include "utilstrencodings.h" #include "cachemap.h" #include "cachemultimap.h" #include #include class CGovernanceManager; class CGovernanceTriggerManager; class CGovernanceObject; class CGovernanceVote; extern std::map mapAskedForGovernanceObject; extern CGovernanceManager governance; typedef std::pair object_time_pair_t; // // Governance Manager : Contains all proposals for the budget // class CGovernanceManager { friend class CGovernanceObject; public: // Types typedef std::map object_m_t; typedef object_m_t::iterator object_m_it; typedef object_m_t::const_iterator object_m_cit; typedef CacheMap object_ref_cache_t; typedef std::map count_m_t; typedef count_m_t::iterator count_m_it; typedef count_m_t::const_iterator count_m_cit; typedef std::map vote_m_t; typedef vote_m_t::iterator vote_m_it; typedef vote_m_t::const_iterator vote_m_cit; typedef CacheMap vote_cache_t; typedef CacheMultiMap vote_mcache_t; typedef object_m_t::size_type size_type; typedef std::map txout_m_t; typedef txout_m_t::iterator txout_m_it; typedef txout_m_t::const_iterator txout_m_cit; typedef std::set hash_s_t; typedef hash_s_t::iterator hash_s_it; typedef hash_s_t::const_iterator hash_s_cit; typedef std::map object_time_m_t; typedef object_time_m_t::iterator object_time_m_it; typedef object_time_m_t::const_iterator object_time_m_cit; typedef std::map hash_time_m_t; typedef hash_time_m_t::iterator hash_time_m_it; typedef hash_time_m_t::const_iterator hash_time_m_cit; private: static const int MAX_CACHE_SIZE = 1000000; static const std::string SERIALIZATION_VERSION_STRING; // Keep track of current block index const CBlockIndex *pCurrentBlockIndex; int64_t nTimeLastDiff; int nCachedBlockHeight; // keep track of the scanning errors object_m_t mapObjects; count_m_t mapSeenGovernanceObjects; object_time_m_t mapMasternodeOrphanObjects; hash_time_m_t mapWatchdogObjects; object_ref_cache_t mapVoteToObject; vote_cache_t mapInvalidVotes; vote_mcache_t mapOrphanVotes; txout_m_t mapLastMasternodeTrigger; hash_s_t setRequestedObjects; hash_s_t setRequestedVotes; bool fRateChecksEnabled; public: // critical section to protect the inner data structures mutable CCriticalSection cs; CGovernanceManager(); virtual ~CGovernanceManager() {} void ClearSeen() { LOCK(cs); mapSeenGovernanceObjects.clear(); } int CountProposalInventoryItems() { // TODO What is this for ? return mapSeenGovernanceObjects.size(); //return mapSeenGovernanceObjects.size() + mapSeenVotes.size(); } /** * This is called by AlreadyHave in main.cpp as part of the inventory * retrieval process. Returns true if we want to retrieve the object, otherwise * false. (Note logic is inverted in AlreadyHave). */ bool ConfirmInventoryRequest(const CInv& inv); void Sync(CNode* node, uint256 nProp); void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv); void NewBlock(); CGovernanceObject *FindGovernanceObject(const uint256& nHash); std::vector GetMatchingVotes(const uint256& nParentHash); std::vector GetCurrentVotes(const uint256& nParentHash, const CTxIn& mnCollateralOutpointFilter); std::vector GetAllNewerThan(int64_t nMoreThanTime); bool IsBudgetPaymentBlock(int nBlockHeight); bool AddGovernanceObject (CGovernanceObject& govobj); std::string GetRequiredPaymentsString(int nBlockHeight); void UpdateCachesAndClean(); void CheckAndRemove() {UpdateCachesAndClean();} void Clear() { LOCK(cs); LogPrint("gobject", "Governance object manager was cleared\n"); mapObjects.clear(); mapSeenGovernanceObjects.clear(); mapVoteToObject.Clear(); mapInvalidVotes.Clear(); mapOrphanVotes.Clear(); mapLastMasternodeTrigger.clear(); } std::string ToString() const; ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { LOCK(cs); std::string strVersion; if(ser_action.ForRead()) { READWRITE(strVersion); } else { strVersion = SERIALIZATION_VERSION_STRING; READWRITE(strVersion); } READWRITE(mapSeenGovernanceObjects); READWRITE(mapInvalidVotes); READWRITE(mapOrphanVotes); READWRITE(mapObjects); READWRITE(mapLastMasternodeTrigger); if(ser_action.ForRead() && (strVersion != SERIALIZATION_VERSION_STRING)) { Clear(); return; } } void UpdatedBlockTip(const CBlockIndex *pindex); int64_t GetLastDiffTime() { return nTimeLastDiff; } void UpdateLastDiffTime(int64_t nTimeIn) { nTimeLastDiff = nTimeIn; } int GetCachedBlockHeight() { return nCachedBlockHeight; } // Accessors for thread-safe access to maps bool HaveObjectForHash(uint256 nHash); bool HaveVoteForHash(uint256 nHash); bool SerializeObjectForHash(uint256 nHash, CDataStream& ss); bool SerializeVoteForHash(uint256 nHash, CDataStream& ss); void AddSeenGovernanceObject(uint256 nHash, int status); void AddSeenVote(uint256 nHash, int status); bool MasternodeRateCheck(const CTxIn& vin, int nObjectType); bool ProcessVote(const CGovernanceVote& vote, CGovernanceException& exception) { return ProcessVote(NULL, vote, exception); } void CheckMasternodeOrphanVotes(); void CheckMasternodeOrphanObjects(); bool AreRateChecksEnabled() const { LOCK(cs); return fRateChecksEnabled; } void InitOnLoad(); private: void RequestGovernanceObject(CNode* pfrom, const uint256& nHash); void AddInvalidVote(const CGovernanceVote& vote) { mapInvalidVotes.Insert(vote.GetHash(), vote); } void AddOrphanVote(const CGovernanceVote& vote) { mapOrphanVotes.Insert(vote.GetHash(), vote_time_pair_t(vote, GetAdjustedTime() + GOVERNANCE_ORPHAN_EXPIRATION_TIME)); } bool ProcessVote(CNode* pfrom, const CGovernanceVote& vote, CGovernanceException& exception); /// Called to indicate a requested object has been received bool AcceptObjectMessage(const uint256& nHash); /// Called to indicate a requested vote has been received bool AcceptVoteMessage(const uint256& nHash); static bool AcceptMessage(const uint256& nHash, hash_s_t& setHash); void CheckOrphanVotes(CNode* pfrom, CGovernanceObject& govobj, CGovernanceException& exception); void RebuildIndexes(); /// Returns MN index, handling the case of index rebuilds int GetMasternodeIndex(const CTxIn& masternodeVin); void RebuildVoteMaps(); void AddCachedTriggers(); }; #endif