From 64d81a226d3e4010c18bfac1515e830c9bd6c952 Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Mon, 30 Jan 2023 19:07:48 +0800 Subject: [PATCH 01/11] feat: add possibility to vote with owner/operator address instead of maternode id --- src/masternodes/rpc_proposals.cpp | 23 +++++++- ...re_on_chain_government_voting_scenarios.py | 55 +++++++++++++++++-- 2 files changed, 71 insertions(+), 7 deletions(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index be3913df099..6f1b23d8df3 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -415,7 +415,7 @@ UniValue votegov(const JSONRPCRequest &request) { "\nVote for community proposal" + HelpRequiringPassphrase(pwallet) + "\n", { {"proposalId", RPCArg::Type::STR, RPCArg::Optional::NO, "The proposal txid"}, - {"masternodeId", RPCArg::Type::STR, RPCArg::Optional::NO, "The masternode id which made the vote"}, + {"masternodeId/ownerAddress/operatorAdress", RPCArg::Type::STR, RPCArg::Optional::NO, "The masternode id / owner address / operator address which made the vote"}, {"decision", RPCArg::Type::STR, RPCArg::Optional::NO, "The vote decision (yes/no/neutral)"}, { "inputs", @@ -449,7 +449,8 @@ UniValue votegov(const JSONRPCRequest &request) { RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VSTR, UniValue::VSTR, UniValue::VARR}, true); auto propId = ParseHashV(request.params[0].get_str(), "proposalId"); - auto mnId = ParseHashV(request.params[1].get_str(), "masternodeId"); + std::string id = request.params[1].get_str(); + uint256 mnId = uint256(); auto vote = CProposalVoteType::VoteNeutral; auto voteStr = ToLower(request.params[2].get_str()); @@ -474,9 +475,25 @@ UniValue votegov(const JSONRPCRequest &request) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Proposal <%s> is not in voting period", propId.GetHex())); } + if (id.length() == 64) { + mnId = ParseHashV(id, "masternodeId"); + } auto node = view.GetMasternode(mnId); if (!node) { - throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("The masternode %s does not exist", mnId.ToString())); + CTxDestination dest = DecodeDestination(id); + const CKeyID id = dest.index() == PKHashType ? CKeyID(std::get(dest)) : CKeyID(std::get(dest)); + auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(id); + if (!masterNodeIdByOwner) { + auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(id); + if (!masterNodeIdByOperator) { + throw JSONRPCError(RPC_INVALID_PARAMETER, + strprintf("The masternode does not exist or the address doesn't own a masternode: %s", mnId.ToString())); + } + mnId = masterNodeIdByOperator.value(); + } else { + mnId = masterNodeIdByOwner.value(); + } + node = view.GetMasternode(mnId); } ownerDest = node->ownerType == 1 ? CTxDestination(PKHash(node->ownerAuthAddress)) : CTxDestination(WitnessV0KeyHash(node->ownerAuthAddress)); diff --git a/test/functional/feature_on_chain_government_voting_scenarios.py b/test/functional/feature_on_chain_government_voting_scenarios.py index aa09fb67570..4f4956415a3 100755 --- a/test/functional/feature_on_chain_government_voting_scenarios.py +++ b/test/functional/feature_on_chain_government_voting_scenarios.py @@ -24,22 +24,22 @@ def set_test_params(self): def setup_masternodes(self, nMasternodes = 19): self.nodes[0].mns = [] - operatorAddresses = [] + self.operatorAddresses = [] for _ in range(nMasternodes): address = self.nodes[0].getnewaddress('', 'legacy') self.nodes[0].mns.append(self.nodes[0].createmasternode(address)) - operatorAddresses.append(address) + self.operatorAddresses.append(address) self.nodes[0].generate(1) self.nodes[0].generate(20) # Enables all MNs self.sync_blocks(timeout=120) # restart node with masternode_operator addresses to be able to mint with every MNs - self.restart_node(0, self.nodes[0].extra_args + ['-masternode_operator={}'.format(address) for address in operatorAddresses]) + self.restart_node(0, self.nodes[0].extra_args + ['-masternode_operator={}'.format(address) for address in self.operatorAddresses]) # Mint with every MNs to meet voting eligibility criteria - for address in operatorAddresses: + for address in self.operatorAddresses: self.nodes[0].generatetoaddress(1, address) def setup(self): @@ -92,38 +92,85 @@ def test_vote_on_cfp(self, yesVote, noVote, neutralVote, expectedStatus): self.rollback_to(height) + def test_vote_on_cfp_with_address(self, yesVote, noVote, neutralVote, expectedStatus): + height = self.nodes[0].getblockcount() + + # Create address for CFP + address = self.nodes[0].getnewaddress() + context = "" + title = "Create test community fund proposal" + amount = 100 + + # Create CFP + propId = self.nodes[0].creategovcfp({"title": title, "context": context, "amount": amount, "cycles": 1, "payoutAddress": address}) + self.nodes[0].generate(1) + + addressIterator = iter(self.operatorAddresses) + + for _ in range(yesVote): + mnId = next(addressIterator) + self.nodes[0].votegov(propId, mnId, 'yes') + + for _ in range(noVote): + mnId = next(addressIterator) + self.nodes[0].votegov(propId, mnId, 'no') + + for _ in range(neutralVote): + mnId = next(addressIterator) + self.nodes[0].votegov(propId, mnId, 'neutral') + + self.nodes[0].generate(1) + + self.nodes[0].generate(VOTING_PERIOD * 2) + proposal = self.nodes[0].getgovproposal(propId) + + assert_equal(proposal['status'], expectedStatus) + + self.rollback_to(height) + def test_scenario_below_approval_threshold(self, expectedStatus): self.test_vote_on_cfp(yesVote=4, noVote=6, neutralVote=2, expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=4, noVote=6, neutralVote=2, expectedStatus=expectedStatus) def test_scenario_at_approval_threshold(self, expectedStatus): self.test_vote_on_cfp(yesVote=8, noVote=8, neutralVote=0, expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=8, noVote=8, neutralVote=0, expectedStatus=expectedStatus) def test_scenario_above_approval_threshold(self, expectedStatus): self.test_vote_on_cfp(yesVote=10, noVote=6, neutralVote=2, expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=10, noVote=6, neutralVote=2, expectedStatus=expectedStatus) def test_scenario_below_quorum(self, expectedStatus): self.test_vote_on_cfp(yesVote=6, noVote=2, neutralVote=1, expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=6, noVote=2, neutralVote=1, expectedStatus=expectedStatus) def test_scenario_at_quorum(self, expectedStatus): self.test_vote_on_cfp(yesVote=6, noVote=2, neutralVote=2, expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=6, noVote=2, neutralVote=2, expectedStatus=expectedStatus) def test_scenario_above_quorum(self, expectedStatus): self.test_vote_on_cfp(yesVote=6, noVote=3, neutralVote=2, expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=6, noVote=3, neutralVote=2, expectedStatus=expectedStatus) def test_scenario_high_neutral_vote(self, expectedStatus): self.test_vote_on_cfp(yesVote=8, noVote=3, neutralVote=5, expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=8, noVote=3, neutralVote=5, expectedStatus=expectedStatus) def test_scenario_only_yes_and_neutral(self, expectedStatus): self.test_vote_on_cfp(yesVote=8, noVote=0, neutralVote=8, expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=8, noVote=0, neutralVote=8, expectedStatus=expectedStatus) def test_scenario_66_6_percent_approval_full_yes_votes(self, expectedStatus): self.test_vote_on_cfp(yesVote=len(self.nodes[0].mns), noVote=0, neutralVote=0, expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=len(self.nodes[0].mns), noVote=0, neutralVote=0, expectedStatus=expectedStatus) def test_scenario_66_6_percent_approval_full_no_votes(self, expectedStatus): self.test_vote_on_cfp(yesVote=0, noVote=len(self.nodes[0].mns), neutralVote=0, expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=0, noVote=len(self.nodes[0].mns), neutralVote=0, expectedStatus=expectedStatus) def test_scenario_66_6_percent_approval_full_neutral_votes(self, expectedStatus): self.test_vote_on_cfp(yesVote=0, noVote=0, neutralVote=len(self.nodes[0].mns), expectedStatus=expectedStatus) + self.test_vote_on_cfp_with_address(yesVote=0, noVote=0, neutralVote=len(self.nodes[0].mns), expectedStatus=expectedStatus) def scenarios_test(self): self.nodes[0].setgov({"ATTRIBUTES":{ From 9843389ceaee8fab56a62bcdad09e01b60479285 Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Tue, 31 Jan 2023 15:13:21 +0800 Subject: [PATCH 02/11] Add test case for votegov when address does not own or operate a masternode --- src/masternodes/rpc_proposals.cpp | 8 ++++---- ...ture_on_chain_government_voting_scenarios.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index 6f1b23d8df3..68f7f9a05c9 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -481,13 +481,13 @@ UniValue votegov(const JSONRPCRequest &request) { auto node = view.GetMasternode(mnId); if (!node) { CTxDestination dest = DecodeDestination(id); - const CKeyID id = dest.index() == PKHashType ? CKeyID(std::get(dest)) : CKeyID(std::get(dest)); - auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(id); + const CKeyID ckeyId = dest.index() == PKHashType ? CKeyID(std::get(dest)) : CKeyID(std::get(dest)); + auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId); if (!masterNodeIdByOwner) { - auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(id); + auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(ckeyId); if (!masterNodeIdByOperator) { throw JSONRPCError(RPC_INVALID_PARAMETER, - strprintf("The masternode does not exist or the address doesn't own a masternode: %s", mnId.ToString())); + strprintf("The masternode does not exist or the address doesn't own a masternode: %s", id)); } mnId = masterNodeIdByOperator.value(); } else { diff --git a/test/functional/feature_on_chain_government_voting_scenarios.py b/test/functional/feature_on_chain_government_voting_scenarios.py index 4f4956415a3..d062647521f 100755 --- a/test/functional/feature_on_chain_government_voting_scenarios.py +++ b/test/functional/feature_on_chain_government_voting_scenarios.py @@ -8,6 +8,7 @@ from test_framework.test_framework import DefiTestFramework from test_framework.util import ( assert_equal, + assert_raises_rpc_error ) APPROVAL_THRESHOLD=50 @@ -128,6 +129,21 @@ def test_vote_on_cfp_with_address(self, yesVote, noVote, neutralVote, expectedSt self.rollback_to(height) + def test_vote_with_invalid_address(self): + # Create address for CFP + address = self.nodes[0].getnewaddress() + context = "" + title = "Create test community fund proposal" + amount = 100 + + # Create CFP + propId = self.nodes[0].creategovcfp({"title": title, "context": context, "amount": amount, "cycles": 1, "payoutAddress": address}) + self.nodes[0].generate(1) + + address = self.nodes[0].getnewaddress('', 'legacy') + + assert_raises_rpc_error(-8, "The masternode does not exist or the address doesn't own a masternode: {}".format(address), self.nodes[0].votegov, propId, address, 'yes') + def test_scenario_below_approval_threshold(self, expectedStatus): self.test_vote_on_cfp(yesVote=4, noVote=6, neutralVote=2, expectedStatus=expectedStatus) self.test_vote_on_cfp_with_address(yesVote=4, noVote=6, neutralVote=2, expectedStatus=expectedStatus) @@ -213,6 +229,7 @@ def run_test(self): self.setup() self.scenarios_test() + self.test_vote_with_invalid_address() if __name__ == '__main__': OCGVotingScenarionTest().main () From f7ceb9268fc0b66c2fc93d7ec331058941e54213 Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Tue, 31 Jan 2023 18:21:00 +0800 Subject: [PATCH 03/11] add test case for votegov where address is not in the proper format --- src/masternodes/rpc_proposals.cpp | 25 +++++++++++-------- ...re_on_chain_government_voting_scenarios.py | 17 ++++++++++++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index 68f7f9a05c9..4b984d869c4 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -480,20 +480,25 @@ UniValue votegov(const JSONRPCRequest &request) { } auto node = view.GetMasternode(mnId); if (!node) { - CTxDestination dest = DecodeDestination(id); - const CKeyID ckeyId = dest.index() == PKHashType ? CKeyID(std::get(dest)) : CKeyID(std::get(dest)); - auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId); - if (!masterNodeIdByOwner) { - auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(ckeyId); - if (!masterNodeIdByOperator) { - throw JSONRPCError(RPC_INVALID_PARAMETER, + if (id.length() == 34) { + CTxDestination dest = DecodeDestination(id); + const CKeyID ckeyId = dest.index() == PKHashType ? CKeyID(std::get(dest)) : CKeyID(std::get(dest)); + auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId); + if (!masterNodeIdByOwner) { + auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(ckeyId); + if (!masterNodeIdByOperator) { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("The masternode does not exist or the address doesn't own a masternode: %s", id)); + } + mnId = masterNodeIdByOperator.value(); + } else { + mnId = masterNodeIdByOwner.value(); } - mnId = masterNodeIdByOperator.value(); + node = view.GetMasternode(mnId); } else { - mnId = masterNodeIdByOwner.value(); + throw JSONRPCError(RPC_INVALID_PARAMETER, + strprintf("The masternode id or address is not valid: %s", id)); } - node = view.GetMasternode(mnId); } ownerDest = node->ownerType == 1 ? CTxDestination(PKHash(node->ownerAuthAddress)) : CTxDestination(WitnessV0KeyHash(node->ownerAuthAddress)); diff --git a/test/functional/feature_on_chain_government_voting_scenarios.py b/test/functional/feature_on_chain_government_voting_scenarios.py index d062647521f..87a491b11a9 100755 --- a/test/functional/feature_on_chain_government_voting_scenarios.py +++ b/test/functional/feature_on_chain_government_voting_scenarios.py @@ -129,7 +129,7 @@ def test_vote_on_cfp_with_address(self, yesVote, noVote, neutralVote, expectedSt self.rollback_to(height) - def test_vote_with_invalid_address(self): + def test_vote_with_address_without_masternode(self): # Create address for CFP address = self.nodes[0].getnewaddress() context = "" @@ -144,6 +144,20 @@ def test_vote_with_invalid_address(self): assert_raises_rpc_error(-8, "The masternode does not exist or the address doesn't own a masternode: {}".format(address), self.nodes[0].votegov, propId, address, 'yes') + def test_vote_with_invalid_address(self): + # Create address for CFP + address = self.nodes[0].getnewaddress() + context = "" + title = "Create test community fund proposal" + amount = 100 + + # Create CFP + propId = self.nodes[0].creategovcfp({"title": title, "context": context, "amount": amount, "cycles": 1, "payoutAddress": address}) + self.nodes[0].generate(1) + + address = "fake_address" + assert_raises_rpc_error(-8, "The masternode id or address is not valid: {}".format(address), self.nodes[0].votegov, propId, address, 'yes') + def test_scenario_below_approval_threshold(self, expectedStatus): self.test_vote_on_cfp(yesVote=4, noVote=6, neutralVote=2, expectedStatus=expectedStatus) self.test_vote_on_cfp_with_address(yesVote=4, noVote=6, neutralVote=2, expectedStatus=expectedStatus) @@ -229,6 +243,7 @@ def run_test(self): self.setup() self.scenarios_test() + self.test_vote_with_address_without_masternode() self.test_vote_with_invalid_address() if __name__ == '__main__': From b58549cb7cfbd71fffb09224f2d7b65c3e1a13b1 Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Wed, 1 Feb 2023 18:06:21 +0800 Subject: [PATCH 04/11] Make a proper check for address passed in votegov rpc --- src/masternodes/rpc_proposals.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index 4b984d869c4..77f4955d20b 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -450,7 +450,7 @@ UniValue votegov(const JSONRPCRequest &request) { auto propId = ParseHashV(request.params[0].get_str(), "proposalId"); std::string id = request.params[1].get_str(); - uint256 mnId = uint256(); + uint256 mnId; auto vote = CProposalVoteType::VoteNeutral; auto voteStr = ToLower(request.params[2].get_str()); @@ -480,8 +480,8 @@ UniValue votegov(const JSONRPCRequest &request) { } auto node = view.GetMasternode(mnId); if (!node) { - if (id.length() == 34) { - CTxDestination dest = DecodeDestination(id); + CTxDestination dest = DecodeDestination(id); + if (IsValidDestination(dest)) { const CKeyID ckeyId = dest.index() == PKHashType ? CKeyID(std::get(dest)) : CKeyID(std::get(dest)); auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId); if (!masterNodeIdByOwner) { From 26349e0e66af198fff388377ae4eeabb350b394a Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Wed, 1 Feb 2023 18:09:46 +0800 Subject: [PATCH 05/11] fix logic for votegov --- src/masternodes/rpc_proposals.cpp | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index 77f4955d20b..38edb678803 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -481,24 +481,23 @@ UniValue votegov(const JSONRPCRequest &request) { auto node = view.GetMasternode(mnId); if (!node) { CTxDestination dest = DecodeDestination(id); - if (IsValidDestination(dest)) { - const CKeyID ckeyId = dest.index() == PKHashType ? CKeyID(std::get(dest)) : CKeyID(std::get(dest)); - auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId); - if (!masterNodeIdByOwner) { - auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(ckeyId); - if (!masterNodeIdByOperator) { - throw JSONRPCError(RPC_INVALID_PARAMETER, - strprintf("The masternode does not exist or the address doesn't own a masternode: %s", id)); - } - mnId = masterNodeIdByOperator.value(); - } else { - mnId = masterNodeIdByOwner.value(); - } - node = view.GetMasternode(mnId); - } else { + if (!IsValidDestination(dest)) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("The masternode id or address is not valid: %s", id)); } + const CKeyID ckeyId = dest.index() == PKHashType ? CKeyID(std::get(dest)) : CKeyID(std::get(dest)); + auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId); + if (!masterNodeIdByOwner) { + auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(ckeyId); + if (!masterNodeIdByOperator) { + throw JSONRPCError(RPC_INVALID_PARAMETER, + strprintf("The masternode does not exist or the address doesn't own a masternode: %s", id)); + } + mnId = masterNodeIdByOperator.value(); + } else { + mnId = masterNodeIdByOwner.value(); + } + node = view.GetMasternode(mnId); } ownerDest = node->ownerType == 1 ? CTxDestination(PKHash(node->ownerAuthAddress)) : CTxDestination(WitnessV0KeyHash(node->ownerAuthAddress)); From 5de0fd421ff6b681938e768c82c5c897d2a540b4 Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Wed, 1 Feb 2023 18:20:36 +0800 Subject: [PATCH 06/11] fix logic for votegov rpc --- src/masternodes/rpc_proposals.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index 38edb678803..dfc136f0322 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -477,9 +477,7 @@ UniValue votegov(const JSONRPCRequest &request) { } if (id.length() == 64) { mnId = ParseHashV(id, "masternodeId"); - } - auto node = view.GetMasternode(mnId); - if (!node) { + } else { CTxDestination dest = DecodeDestination(id); if (!IsValidDestination(dest)) { throw JSONRPCError(RPC_INVALID_PARAMETER, @@ -489,15 +487,15 @@ UniValue votegov(const JSONRPCRequest &request) { auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId); if (!masterNodeIdByOwner) { auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(ckeyId); - if (!masterNodeIdByOperator) { - throw JSONRPCError(RPC_INVALID_PARAMETER, - strprintf("The masternode does not exist or the address doesn't own a masternode: %s", id)); - } mnId = masterNodeIdByOperator.value(); } else { mnId = masterNodeIdByOwner.value(); } - node = view.GetMasternode(mnId); + } + auto node = view.GetMasternode(mnId); + if (!node) { + throw JSONRPCError(RPC_INVALID_PARAMETER, + strprintf("The masternode does not exist or the address doesn't own a masternode: %s", id)); } ownerDest = node->ownerType == 1 ? CTxDestination(PKHash(node->ownerAuthAddress)) : CTxDestination(WitnessV0KeyHash(node->ownerAuthAddress)); From d1849d5071851d3363ce9ee8c3a8df5fdcab8a32 Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Thu, 2 Feb 2023 10:02:33 +0800 Subject: [PATCH 07/11] fix thrown error for rpc_proposal votegov --- src/masternodes/rpc_proposals.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index dfc136f0322..2ebb4a7eabb 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -485,11 +485,10 @@ UniValue votegov(const JSONRPCRequest &request) { } const CKeyID ckeyId = dest.index() == PKHashType ? CKeyID(std::get(dest)) : CKeyID(std::get(dest)); auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId); - if (!masterNodeIdByOwner) { - auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(ckeyId); - mnId = masterNodeIdByOperator.value(); - } else { + if (auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId)) { mnId = masterNodeIdByOwner.value(); + } else if (auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(ckeyId)) { + mnId = masterNodeIdByOperator.value(); } } auto node = view.GetMasternode(mnId); From f9411ff069fd0b57a624602d2a876f9cf5a569cf Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Thu, 2 Feb 2023 15:33:39 +0800 Subject: [PATCH 08/11] fix throw error if voting address is not P2PKH or P2WPKH --- src/masternodes/rpc_proposals.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index 2ebb4a7eabb..002957fb3ca 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -483,7 +483,9 @@ UniValue votegov(const JSONRPCRequest &request) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("The masternode id or address is not valid: %s", id)); } - const CKeyID ckeyId = dest.index() == PKHashType ? CKeyID(std::get(dest)) : CKeyID(std::get(dest)); + const CKeyID ckeyId = dest.index() == PKHashType ? + CKeyID(std::get(dest)) : dest.index() == WitV0KeyHashType ? + CKeyID(std::get(dest)) : throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s does not refer to a P2PKH or P2WPKH address", id)); auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId); if (auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId)) { mnId = masterNodeIdByOwner.value(); From 287b57f6f772b67a97a4dda0b1ae1a3bca131578 Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Thu, 2 Feb 2023 16:56:33 +0800 Subject: [PATCH 09/11] remove duplicate line in votegov --- src/masternodes/rpc_proposals.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index 002957fb3ca..24cf31799dc 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -486,7 +486,6 @@ UniValue votegov(const JSONRPCRequest &request) { const CKeyID ckeyId = dest.index() == PKHashType ? CKeyID(std::get(dest)) : dest.index() == WitV0KeyHashType ? CKeyID(std::get(dest)) : throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s does not refer to a P2PKH or P2WPKH address", id)); - auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId); if (auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId)) { mnId = masterNodeIdByOwner.value(); } else if (auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(ckeyId)) { From 06e24c2cab5da781246218503dc00f1116615c08 Mon Sep 17 00:00:00 2001 From: DrPing Date: Mon, 6 Feb 2023 13:35:34 +0800 Subject: [PATCH 10/11] Update src/masternodes/rpc_proposals.cpp Co-authored-by: Shoham Chakraborty --- src/masternodes/rpc_proposals.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index 16d31854d5c..b52981efa66 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -417,7 +417,7 @@ UniValue votegov(const JSONRPCRequest &request) { "\nVote for community proposal" + HelpRequiringPassphrase(pwallet) + "\n", { {"proposalId", RPCArg::Type::STR, RPCArg::Optional::NO, "The proposal txid"}, - {"masternodeId/ownerAddress/operatorAdress", RPCArg::Type::STR, RPCArg::Optional::NO, "The masternode id / owner address / operator address which made the vote"}, + {"masternodeId", RPCArg::Type::STR, RPCArg::Optional::NO, "The masternode id / owner address / operator address which made the vote"}, {"decision", RPCArg::Type::STR, RPCArg::Optional::NO, "The vote decision (yes/no/neutral)"}, { "inputs", From 72fbf435d6856e43bbf481b13225d4d0dfe7a019 Mon Sep 17 00:00:00 2001 From: cedric ogire Date: Mon, 6 Feb 2023 14:14:47 +0800 Subject: [PATCH 11/11] replace ternary operation by if for better readability --- src/masternodes/rpc_proposals.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/masternodes/rpc_proposals.cpp b/src/masternodes/rpc_proposals.cpp index b52981efa66..573f4fb215c 100644 --- a/src/masternodes/rpc_proposals.cpp +++ b/src/masternodes/rpc_proposals.cpp @@ -488,9 +488,14 @@ UniValue votegov(const JSONRPCRequest &request) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("The masternode id or address is not valid: %s", id)); } - const CKeyID ckeyId = dest.index() == PKHashType ? - CKeyID(std::get(dest)) : dest.index() == WitV0KeyHashType ? - CKeyID(std::get(dest)) : throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s does not refer to a P2PKH or P2WPKH address", id)); + CKeyID ckeyId; + if (dest.index() == PKHashType) { + ckeyId = CKeyID(std::get(dest)); + } else if (dest.index() == WitV0KeyHashType) { + ckeyId = CKeyID(std::get(dest)); + } else { + throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("%s does not refer to a P2PKH or P2WPKH address", id)); + } if (auto masterNodeIdByOwner = view.GetMasternodeIdByOwner(ckeyId)) { mnId = masterNodeIdByOwner.value(); } else if (auto masterNodeIdByOperator = view.GetMasternodeIdByOperator(ckeyId)) {