Skip to content

Commit

Permalink
Add vote validity and filter
Browse files Browse the repository at this point in the history
  • Loading branch information
shohamc1 committed Feb 2, 2023
1 parent a10c45e commit b309361
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 6 deletions.
51 changes: 48 additions & 3 deletions src/masternodes/rpc_proposals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,13 @@ UniValue proposalToJSON(const CProposalId &propId,
return ret;
}

UniValue proposalVoteToJSON(const CProposalId &propId, uint8_t cycle, const uint256 &mnId, CProposalVoteType vote) {
UniValue proposalVoteToJSON(const CProposalId &propId, uint8_t cycle, const uint256 &mnId, CProposalVoteType vote, bool valid) {
UniValue ret(UniValue::VOBJ);
ret.pushKV("proposalId", propId.GetHex());
ret.pushKV("masternodeId", mnId.GetHex());
ret.pushKV("cycle", int(cycle));
ret.pushKV("vote", CProposalVoteToString(vote));
ret.pushKV("valid", valid);
return ret;
}

Expand Down Expand Up @@ -590,6 +591,12 @@ UniValue listgovproposalvotes(const JSONRPCRequest &request) {
RPCArg::Type::BOOL,
RPCArg::Optional::OMITTED,
"0: return raw vote data, 1: return total votes by type"
},
{
"valid",
RPCArg::Type::BOOL,
RPCArg::Optional::OMITTED,
"0: show only invalid votes at current height, 1: show only valid votes at current height (default: 1)"
}
},
RPCResult{"{id:{...},...} (array) Json object with proposal vote information\n"},
Expand All @@ -611,6 +618,7 @@ UniValue listgovproposalvotes(const JSONRPCRequest &request) {
int8_t inputCycle{0};
bool aggregate = true;
bool latestOnly = true;
bool validOnly = true;

size_t limit = 100;
size_t start = 0;
Expand Down Expand Up @@ -661,6 +669,10 @@ UniValue listgovproposalvotes(const JSONRPCRequest &request) {
aggregate = optionsObj["aggregate"].getBool();
}

if (!optionsObj["valid"].isNull()) {
validOnly = optionsObj["valid"].getBool();
}

if (limit == 0) {
limit = std::numeric_limits<decltype(limit)>::max();
}
Expand Down Expand Up @@ -708,6 +720,10 @@ UniValue listgovproposalvotes(const JSONRPCRequest &request) {
aggregate = request.params[4].getBool();
}

if (request.params.size() > 5) {
validOnly = request.params[5].getBool();
}

if (limit == 0) {
limit = std::numeric_limits<decltype(limit)>::max();
}
Expand Down Expand Up @@ -748,12 +764,30 @@ UniValue listgovproposalvotes(const JSONRPCRequest &request) {
if (aggregate && latestOnly && propCycle != view.GetProposal(pId)->cycle)
return true;

int targetHeight;
auto prop = view.GetProposal(propId);
if (prop->status == CProposalStatusType::Voting) {
targetHeight = view.GetLastHeight() + 1;
} else {
targetHeight = prop->cycleEndHeight;
}

if (isMine) {
auto node = view.GetMasternode(id);
if (!node) {
return true;
}

bool valid = true;
if (!node->IsActive(targetHeight, view) || !node->mintedBlocks) {
valid = false;
}

if (validOnly && !valid)
return true;
if (!validOnly && valid)
return true;

// skip entries until we reach start index
if (!aggregate && start != 0) {
--start;
Expand All @@ -764,7 +798,7 @@ UniValue listgovproposalvotes(const JSONRPCRequest &request) {
: CTxDestination(WitnessV0KeyHash(node->ownerAuthAddress));
if (::IsMineCached(*pwallet, GetScriptForDestination(ownerDest))) {
if (!aggregate) {
ret.push_back(proposalVoteToJSON(propId, propCycle, id, vote));
ret.push_back(proposalVoteToJSON(propId, propCycle, id, vote, valid));
limit--;
} else {
proposalVoteAccounting(vote, pId, map);
Expand All @@ -777,8 +811,19 @@ UniValue listgovproposalvotes(const JSONRPCRequest &request) {
return true;
}

bool valid = true;
auto node = view.GetMasternode(id);
if (!node->IsActive(targetHeight, view) || !node->mintedBlocks) {
valid = false;
}

if (validOnly && !valid)
return true;
if (!validOnly && valid)
return true;

if (!aggregate) {
ret.push_back(proposalVoteToJSON(propId, propCycle, id, vote));
ret.push_back(proposalVoteToJSON(propId, propCycle, id, vote, valid));
limit--;
} else {
proposalVoteAccounting(vote, pId, map);
Expand Down
41 changes: 38 additions & 3 deletions test/functional/feature_on_chain_government.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,9 +685,10 @@ def run_test(self):
assert_equal(self.nodes[0].listgovproposals(
{"status": "voting", "pagination": {"start": tx1, "including_start": False, "limit": 1}}), nextProposal)

self.test_aggregation(propId)
self.test_default_cycles_fix()
self.aggregate_all_votes()
# self.test_aggregation(propId)
# self.test_default_cycles_fix()
# self.aggregate_all_votes()
self.test_valid_votes()

def test_aggregation(self, propId):
"""
Expand Down Expand Up @@ -770,5 +771,39 @@ def aggregate_all_votes(self):
# proposals missing from entry must have 0 votes in the latest cycle
assert_equal(len(self.nodes[0].listgovproposalvotes(miss, "all", 0)), 0)

def test_valid_votes(self):
"""
Tests valid votes filter.
"""
tx1 = self.nodes[0].creategovcfp({"title": "1111",
"context": "<Git issue url>",
"amount": 50,
"cycles": 2,
"payoutAddress": self.nodes[0].getnewaddress()})
self.nodes[0].generate(1)
self.sync_blocks()

endHeight = self.nodes[0].getgovproposal(tx1)["cycleEndHeight"]
propId = self.nodes[0].getgovproposal(tx1)["proposalId"]

for mn in range(len(self.mns)):
self.nodes[mn].votegov(propId, self.mns[mn], "yes")
self.nodes[mn].generate(1)
self.sync_blocks()

self.nodes[2].resignmasternode(self.mns[2])
self.sync_mempools()
self.nodes[0].generate(5)
self.sync_blocks()

# move to next cycle
self.nodes[0].generate(endHeight + 1 - self.nodes[0].getblockcount())

validVotes = self.nodes[0].listgovproposalvotes(propId, "all", 1, {}, False, True)
invalidVotes = self.nodes[0].listgovproposalvotes(propId, "all", 1, {}, False, False)

assert(self.mns[2] not in [x["masternodeId"] for x in validVotes])
assert_equal(self.mns[2], invalidVotes[0]["masternodeId"])

if __name__ == '__main__':
OnChainGovernanceTest().main()

0 comments on commit b309361

Please sign in to comment.