dash/src/governance.h
Tim Flynn 4dac0025a7 Governance relaying fixes (#1195)
* Vote relaying changes
 - Remove vote relaying from ProcessVote
 - Remove vote relaying from orphan vote processing
 - Relay vote in ProcessMessages (only)

* Do not relay governance objects during orphan processing

* Restore relaying of local votes

* Changed overloaded function name: ProcessVote->ProcessVoteAndRelay
2016-12-07 08:16:34 +04:00

296 lines
7.9 KiB
C++

// 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 <boost/lexical_cast.hpp>
#include "init.h"
#include <univalue.h>
#include "utilstrencodings.h"
#include "cachemap.h"
#include "cachemultimap.h"
#include <stdio.h>
#include <string.h>
class CGovernanceManager;
class CGovernanceTriggerManager;
class CGovernanceObject;
class CGovernanceVote;
extern std::map<uint256, int64_t> mapAskedForGovernanceObject;
extern CGovernanceManager governance;
typedef std::pair<CGovernanceObject, int64_t> object_time_pair_t;
//
// Governance Manager : Contains all proposals for the budget
//
class CGovernanceManager
{
friend class CGovernanceObject;
public: // Types
typedef std::map<uint256, CGovernanceObject> object_m_t;
typedef object_m_t::iterator object_m_it;
typedef object_m_t::const_iterator object_m_cit;
typedef CacheMap<uint256, CGovernanceObject*> object_ref_cache_t;
typedef std::map<uint256, int> count_m_t;
typedef count_m_t::iterator count_m_it;
typedef count_m_t::const_iterator count_m_cit;
typedef std::map<uint256, CGovernanceVote> vote_m_t;
typedef vote_m_t::iterator vote_m_it;
typedef vote_m_t::const_iterator vote_m_cit;
typedef CacheMap<uint256, CGovernanceVote> vote_cache_t;
typedef CacheMultiMap<uint256, vote_time_pair_t> vote_mcache_t;
typedef object_m_t::size_type size_type;
typedef std::map<COutPoint, int> txout_m_t;
typedef txout_m_t::iterator txout_m_it;
typedef txout_m_t::const_iterator txout_m_cit;
typedef std::set<uint256> hash_s_t;
typedef hash_s_t::iterator hash_s_it;
typedef hash_s_t::const_iterator hash_s_cit;
typedef std::map<uint256, object_time_pair_t> 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<uint256, int64_t> 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() {}
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<CGovernanceVote> GetMatchingVotes(const uint256& nParentHash);
std::vector<CGovernanceVote> GetCurrentVotes(const uint256& nParentHash, const CTxIn& mnCollateralOutpointFilter);
std::vector<CGovernanceObject*> 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();
mapWatchdogObjects.clear();
mapVoteToObject.Clear();
mapInvalidVotes.Clear();
mapOrphanVotes.Clear();
mapLastMasternodeTrigger.clear();
}
std::string ToString() const;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
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(mapWatchdogObjects);
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 ProcessVoteAndRelay(const CGovernanceVote& vote, CGovernanceException& exception) {
bool fOK = ProcessVote(NULL, vote, exception);
if(fOK) {
vote.Relay();
}
return fOK;
}
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(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