added masternode voting system for dash initiates

This commit is contained in:
Evan Duffield 2015-03-20 11:24:11 -07:00
parent d0e5aa8385
commit 412a6838c7
4 changed files with 140 additions and 2 deletions

View File

@ -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<unsigned char> newSig, int64_t newSigTime, CPubKey newPubkey2, int protocolVersionIn, CScript newDonationAddress, int newDonationPercentage)

View File

@ -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);

View File

@ -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<unsigned char> 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<std::string>(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;

View File

@ -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<CMasternodeConfig::CMasternodeEntry> 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<unsigned char> 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<std::string>(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<CMasternodeConfig::CMasternodeEntry> 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<unsigned char> vchMasterNodeSignature;
std::string strMessage = activeMasternode.vin.ToString() + boost::lexical_cast<std::string>(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;