Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement getcurrentvotes JSONRPC call #1164

Merged
merged 6 commits into from
Nov 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/governance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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());
Expand Down
3 changes: 3 additions & 0 deletions src/governance.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class CGovernanceManager
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);
Expand Down Expand Up @@ -528,6 +529,8 @@ class CGovernanceObject
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();
Expand Down
49 changes: 47 additions & 2 deletions src/rpcgovernance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,16 @@ 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"
"\nAvailable commands:\n"
" 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"
Expand Down Expand Up @@ -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;
}

Expand Down