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(); donationAddress = CScript();
donationPercentage = 0; donationPercentage = 0;
nScanningErrorCount = 0; nScanningErrorCount = 0;
nVote = 0;
lastVote = 0;
} }
CMasternode::CMasternode(const CMasternode& other) CMasternode::CMasternode(const CMasternode& other)
@ -167,6 +169,8 @@ CMasternode::CMasternode(const CMasternode& other)
donationAddress = other.donationAddress; donationAddress = other.donationAddress;
donationPercentage = other.donationPercentage; donationPercentage = other.donationPercentage;
nScanningErrorCount = other.nScanningErrorCount; 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) 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 int64_t nLastDsq; //the dsq count from the last dsq broadcast of this node
int nScanningErrorCount; int nScanningErrorCount;
int nLastScanningErrorBlockHeight; int nLastScanningErrorBlockHeight;
int nVote;
int64_t lastVote;
CMasternode(); CMasternode();
CMasternode(const CMasternode& other); 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; int64_t askAgain = GetTime() + MASTERNODE_MIN_DSEEP_SECONDS;
mWeAskedForMasternodeListEntry[vin.prevout] = askAgain; 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 } else if (strCommand == "dseg") { //Get Masternode list or specific entry
CTxIn vin; CTxIn vin;

View File

@ -93,7 +93,7 @@ Value masternode(const Array& params, bool fHelp)
if (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 != "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( throw runtime_error(
"masternode \"command\"... ( \"passphrase\" )\n" "masternode \"command\"... ( \"passphrase\" )\n"
"Set of commands to execute masternode related actions\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 - Print list of all known masternodes (see masternodelist for more info)\n"
" list-conf - Print masternode.conf in JSON format\n" " list-conf - Print masternode.conf in JSON format\n"
" winners - Print list of masternode winners\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") 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; return Value::null;
} }
@ -575,7 +662,7 @@ Value masternodelist(const Array& params, bool fHelp)
if (fHelp || if (fHelp ||
(strMode != "active" && strMode != "vin" && strMode != "pubkey" && strMode != "lastseen" (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( throw runtime_error(
"masternodelist ( \"mode\" \"filter\" )\n" "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" " 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" " 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" " 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_REMOVE) strStatus = "REMOVE";
if(mn.activeState == MASTERNODE_POS_ERROR) strStatus = "POS_ERROR"; 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())); obj.push_back(Pair(strAddr, strStatus.c_str()));
} else if (strMode == "activeseconds") { } else if (strMode == "activeseconds") {
if(strFilter !="" && strAddr.find(strFilter) == string::npos) continue; if(strFilter !="" && strAddr.find(strFilter) == string::npos) continue;