Dash Core  0.12.2.1
P2P Digital Currency
governance-vote.cpp
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 #include "governance-vote.h"
6 #include "governance-object.h"
7 #include "masternodeman.h"
8 #include "messagesigner.h"
9 #include "util.h"
10 
11 #include <boost/lexical_cast.hpp>
12 
14 {
15  switch(nOutcome)
16  {
17  case VOTE_OUTCOME_NONE:
18  return "NONE"; break;
19  case VOTE_OUTCOME_YES:
20  return "YES"; break;
21  case VOTE_OUTCOME_NO:
22  return "NO"; break;
24  return "ABSTAIN"; break;
25  }
26  return "error";
27 }
28 
30 {
31  string strReturn = "NONE";
32  switch(nSignal)
33  {
34  case VOTE_SIGNAL_NONE:
35  strReturn = "NONE";
36  break;
38  strReturn = "FUNDING";
39  break;
40  case VOTE_SIGNAL_VALID:
41  strReturn = "VALID";
42  break;
43  case VOTE_SIGNAL_DELETE:
44  strReturn = "DELETE";
45  break;
47  strReturn = "ENDORSED";
48  break;
49  case VOTE_SIGNAL_NOOP1:
50  strReturn = "NOOP1";
51  break;
52  case VOTE_SIGNAL_NOOP2:
53  strReturn = "NOOP2";
54  break;
55  case VOTE_SIGNAL_NOOP3:
56  strReturn = "NOOP3";
57  break;
58  case VOTE_SIGNAL_NOOP4:
59  strReturn = "NOOP4";
60  break;
61  case VOTE_SIGNAL_NOOP5:
62  strReturn = "NOOP5";
63  break;
64  case VOTE_SIGNAL_NOOP6:
65  strReturn = "NOOP6";
66  break;
67  case VOTE_SIGNAL_NOOP7:
68  strReturn = "NOOP7";
69  break;
70  case VOTE_SIGNAL_NOOP8:
71  strReturn = "NOOP8";
72  break;
73  case VOTE_SIGNAL_NOOP9:
74  strReturn = "NOOP9";
75  break;
76  case VOTE_SIGNAL_NOOP10:
77  strReturn = "NOOP10";
78  break;
79  case VOTE_SIGNAL_NOOP11:
80  strReturn = "NOOP11";
81  break;
83  strReturn = "CUSTOM1";
84  break;
86  strReturn = "CUSTOM2";
87  break;
89  strReturn = "CUSTOM3";
90  break;
92  strReturn = "CUSTOM4";
93  break;
95  strReturn = "CUSTOM5";
96  break;
98  strReturn = "CUSTOM6";
99  break;
100  case VOTE_SIGNAL_CUSTOM7:
101  strReturn = "CUSTOM7";
102  break;
103  case VOTE_SIGNAL_CUSTOM8:
104  strReturn = "CUSTOM8";
105  break;
106  case VOTE_SIGNAL_CUSTOM9:
107  strReturn = "CUSTOM9";
108  break;
110  strReturn = "CUSTOM10";
111  break;
113  strReturn = "CUSTOM11";
114  break;
116  strReturn = "CUSTOM12";
117  break;
119  strReturn = "CUSTOM13";
120  break;
122  strReturn = "CUSTOM14";
123  break;
125  strReturn = "CUSTOM15";
126  break;
128  strReturn = "CUSTOM16";
129  break;
131  strReturn = "CUSTOM17";
132  break;
134  strReturn = "CUSTOM18";
135  break;
137  strReturn = "CUSTOM19";
138  break;
140  strReturn = "CUSTOM20";
141  break;
142  }
143 
144  return strReturn;
145 }
146 
147 
149 {
151  if(strVoteOutcome == "yes") {
152  eVote = VOTE_OUTCOME_YES;
153  }
154  else if(strVoteOutcome == "no") {
155  eVote = VOTE_OUTCOME_NO;
156  }
157  else if(strVoteOutcome == "abstain") {
158  eVote = VOTE_OUTCOME_ABSTAIN;
159  }
160  return eVote;
161 }
162 
164 {
166  if(strVoteSignal == "funding") {
167  eSignal = VOTE_SIGNAL_FUNDING;
168  }
169  else if(strVoteSignal == "valid") {
170  eSignal = VOTE_SIGNAL_VALID;
171  }
172  if(strVoteSignal == "delete") {
173  eSignal = VOTE_SIGNAL_DELETE;
174  }
175  if(strVoteSignal == "endorsed") {
176  eSignal = VOTE_SIGNAL_ENDORSED;
177  }
178 
179  if(eSignal != VOTE_SIGNAL_NONE) {
180  return eSignal;
181  }
182 
183  // ID FIVE THROUGH CUSTOM_START ARE TO BE USED BY GOVERNANCE ENGINE / TRIGGER SYSTEM
184 
185  // convert custom sentinel outcomes to integer and store
186  try {
187  int i = boost::lexical_cast<int>(strVoteSignal);
188  if(i < VOTE_SIGNAL_CUSTOM1 || i > VOTE_SIGNAL_CUSTOM20) {
189  eSignal = VOTE_SIGNAL_NONE;
190  }
191  else {
192  eSignal = vote_signal_enum_t(i);
193  }
194  }
195  catch(std::exception const & e)
196  {
197  std::ostringstream ostr;
198  ostr << "CGovernanceVote::ConvertVoteSignal: error : " << e.what() << std::endl;
199  LogPrintf(ostr.str().c_str());
200  }
201 
202  return eSignal;
203 }
204 
206  : fValid(true),
207  fSynced(false),
208  nVoteSignal(int(VOTE_SIGNAL_NONE)),
209  vinMasternode(),
210  nParentHash(),
211  nVoteOutcome(int(VOTE_OUTCOME_NONE)),
212  nTime(0),
213  vchSig()
214 {}
215 
216 CGovernanceVote::CGovernanceVote(COutPoint outpointMasternodeIn, uint256 nParentHashIn, vote_signal_enum_t eVoteSignalIn, vote_outcome_enum_t eVoteOutcomeIn)
217  : fValid(true),
218  fSynced(false),
219  nVoteSignal(eVoteSignalIn),
220  vinMasternode(outpointMasternodeIn),
221  nParentHash(nParentHashIn),
222  nVoteOutcome(eVoteOutcomeIn),
223  nTime(GetAdjustedTime()),
224  vchSig()
225 {}
226 
227 void CGovernanceVote::Relay(CConnman& connman) const
228 {
231 }
232 
233 bool CGovernanceVote::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
234 {
235  // Choose coins to use
236  CPubKey pubKeyCollateralAddress;
237  CKey keyCollateralAddress;
238 
239  std::string strError;
240  std::string strMessage = vinMasternode.prevout.ToStringShort() + "|" + nParentHash.ToString() + "|" +
241  boost::lexical_cast<std::string>(nVoteSignal) + "|" + boost::lexical_cast<std::string>(nVoteOutcome) + "|" + boost::lexical_cast<std::string>(nTime);
242 
243  if(!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) {
244  LogPrintf("CGovernanceVote::Sign -- SignMessage() failed\n");
245  return false;
246  }
247 
248  if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
249  LogPrintf("CGovernanceVote::Sign -- VerifyMessage() failed, error: %s\n", strError);
250  return false;
251  }
252 
253  return true;
254 }
255 
256 bool CGovernanceVote::IsValid(bool fSignatureCheck) const
257 {
258  if(nTime > GetAdjustedTime() + (60*60)) {
259  LogPrint("gobject", "CGovernanceVote::IsValid -- vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n", GetHash().ToString(), nTime, GetAdjustedTime() + (60*60));
260  return false;
261  }
262 
263  // support up to 50 actions (implemented in sentinel)
265  {
266  LogPrint("gobject", "CGovernanceVote::IsValid -- Client attempted to vote on invalid signal(%d) - %s\n", nVoteSignal, GetHash().ToString());
267  return false;
268  }
269 
270  // 0=none, 1=yes, 2=no, 3=abstain. Beyond that reject votes
271  if(nVoteOutcome > 3)
272  {
273  LogPrint("gobject", "CGovernanceVote::IsValid -- Client attempted to vote on invalid outcome(%d) - %s\n", nVoteSignal, GetHash().ToString());
274  return false;
275  }
276 
277  masternode_info_t infoMn;
279  LogPrint("gobject", "CGovernanceVote::IsValid -- Unknown Masternode - %s\n", vinMasternode.prevout.ToStringShort());
280  return false;
281  }
282 
283  if(!fSignatureCheck) return true;
284 
285  std::string strError;
286  std::string strMessage = vinMasternode.prevout.ToStringShort() + "|" + nParentHash.ToString() + "|" +
287  boost::lexical_cast<std::string>(nVoteSignal) + "|" + boost::lexical_cast<std::string>(nVoteOutcome) + "|" + boost::lexical_cast<std::string>(nTime);
288 
289  if(!CMessageSigner::VerifyMessage(infoMn.pubKeyMasternode, vchSig, strMessage, strError)) {
290  LogPrintf("CGovernanceVote::IsValid -- VerifyMessage() failed, error: %s\n", strError);
291  return false;
292  }
293 
294  return true;
295 }
296 
297 bool operator==(const CGovernanceVote& vote1, const CGovernanceVote& vote2)
298 {
299  bool fResult = ((vote1.vinMasternode == vote2.vinMasternode) &&
300  (vote1.nParentHash == vote2.nParentHash) &&
301  (vote1.nVoteOutcome == vote2.nVoteOutcome) &&
302  (vote1.nVoteSignal == vote2.nVoteSignal) &&
303  (vote1.nTime == vote2.nTime));
304  return fResult;
305 }
306 
307 bool operator<(const CGovernanceVote& vote1, const CGovernanceVote& vote2)
308 {
309  bool fResult = (vote1.vinMasternode < vote2.vinMasternode);
310  if(!fResult) {
311  return false;
312  }
313  fResult = (vote1.vinMasternode == vote2.vinMasternode);
314 
315  fResult = fResult && (vote1.nParentHash < vote2.nParentHash);
316  if(!fResult) {
317  return false;
318  }
319  fResult = fResult && (vote1.nParentHash == vote2.nParentHash);
320 
321  fResult = fResult && (vote1.nVoteOutcome < vote2.nVoteOutcome);
322  if(!fResult) {
323  return false;
324  }
325  fResult = fResult && (vote1.nVoteOutcome == vote2.nVoteOutcome);
326 
327  fResult = fResult && (vote1.nVoteSignal == vote2.nVoteSignal);
328  if(!fResult) {
329  return false;
330  }
331  fResult = fResult && (vote1.nVoteSignal == vote2.nVoteSignal);
332 
333  fResult = fResult && (vote1.nTime < vote2.nTime);
334 
335  return fResult;
336 }
CMasternodeMan mnodeman
bool operator<(const CGovernanceVote &vote1, const CGovernanceVote &vote2)
static const int MIN_GOVERNANCE_PEER_PROTO_VERSION
Definition: net.h:108
static vote_signal_enum_t ConvertVoteSignal(std::string strVoteSignal)
void RelayInv(CInv &inv, const int minProtoVersion=MIN_PEER_PROTO_VERSION)
Definition: net.cpp:2528
CPubKey pubKeyMasternode
Definition: masternode.h:117
static vote_outcome_enum_t ConvertVoteOutcome(std::string strVoteOutcome)
uint256 GetHash() const
#define LogPrintf(...)
Definition: util.h:98
COutPoint prevout
Definition: transaction.h:61
static int LogPrint(const char *category, const char *format)
Definition: util.h:126
std::string ToString() const
bool GetMasternodeInfo(const COutPoint &outpoint, masternode_info_t &mnInfoRet)
static bool VerifyMessage(const CPubKey pubkey, const std::vector< unsigned char > &vchSig, const std::string strMessage, std::string &strErrorRet)
Verify the message signature, returns true if succcessful.
std::string ToString() const
Definition: uint256.cpp:65
bool operator==(const CGovernanceVote &vote1, const CGovernanceVote &vote2)
bool IsValid() const
bool Sign(CKey &keyMasternode, CPubKey &pubKeyMasternode)
std::vector< unsigned char > vchSig
vote_outcome_enum_t
int64_t GetAdjustedTime()
Definition: timedata.cpp:33
vote_signal_enum_t
static std::string ConvertOutcomeToString(vote_outcome_enum_t nOutcome)
Definition: protocol.h:314
static std::string ConvertSignalToString(vote_signal_enum_t nSignal)
Definition: pubkey.h:37
static bool SignMessage(const std::string strMessage, std::vector< unsigned char > &vchSigRet, const CKey key)
Sign the message, returns true if successful.
void Relay(CConnman &connman) const
Definition: key.h:35
std::string ToStringShort() const
Definition: transaction.cpp:17
static const int MAX_SUPPORTED_VOTE_SIGNAL