Dash Core  0.12.2.1
P2P Digital Currency
governance.h
Go to the documentation of this file.
1 // Copyright (c) 2014-2017 The Dash Core developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef GOVERNANCE_H
6 #define GOVERNANCE_H
7 
8 //#define ENABLE_DASH_DEBUG
9 
10 #include "bloom.h"
11 #include "cachemap.h"
12 #include "cachemultimap.h"
13 #include "chain.h"
14 #include "governance-exceptions.h"
15 #include "governance-object.h"
16 #include "governance-vote.h"
17 #include "net.h"
18 #include "sync.h"
19 #include "timedata.h"
20 #include "util.h"
21 
22 class CGovernanceManager;
24 class CGovernanceObject;
25 class CGovernanceVote;
26 
28 
30  ExpirationInfo(int64_t _nExpirationTime, int _idFrom) : nExpirationTime(_nExpirationTime), idFrom(_idFrom) {}
31 
32  int64_t nExpirationTime;
34 };
35 
36 typedef std::pair<CGovernanceObject, ExpirationInfo> object_info_pair_t;
37 
38 static const int RATE_BUFFER_SIZE = 5;
39 
41 private:
42  std::vector<int64_t> vecTimestamps;
43 
45 
46  int nDataEnd;
47 
49 
50 public:
53  nDataStart(0),
54  nDataEnd(0),
55  fBufferEmpty(true)
56  {}
57 
58  void AddTimestamp(int64_t nTimestamp)
59  {
60  if((nDataEnd == nDataStart) && !fBufferEmpty) {
61  // Buffer full, discard 1st element
63  }
64  vecTimestamps[nDataEnd] = nTimestamp;
66  fBufferEmpty = false;
67  }
68 
69  int64_t GetMinTimestamp()
70  {
71  int nIndex = nDataStart;
72  int64_t nMin = numeric_limits<int64_t>::max();
73  if(fBufferEmpty) {
74  return nMin;
75  }
76  do {
77  if(vecTimestamps[nIndex] < nMin) {
78  nMin = vecTimestamps[nIndex];
79  }
80  nIndex = (nIndex + 1) % RATE_BUFFER_SIZE;
81  } while(nIndex != nDataEnd);
82  return nMin;
83  }
84 
85  int64_t GetMaxTimestamp()
86  {
87  int nIndex = nDataStart;
88  int64_t nMax = 0;
89  if(fBufferEmpty) {
90  return nMax;
91  }
92  do {
93  if(vecTimestamps[nIndex] > nMax) {
94  nMax = vecTimestamps[nIndex];
95  }
96  nIndex = (nIndex + 1) % RATE_BUFFER_SIZE;
97  } while(nIndex != nDataEnd);
98  return nMax;
99  }
100 
101  int GetCount()
102  {
103  int nCount = 0;
104  if(fBufferEmpty) {
105  return 0;
106  }
107  if(nDataEnd > nDataStart) {
108  nCount = nDataEnd - nDataStart;
109  }
110  else {
111  nCount = RATE_BUFFER_SIZE - nDataStart + nDataEnd;
112  }
113 
114  return nCount;
115  }
116 
117  double GetRate()
118  {
119  int nCount = GetCount();
120  if(nCount < RATE_BUFFER_SIZE) {
121  return 0.0;
122  }
123  int64_t nMin = GetMinTimestamp();
124  int64_t nMax = GetMaxTimestamp();
125  if(nMin == nMax) {
126  // multiple objects with the same timestamp => infinite rate
127  return 1.0e10;
128  }
129  return double(nCount) / double(nMax - nMin);
130  }
131 
133 
134  template <typename Stream, typename Operation>
135  inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
136  {
141  }
142 };
143 
144 //
145 // Governance Manager : Contains all proposals for the budget
146 //
148 {
149  friend class CGovernanceObject;
150 
151 public: // Types
153  last_object_rec(bool fStatusOKIn = true)
154  : triggerBuffer(),
155  watchdogBuffer(),
156  fStatusOK(fStatusOKIn)
157  {}
158 
160 
161  template <typename Stream, typename Operation>
162  inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion)
163  {
167  }
168 
171  bool fStatusOK;
172  };
173 
174 
175  typedef std::map<uint256, CGovernanceObject> object_m_t;
176 
177  typedef object_m_t::iterator object_m_it;
178 
179  typedef object_m_t::const_iterator object_m_cit;
180 
182 
183  typedef std::map<uint256, CGovernanceVote> vote_m_t;
184 
185  typedef vote_m_t::iterator vote_m_it;
186 
187  typedef vote_m_t::const_iterator vote_m_cit;
188 
190 
192 
193  typedef object_m_t::size_type size_type;
194 
195  typedef std::map<COutPoint, last_object_rec > txout_m_t;
196 
197  typedef txout_m_t::iterator txout_m_it;
198 
199  typedef txout_m_t::const_iterator txout_m_cit;
200 
201  typedef std::map<COutPoint, int> txout_int_m_t;
202 
203  typedef std::set<uint256> hash_s_t;
204 
205  typedef hash_s_t::iterator hash_s_it;
206 
207  typedef hash_s_t::const_iterator hash_s_cit;
208 
209  typedef std::map<uint256, object_info_pair_t> object_info_m_t;
210 
211  typedef object_info_m_t::iterator object_info_m_it;
212 
213  typedef object_info_m_t::const_iterator object_info_m_cit;
214 
215  typedef std::map<uint256, int64_t> hash_time_m_t;
216 
217  typedef hash_time_m_t::iterator hash_time_m_it;
218 
219  typedef hash_time_m_t::const_iterator hash_time_m_cit;
220 
221 private:
222  static const int MAX_CACHE_SIZE = 1000000;
223 
224  static const std::string SERIALIZATION_VERSION_STRING;
225 
226  static const int MAX_TIME_FUTURE_DEVIATION;
227  static const int RELIABLE_PROPAGATION_TIME;
228 
229  int64_t nTimeLastDiff;
230 
231  // keep track of current block height
233 
234  // keep track of the scanning errors
236 
237  // mapErasedGovernanceObjects contains key-value pairs, where
238  // key - governance object's hash
239  // value - expiration time for deleted objects
241 
244 
247 
249 
251 
253 
255 
257 
259 
261 
263 
265 
267 
269  {
270  bool& ref;
272 
273  public:
274  ScopedLockBool(CCriticalSection& _cs, bool& _ref, bool _value) : ref(_ref)
275  {
276  AssertLockHeld(_cs);
277  fPrevValue = ref;
278  ref = _value;
279  }
280 
282  {
283  ref = fPrevValue;
284  }
285  };
286 
287 public:
288  // critical section to protect the inner data structures
290 
292 
293  virtual ~CGovernanceManager() {}
294 
300  bool ConfirmInventoryRequest(const CInv& inv);
301 
302  void Sync(CNode* node, const uint256& nProp, const CBloomFilter& filter, CConnman& connman);
303 
304  void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, CConnman& connman);
305 
306  void DoMaintenance(CConnman& connman);
307 
309 
310  std::vector<CGovernanceVote> GetMatchingVotes(const uint256& nParentHash);
311  std::vector<CGovernanceVote> GetCurrentVotes(const uint256& nParentHash, const COutPoint& mnCollateralOutpointFilter);
312  std::vector<CGovernanceObject*> GetAllNewerThan(int64_t nMoreThanTime);
313 
314  bool IsBudgetPaymentBlock(int nBlockHeight);
315  void AddGovernanceObject(CGovernanceObject& govobj, CConnman& connman, CNode* pfrom = NULL);
316 
317  std::string GetRequiredPaymentsString(int nBlockHeight);
318 
319  void UpdateCachesAndClean();
320 
322 
323  void Clear()
324  {
325  LOCK(cs);
326 
327  LogPrint("gobject", "Governance object manager was cleared\n");
328  mapObjects.clear();
330  mapWatchdogObjects.clear();
336  mapLastMasternodeObject.clear();
337  }
338 
339  std::string ToString() const;
340 
342 
343  template <typename Stream, typename Operation>
344  inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
345  LOCK(cs);
346  std::string strVersion;
347  if(ser_action.ForRead()) {
348  READWRITE(strVersion);
349  }
350  else {
351  strVersion = SERIALIZATION_VERSION_STRING;
352  READWRITE(strVersion);
353  }
354 
363  if(ser_action.ForRead() && (strVersion != SERIALIZATION_VERSION_STRING)) {
364  Clear();
365  return;
366  }
367  }
368 
369  void UpdatedBlockTip(const CBlockIndex *pindex, CConnman& connman);
370  int64_t GetLastDiffTime() { return nTimeLastDiff; }
371  void UpdateLastDiffTime(int64_t nTimeIn) { nTimeLastDiff = nTimeIn; }
372 
374 
375  // Accessors for thread-safe access to maps
376  bool HaveObjectForHash(uint256 nHash);
377 
378  bool HaveVoteForHash(uint256 nHash);
379 
380  int GetVoteCount() const;
381 
382  bool SerializeObjectForHash(uint256 nHash, CDataStream& ss);
383 
384  bool SerializeVoteForHash(uint256 nHash, CDataStream& ss);
385 
387  {
388  LOCK(cs);
389  mapPostponedObjects.insert(std::make_pair(govobj.GetHash(), govobj));
390  }
391 
392  void AddSeenGovernanceObject(uint256 nHash, int status);
393 
394  void AddSeenVote(uint256 nHash, int status);
395 
396  void MasternodeRateUpdate(const CGovernanceObject& govobj);
397 
398  bool MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateFailStatus = false);
399 
400  bool MasternodeRateCheck(const CGovernanceObject& govobj, bool fUpdateFailStatus, bool fForce, bool& fRateCheckBypassed);
401 
402  bool ProcessVoteAndRelay(const CGovernanceVote& vote, CGovernanceException& exception, CConnman& connman) {
403  bool fOK = ProcessVote(NULL, vote, exception, connman);
404  if(fOK) {
405  vote.Relay(connman);
406  }
407  return fOK;
408  }
409 
410  void CheckMasternodeOrphanVotes(CConnman& connman);
411 
412  void CheckMasternodeOrphanObjects(CConnman& connman);
413 
414  void CheckPostponedObjects(CConnman& connman);
415 
416  bool AreRateChecksEnabled() const {
417  LOCK(cs);
418  return fRateChecksEnabled;
419  }
420 
421  void InitOnLoad();
422 
423  int RequestGovernanceObjectVotes(CNode* pnode, CConnman& connman);
424  int RequestGovernanceObjectVotes(const std::vector<CNode*>& vNodesCopy, CConnman& connman);
425 
426 private:
427  void RequestGovernanceObject(CNode* pfrom, const uint256& nHash, CConnman& connman, bool fUseFilter = false);
428 
429  void AddInvalidVote(const CGovernanceVote& vote)
430  {
431  mapInvalidVotes.Insert(vote.GetHash(), vote);
432  }
433 
434  void AddOrphanVote(const CGovernanceVote& vote)
435  {
437  }
438 
439  bool ProcessVote(CNode* pfrom, const CGovernanceVote& vote, CGovernanceException& exception, CConnman& connman);
440 
442  bool AcceptObjectMessage(const uint256& nHash);
443 
445  bool AcceptVoteMessage(const uint256& nHash);
446 
447  static bool AcceptMessage(const uint256& nHash, hash_s_t& setHash);
448 
449  void CheckOrphanVotes(CGovernanceObject& govobj, CGovernanceException& exception, CConnman& connman);
450 
451  void RebuildIndexes();
452 
453  void AddCachedTriggers();
454 
455  bool UpdateCurrentWatchdog(CGovernanceObject& watchdogNew);
456 
457  void RequestOrphanObjects(CConnman& connman);
458 
459  void CleanOrphanObjects();
460 
461 };
462 
463 #endif
std::vector< CGovernanceObject * > GetAllNewerThan(int64_t nMoreThanTime)
Definition: governance.cpp:623
static const std::string SERIALIZATION_VERSION_STRING
Definition: governance.h:224
bool IsBudgetPaymentBlock(int nBlockHeight)
int RequestGovernanceObjectVotes(CNode *pnode, CConnman &connman)
NodeId idFrom
Definition: governance.h:33
bool AreRateChecksEnabled() const
Definition: governance.h:416
static const int RATE_BUFFER_SIZE
Definition: governance.h:38
void AddSeenGovernanceObject(uint256 nHash, int status)
hash_time_m_t mapErasedGovernanceObjects
Definition: governance.h:240
bool AcceptObjectMessage(const uint256 &nHash)
Called to indicate a requested object has been received.
bool ProcessVoteAndRelay(const CGovernanceVote &vote, CGovernanceException &exception, CConnman &connman)
Definition: governance.h:402
void AddOrphanVote(const CGovernanceVote &vote)
Definition: governance.h:434
void AddSeenVote(uint256 nHash, int status)
object_info_m_t mapMasternodeOrphanObjects
Definition: governance.h:242
static const int64_t GOVERNANCE_ORPHAN_EXPIRATION_TIME
#define READWRITE(obj)
Definition: serialize.h:175
object_info_m_t::iterator object_info_m_it
Definition: governance.h:211
std::map< uint256, CGovernanceVote > vote_m_t
Definition: governance.h:183
bool Insert(const K &key, const V &value)
Definition: cachemultimap.h:92
std::pair< CGovernanceVote, int64_t > vote_time_pair_t
static const int MAX_CACHE_SIZE
Definition: governance.h:222
void CheckOrphanVotes(CGovernanceObject &govobj, CGovernanceException &exception, CConnman &connman)
Definition: governance.cpp:274
bool HaveObjectForHash(uint256 nHash)
Definition: governance.cpp:44
hash_s_t::iterator hash_s_it
Definition: governance.h:205
void RequestOrphanObjects(CConnman &connman)
hash_time_m_t::const_iterator hash_time_m_cit
Definition: governance.h:219
virtual ~CGovernanceManager()
Definition: governance.h:293
std::vector< CGovernanceVote > GetCurrentVotes(const uint256 &nParentHash, const COutPoint &mnCollateralOutpointFilter)
Definition: governance.cpp:583
vote_mcache_t mapOrphanVotes
Definition: governance.h:258
CGovernanceObject * FindGovernanceObject(const uint256 &nHash)
Definition: governance.cpp:559
int GetVoteCount() const
Definition: governance.cpp:77
std::vector< CGovernanceVote > GetMatchingVotes(const uint256 &nParentHash)
Definition: governance.cpp:569
txout_m_t::iterator txout_m_it
Definition: governance.h:197
std::pair< CGovernanceObject, ExpirationInfo > object_info_pair_t
Definition: governance.h:36
hash_s_t setRequestedVotes
Definition: governance.h:264
last_object_rec(bool fStatusOKIn=true)
Definition: governance.h:153
Definition: net.h:108
hash_s_t setRequestedObjects
Definition: governance.h:262
void CheckPostponedObjects(CConnman &connman)
object_ref_cache_t mapVoteToObject
Definition: governance.h:254
bool ProcessVote(CNode *pfrom, const CGovernanceVote &vote, CGovernanceException &exception, CConnman &connman)
Definition: governance.cpp:929
bool SerializeVoteForHash(uint256 nHash, CDataStream &ss)
Definition: governance.cpp:83
int64_t nTimeWatchdogCurrent
Definition: governance.h:252
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
Definition: governance.cpp:101
hash_time_m_t mapWatchdogObjects
Definition: governance.h:248
void UpdateLastDiffTime(int64_t nTimeIn)
Definition: governance.h:371
void Clear()
Definition: cachemap.h:91
uint256 GetHash() const
int64_t GetMaxTimestamp()
Definition: governance.h:85
object_m_t mapObjects
Definition: governance.h:235
txout_m_t::const_iterator txout_m_cit
Definition: governance.h:199
void RequestGovernanceObject(CNode *pfrom, const uint256 &nHash, CConnman &connman, bool fUseFilter=false)
bool ConfirmInventoryRequest(const CInv &inv)
Definition: governance.cpp:678
#define AssertLockHeld(cs)
Definition: sync.h:96
uint256 nHashWatchdogCurrent
Definition: governance.h:250
CGovernanceManager governance
Definition: governance.cpp:17
bool MasternodeRateCheck(const CGovernanceObject &govobj, bool fUpdateFailStatus=false)
Definition: governance.cpp:842
static const int RELIABLE_PROPAGATION_TIME
Definition: governance.h:227
bool AcceptVoteMessage(const uint256 &nHash)
Called to indicate a requested vote has been received.
object_m_t::iterator object_m_it
Definition: governance.h:177
hash_s_t setAdditionalRelayObjects
Definition: governance.h:246
void Insert(const K &key, const V &value)
Definition: cachemap.h:111
Definition: net.h:661
static int LogPrint(const char *category, const char *format)
Definition: util.h:126
#define LOCK(cs)
Definition: sync.h:168
object_m_t::size_type size_type
Definition: governance.h:193
void AddTimestamp(int64_t nTimestamp)
Definition: governance.h:58
vote_m_t::iterator vote_m_it
Definition: governance.h:185
static const int MAX_TIME_FUTURE_DEVIATION
Definition: governance.h:226
void AddPostponedObject(const CGovernanceObject &govobj)
Definition: governance.h:386
int64_t nTimeLastDiff
Definition: governance.h:229
void UpdatedBlockTip(const CBlockIndex *pindex, CConnman &connman)
void Sync(CNode *node, const uint256 &nProp, const CBloomFilter &filter, CConnman &connman)
Definition: governance.cpp:733
bool SerializeObjectForHash(uint256 nHash, CDataStream &ss)
Definition: governance.cpp:49
CacheMap< uint256, CGovernanceVote > vote_cache_t
Definition: governance.h:189
CacheMap< uint256, CGovernanceObject * > object_ref_cache_t
Definition: governance.h:181
double GetRate()
Definition: governance.h:117
static bool AcceptMessage(const uint256 &nHash, hash_s_t &setHash)
bool UpdateCurrentWatchdog(CGovernanceObject &watchdogNew)
Definition: governance.cpp:391
void DoMaintenance(CConnman &connman)
Definition: governance.cpp:663
std::map< uint256, object_info_pair_t > object_info_m_t
Definition: governance.h:209
std::set< uint256 > hash_s_t
Definition: governance.h:203
void UpdateCachesAndClean()
Definition: governance.cpp:425
void MasternodeRateUpdate(const CGovernanceObject &govobj)
Definition: governance.cpp:816
void AddInvalidVote(const CGovernanceVote &vote)
Definition: governance.h:429
std::map< COutPoint, int > txout_int_m_t
Definition: governance.h:201
CacheMultiMap< uint256, vote_time_pair_t > vote_mcache_t
Definition: governance.h:191
std::map< COutPoint, last_object_rec > txout_m_t
Definition: governance.h:195
void CheckMasternodeOrphanObjects(CConnman &connman)
Definition: governance.cpp:996
void CheckMasternodeOrphanVotes(CConnman &connman)
Definition: governance.cpp:985
std::string GetRequiredPaymentsString(int nBlockHeight)
int64_t GetMinTimestamp()
Definition: governance.h:69
txout_m_t mapLastMasternodeObject
Definition: governance.h:260
int64_t nExpirationTime
Definition: governance.h:32
void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)
Definition: governance.h:162
ExpirationInfo(int64_t _nExpirationTime, int _idFrom)
Definition: governance.h:30
int64_t GetAdjustedTime()
Definition: timedata.cpp:33
int NodeId
Definition: net.h:94
std::vector< int64_t > vecTimestamps
Definition: governance.h:42
vote_cache_t mapInvalidVotes
Definition: governance.h:256
hash_s_t::const_iterator hash_s_cit
Definition: governance.h:207
int GetCachedBlockHeight()
Definition: governance.h:373
object_m_t::const_iterator object_m_cit
Definition: governance.h:179
txout_int_m_t mapMasternodeOrphanCounter
Definition: governance.h:243
Definition: protocol.h:314
ScopedLockBool(CCriticalSection &_cs, bool &_ref, bool _value)
Definition: governance.h:274
bool HaveVoteForHash(uint256 nHash)
Definition: governance.cpp:62
void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)
Definition: governance.h:344
virtual uint256 GetHash()=0
void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)
Definition: governance.h:135
object_info_m_t::const_iterator object_info_m_cit
Definition: governance.h:213
std::map< uint256, CGovernanceObject > object_m_t
Definition: governance.h:175
void AddGovernanceObject(CGovernanceObject &govobj, CConnman &connman, CNode *pfrom=NULL)
Definition: governance.cpp:301
void Relay(CConnman &connman) const
vote_m_t::const_iterator vote_m_cit
Definition: governance.h:187
hash_time_m_t::iterator hash_time_m_it
Definition: governance.h:217
CCriticalSection cs
Definition: governance.h:289
std::map< uint256, int64_t > hash_time_m_t
Definition: governance.h:215
std::string ToString() const
int64_t GetLastDiffTime()
Definition: governance.h:370
object_m_t mapPostponedObjects
Definition: governance.h:245