From 412a6838c78ea4818749d79f1678423bc1a0f5a1 Mon Sep 17 00:00:00 2001 From: Evan Duffield Date: Fri, 20 Mar 2015 11:24:11 -0700 Subject: [PATCH] added masternode voting system for dash initiates --- src/masternode.cpp | 4 ++ src/masternode.h | 2 + src/masternodeman.cpp | 34 ++++++++++++++ src/rpcdarksend.cpp | 102 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 140 insertions(+), 2 deletions(-) diff --git a/src/masternode.cpp b/src/masternode.cpp index 7097bff0b3..9744d5a90c 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -144,6 +144,8 @@ CMasternode::CMasternode() donationAddress = CScript(); donationPercentage = 0; nScanningErrorCount = 0; + nVote = 0; + lastVote = 0; } CMasternode::CMasternode(const CMasternode& other) @@ -167,6 +169,8 @@ CMasternode::CMasternode(const CMasternode& other) donationAddress = other.donationAddress; donationPercentage = other.donationPercentage; nScanningErrorCount = other.nScanningErrorCount; + nVote = other.nVote; + lastVote = other.lastVote; } CMasternode::CMasternode(CService newAddr, CTxIn newVin, CPubKey newPubkey, std::vector newSig, int64_t newSigTime, CPubKey newPubkey2, int protocolVersionIn, CScript newDonationAddress, int newDonationPercentage) diff --git a/src/masternode.h b/src/masternode.h index a9678928ff..dfe1887745 100644 --- a/src/masternode.h +++ b/src/masternode.h @@ -83,6 +83,8 @@ public: int64_t nLastDsq; //the dsq count from the last dsq broadcast of this node int nScanningErrorCount; int nLastScanningErrorBlockHeight; + int nVote; + int64_t lastVote; CMasternode(); CMasternode(const CMasternode& other); diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index 2743f6a821..261aa1686d 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -769,6 +769,40 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData int64_t askAgain = GetTime() + MASTERNODE_MIN_DSEEP_SECONDS; mWeAskedForMasternodeListEntry[vin.prevout] = askAgain; + } else if (strCommand == "mvote") { //Masternode Vote + + CTxIn vin; + vector vchSig; + int nVote; + vRecv >> vin >> vchSig >> nVote; + + // see if we have this Masternode + CMasternode* pmn = this->Find(vin); + if(pmn != NULL) + { + if((GetAdjustedTime() - pmn->lastVote) > (60*60)) + { + std::string strMessage = vin.ToString() + boost::lexical_cast(nVote); + + std::string errorMessage = ""; + if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchSig, strMessage, errorMessage)) + { + LogPrintf("mvote - Got bad Masternode address signature %s \n", vin.ToString().c_str()); + return; + } + + pmn->nVote = nVote; + pmn->lastVote = GetAdjustedTime(); + + //send to all peers + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + pnode->PushMessage("mvote", vin, vchSig, nVote); + } + + return; + } + } else if (strCommand == "dseg") { //Get Masternode list or specific entry CTxIn vin; diff --git a/src/rpcdarksend.cpp b/src/rpcdarksend.cpp index 57290eddc4..a646cfd8a5 100644 --- a/src/rpcdarksend.cpp +++ b/src/rpcdarksend.cpp @@ -93,7 +93,7 @@ Value masternode(const Array& params, bool fHelp) if (fHelp || (strCommand != "start" && strCommand != "start-alias" && strCommand != "start-many" && strCommand != "stop" && strCommand != "stop-alias" && strCommand != "stop-many" && strCommand != "list" && strCommand != "list-conf" && strCommand != "count" && strCommand != "enforce" - && strCommand != "debug" && strCommand != "current" && strCommand != "winners" && strCommand != "genkey" && strCommand != "connect" && strCommand != "outputs")) + && strCommand != "debug" && strCommand != "current" && strCommand != "winners" && strCommand != "genkey" && strCommand != "connect" && strCommand != "outputs" && strCommand != "vote-many" && strCommand != "vote")) throw runtime_error( "masternode \"command\"... ( \"passphrase\" )\n" "Set of commands to execute masternode related actions\n" @@ -116,6 +116,8 @@ Value masternode(const Array& params, bool fHelp) " list - Print list of all known masternodes (see masternodelist for more info)\n" " list-conf - Print masternode.conf in JSON format\n" " winners - Print list of masternode winners\n" + " vote-many - Vote on a Dash initiative\n" + " vote - Vote on a Dash initiative\n" ); if (strCommand == "stop") @@ -562,6 +564,91 @@ Value masternode(const Array& params, bool fHelp) } + if(strCommand == "vote-many") + { + std::vector mnEntries; + mnEntries = masternodeConfig.getEntries(); + + std::string vote = params[1].get_str().c_str(); + if(vote != "yay" && vote != "nay") return "You can only vote 'yay' or 'nay'"; + int nVote = 0; + if(vote == "yay") nVote = 1; + if(vote == "nay") nVote = -1; + + + Object resultObj; + + BOOST_FOREACH(CMasternodeConfig::CMasternodeEntry mne, masternodeConfig.getEntries()) { + std::string errorMessage; + std::vector vchMasterNodeSignature; + std::string strMasterNodeSignMessage; + + CTxIn vin; + CPubKey pubKeyCollateralAddress; + CKey keyCollateralAddress; + CPubKey pubKeyMasternode; + CKey keyMasternode; + + if(!activeMasternode.GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress, mne.getTxHash(), mne.getOutputIndex())) { + return("could not allocate vin"); + } + + std::string strMessage = vin.ToString() + boost::lexical_cast(nVote); + + if(!darkSendSigner.SetKey(mne.getPrivKey(), errorMessage, keyMasternode, pubKeyMasternode)) + return(" Error upon calling SetKey"); + + if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, keyMasternode)) + return(" Error upon calling SignMessage"); + + if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchMasterNodeSignature, strMessage, errorMessage)) + return(" Error upon calling VerifyMessage"); + + //send to all peers + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + pnode->PushMessage("mvote", vin, vchMasterNodeSignature, nVote); + + } + } + + if(strCommand == "vote") + { + std::vector mnEntries; + mnEntries = masternodeConfig.getEntries(); + + std::string vote = params[1].get_str().c_str(); + if(vote != "yay" && vote != "nay") return "You can only vote 'yay' or 'nay'"; + int nVote = 0; + if(vote == "yay") nVote = 1; + if(vote == "nay") nVote = -1; + + // Choose coins to use + CPubKey pubKeyCollateralAddress; + CKey keyCollateralAddress; + CPubKey pubKeyMasternode; + CKey keyMasternode; + + std::string errorMessage; + std::vector vchMasterNodeSignature; + std::string strMessage = activeMasternode.vin.ToString() + boost::lexical_cast(nVote); + + if(!darkSendSigner.SetKey(strMasterNodePrivKey, errorMessage, keyMasternode, pubKeyMasternode)) + return(" Error upon calling SetKey"); + + if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchMasterNodeSignature, keyMasternode)) + return(" Error upon calling SignMessage"); + + if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchMasterNodeSignature, strMessage, errorMessage)) + return(" Error upon calling VerifyMessage"); + + //send to all peers + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + pnode->PushMessage("mvote", activeMasternode.vin, vchMasterNodeSignature, nVote); + + } + return Value::null; } @@ -575,7 +662,7 @@ Value masternodelist(const Array& params, bool fHelp) if (fHelp || (strMode != "active" && strMode != "vin" && strMode != "pubkey" && strMode != "lastseen" - && strMode != "activeseconds" && strMode != "rank" && strMode != "protocol" && strMode != "full")) + && strMode != "activeseconds" && strMode != "rank" && strMode != "protocol" && strMode != "full" && strMode != "votes")) { throw runtime_error( "masternodelist ( \"mode\" \"filter\" )\n" @@ -592,6 +679,7 @@ Value masternodelist(const Array& params, bool fHelp) " pubkey - Print public key associated with a masternode (can be additionally filtered, partial match)\n" " rank - Print rank of a masternode based on current block\n" " vin - Print vin associated with a masternode (can be additionally filtered, partial match)\n" + " votes - Print all masternode votes for a Dash initiative\n" ); } @@ -619,6 +707,16 @@ Value masternodelist(const Array& params, bool fHelp) if(mn.activeState == MASTERNODE_REMOVE) strStatus = "REMOVE"; if(mn.activeState == MASTERNODE_POS_ERROR) strStatus = "POS_ERROR"; + obj.push_back(Pair(strAddr, strStatus.c_str())); + } else if(strMode == "votes"){ + if(strFilter !="" && strFilter != (mn.IsEnabled() ? "true" : "false") && + strAddr.find(strFilter) == string::npos) continue; + + std::string strStatus = "ABSTAIN"; + + if(mn.nVote == -1) strStatus = "NAY"; + if(mn.nVote == 1) strStatus = "YAY"; + obj.push_back(Pair(strAddr, strStatus.c_str())); } else if (strMode == "activeseconds") { if(strFilter !="" && strAddr.find(strFilter) == string::npos) continue;