Implement getcurrentvotes JSONRPC call (#1164)

This commit is contained in:
Nathan Marley 2016-11-22 11:26:36 -08:00 committed by UdjinM6
parent 9c4e019c36
commit ec59862506
3 changed files with 108 additions and 2 deletions

View File

@ -419,6 +419,53 @@ std::vector<CGovernanceVote> CGovernanceManager::GetMatchingVotes(const uint256&
return govobj.GetVoteFile().GetVotes();
}
std::vector<CGovernanceVote> CGovernanceManager::GetCurrentVotes(const uint256& nParentHash, const CTxIn& mnCollateralOutpointFilter)
{
LOCK(cs);
std::vector<CGovernanceVote> vecResult;
// Find the governance object or short-circuit.
object_m_it it = mapObjects.find(nParentHash);
if(it == mapObjects.end()) return vecResult;
CGovernanceObject& govobj = it->second;
// Compile a list of Masternode collateral outpoints for which to get votes
std::vector<CTxIn> vecMNTxIn;
if (mnCollateralOutpointFilter == CTxIn()) {
std::vector<CMasternode> mnlist = mnodeman.GetFullMasternodeVector();
for (std::vector<CMasternode>::iterator it = mnlist.begin(); it != mnlist.end(); ++it)
{
vecMNTxIn.push_back(it->vin);
}
}
else {
vecMNTxIn.push_back(mnCollateralOutpointFilter);
}
// Loop thru each MN collateral outpoint and get the votes for the `nParentHash` governance object
for (std::vector<CTxIn>::iterator it = vecMNTxIn.begin(); it != vecMNTxIn.end(); ++it)
{
CTxIn &mnCollateralOutpoint = *it;
// get a vote_rec_t from the govobj
vote_rec_t voteRecord;
if (!govobj.GetCurrentMNVotes(mnCollateralOutpoint, voteRecord)) continue;
for (vote_instance_m_it it3 = voteRecord.mapInstances.begin(); it3 != voteRecord.mapInstances.end(); ++it3) {
int signal = (it3->first);
int outcome = ((it3->second).eOutcome);
int64_t nTime = ((it3->second).nTime);
CGovernanceVote vote = CGovernanceVote(mnCollateralOutpoint, nParentHash, (vote_signal_enum_t)signal, (vote_outcome_enum_t)outcome);
vote.SetTime(nTime);
vecResult.push_back(vote);
}
}
return vecResult;
}
std::vector<CGovernanceObject*> CGovernanceManager::GetAllNewerThan(int64_t nMoreThanTime)
{
LOCK(cs);
@ -1397,6 +1444,17 @@ int CGovernanceObject::GetAbstainCount(vote_signal_enum_t eVoteSignalIn) const
return CountMatchingVotes(eVoteSignalIn, VOTE_OUTCOME_ABSTAIN);
}
bool CGovernanceObject::GetCurrentMNVotes(const CTxIn& mnCollateralOutpoint, vote_rec_t& voteRecord)
{
int nMNIndex = governance.GetMasternodeIndex(mnCollateralOutpoint);
vote_m_it it = mapCurrentMNVotes.find(nMNIndex);
if (it == mapCurrentMNVotes.end()) {
return false;
}
voteRecord = it->second;
return true;
}
void CGovernanceObject::Relay()
{
CInv inv(MSG_GOVERNANCE_OBJECT, GetHash());

View File

@ -175,6 +175,7 @@ public:
CGovernanceObject *FindGovernanceObject(const uint256& nHash);
std::vector<CGovernanceVote> GetMatchingVotes(const uint256& nParentHash);
std::vector<CGovernanceVote> GetCurrentVotes(const uint256& nParentHash, const CTxIn& mnCollateralOutpointFilter);
std::vector<CGovernanceObject*> GetAllNewerThan(int64_t nMoreThanTime);
bool IsBudgetPaymentBlock(int nBlockHeight);
@ -528,6 +529,8 @@ public:
int GetNoCount(vote_signal_enum_t eVoteSignalIn) const;
int GetAbstainCount(vote_signal_enum_t eVoteSignalIn) const;
bool GetCurrentMNVotes(const CTxIn& mnCollateralOutpoint, vote_rec_t& voteRecord);
// FUNCTIONS FOR DEALING WITH DATA STRING
std::string GetDataAsHex();

View File

@ -36,7 +36,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
if (fHelp ||
(strCommand != "vote-many" && strCommand != "vote-conf" && strCommand != "vote-alias" && strCommand != "prepare" && strCommand != "submit" &&
strCommand != "vote" && strCommand != "get" && strCommand != "getvotes" && strCommand != "list" && strCommand != "diff" && strCommand != "deserialize"))
strCommand != "vote" && strCommand != "get" && strCommand != "getvotes" && strCommand != "getcurrentvotes" && strCommand != "list" && strCommand != "diff" && strCommand != "deserialize"))
throw std::runtime_error(
"gobject \"command\"...\n"
"Manage governance objects\n"
@ -44,7 +44,8 @@ UniValue gobject(const UniValue& params, bool fHelp)
" prepare - Prepare governance object by signing and creating tx\n"
" submit - Submit governance object to network\n"
" get - Get governance object by hash\n"
" getvotes - Get votes for a governance object hash\n"
" getvotes - Get all votes for a governance object hash (including old votes)\n"
" getcurrentvotes - Get only current (tallying) votes for a governance object hash (does not include old votes)\n"
" list - List all governance objects\n"
" diff - List differences since last diff\n"
" vote-alias - Vote on a governance object by masternode alias (using masternode.conf setup)\n"
@ -706,6 +707,50 @@ UniValue gobject(const UniValue& params, bool fHelp)
return bResult;
}
// GETVOTES FOR SPECIFIC GOVERNANCE OBJECT
if(strCommand == "getcurrentvotes")
{
if (params.size() < 2 || params.size() == 3 || params.size() > 4)
throw std::runtime_error(
"Correct usage is 'gobject getcurrentvotes <governance-hash> [txid vout_index]'"
);
// COLLECT PARAMETERS FROM USER
uint256 hash = ParseHashV(params[1], "Governance hash");
CTxIn mnCollateralOutpoint;
if (params.size() == 4) {
uint256 txid = ParseHashV(params[2], "Masternode Collateral hash");
std::string strVout = params[3].get_str();
uint32_t vout = boost::lexical_cast<uint32_t>(strVout);
mnCollateralOutpoint = CTxIn(txid, vout);
}
// FIND OBJECT USER IS LOOKING FOR
LOCK(governance.cs);
CGovernanceObject* pGovObj = governance.FindGovernanceObject(hash);
if(pGovObj == NULL) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Unknown governance-hash");
}
// REPORT RESULTS TO USER
UniValue bResult(UniValue::VOBJ);
// GET MATCHING VOTES BY HASH, THEN SHOW USERS VOTE INFORMATION
std::vector<CGovernanceVote> vecVotes = governance.GetCurrentVotes(hash, mnCollateralOutpoint);
BOOST_FOREACH(CGovernanceVote vote, vecVotes) {
bResult.push_back(Pair(vote.GetHash().ToString(), vote.ToString()));
}
return bResult;
}
return NullUniValue;
}