Skip to content

Commit bc29fe1

Browse files
committed
Remove compatibility code from governance RPCs and directly use deterministicMNManager
1 parent b49ef5d commit bc29fe1

File tree

1 file changed

+61
-138
lines changed

1 file changed

+61
-138
lines changed

src/rpc/governance.cpp

+61-138
Original file line numberDiff line numberDiff line change
@@ -412,10 +412,9 @@ UniValue gobject_vote_conf(const JSONRPCRequest& request)
412412
UniValue statusObj(UniValue::VOBJ);
413413
UniValue returnObj(UniValue::VOBJ);
414414

415-
CMasternode mn;
416-
bool fMnFound = mnodeman.Get(activeMasternodeInfo.outpoint, mn);
415+
auto dmn = deterministicMNManager->GetListAtChainTip().GetValidMNByCollateral(activeMasternodeInfo.outpoint);
417416

418-
if (!fMnFound) {
417+
if (!dmn) {
419418
nFailed++;
420419
statusObj.push_back(Pair("result", "failed"));
421420
statusObj.push_back(Pair("errorMessage", "Can't find masternode by collateral output"));
@@ -425,19 +424,16 @@ UniValue gobject_vote_conf(const JSONRPCRequest& request)
425424
return returnObj;
426425
}
427426

428-
CGovernanceVote vote(mn.outpoint, hash, eVoteSignal, eVoteOutcome);
427+
CGovernanceVote vote(dmn->collateralOutpoint, hash, eVoteSignal, eVoteOutcome);
429428

430429
bool signSuccess = false;
431-
if (deterministicMNManager->IsDIP3Active()) {
432-
if (govObjType == GOVERNANCE_OBJECT_PROPOSAL && eVoteSignal == VOTE_SIGNAL_FUNDING) {
433-
throw JSONRPCError(RPC_INVALID_PARAMETER, "Can't use vote-conf for proposals when deterministic masternodes are active");
434-
}
435-
if (activeMasternodeInfo.blsKeyOperator) {
436-
signSuccess = vote.Sign(*activeMasternodeInfo.blsKeyOperator);
437-
}
438-
} else {
439-
signSuccess = vote.Sign(activeMasternodeInfo.legacyKeyOperator, activeMasternodeInfo.legacyKeyIDOperator);
430+
if (govObjType == GOVERNANCE_OBJECT_PROPOSAL && eVoteSignal == VOTE_SIGNAL_FUNDING) {
431+
throw JSONRPCError(RPC_INVALID_PARAMETER, "Can't use vote-conf for proposals");
432+
}
433+
if (activeMasternodeInfo.blsKeyOperator) {
434+
signSuccess = vote.Sign(*activeMasternodeInfo.blsKeyOperator);
440435
}
436+
441437
if (!signSuccess) {
442438
nFailed++;
443439
statusObj.push_back(Pair("result", "failed"));
@@ -466,9 +462,9 @@ UniValue gobject_vote_conf(const JSONRPCRequest& request)
466462
return returnObj;
467463
}
468464

469-
UniValue VoteWithMasternodeList(const std::vector<CMasternodeConfig::CMasternodeEntry>& entries,
470-
const uint256& hash, vote_signal_enum_t eVoteSignal,
471-
vote_outcome_enum_t eVoteOutcome)
465+
UniValue VoteWithMasternodes(const std::map<uint256, CKey>& keys,
466+
const uint256& hash, vote_signal_enum_t eVoteSignal,
467+
vote_outcome_enum_t eVoteOutcome)
472468
{
473469
int govObjType;
474470
{
@@ -483,59 +479,31 @@ UniValue VoteWithMasternodeList(const std::vector<CMasternodeConfig::CMasternode
483479
int nSuccessful = 0;
484480
int nFailed = 0;
485481

482+
auto mnList = deterministicMNManager->GetListAtChainTip();
483+
486484
UniValue resultsObj(UniValue::VOBJ);
487485

488-
for (const auto& mne : entries) {
489-
CPubKey pubKeyOperator;
490-
CKey keyOperator;
486+
for (const auto& p : keys) {
487+
const auto& proTxHash = p.first;
488+
const auto& key = p.second;
491489

492490
UniValue statusObj(UniValue::VOBJ);
493491

494-
if (!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyOperator, pubKeyOperator)) {
495-
nFailed++;
496-
statusObj.push_back(Pair("result", "failed"));
497-
statusObj.push_back(Pair("errorMessage", "Masternode signing error, could not set key correctly"));
498-
resultsObj.push_back(Pair(mne.getAlias(), statusObj));
499-
continue;
500-
}
501-
502-
uint256 nTxHash;
503-
nTxHash.SetHex(mne.getTxHash());
504-
505-
int nOutputIndex = 0;
506-
if (!ParseInt32(mne.getOutputIndex(), &nOutputIndex)) {
507-
continue;
508-
}
509-
510-
COutPoint outpoint(nTxHash, nOutputIndex);
511-
512-
CMasternode mn;
513-
bool fMnFound = mnodeman.Get(outpoint, mn);
514-
515-
if (!fMnFound) {
492+
auto dmn = mnList.GetValidMN(proTxHash);
493+
if (!dmn) {
516494
nFailed++;
517495
statusObj.push_back(Pair("result", "failed"));
518-
statusObj.push_back(Pair("errorMessage", "Can't find masternode by collateral output"));
519-
resultsObj.push_back(Pair(mne.getAlias(), statusObj));
496+
statusObj.push_back(Pair("errorMessage", "Can't find masternode by proTxHash"));
497+
resultsObj.push_back(Pair(proTxHash.ToString(), statusObj));
520498
continue;
521499
}
522500

523-
if (deterministicMNManager->IsDIP3Active()) {
524-
if (govObjType == GOVERNANCE_OBJECT_PROPOSAL && mn.keyIDVoting != pubKeyOperator.GetID()) {
525-
nFailed++;
526-
statusObj.push_back(Pair("result", "failed"));
527-
statusObj.push_back(Pair("errorMessage", "Can't vote on proposal when key does not match voting key"));
528-
resultsObj.push_back(Pair(mne.getAlias(), statusObj));
529-
continue;
530-
}
531-
}
532-
533-
CGovernanceVote vote(mn.outpoint, hash, eVoteSignal, eVoteOutcome);
534-
if (!vote.Sign(keyOperator, pubKeyOperator.GetID())) {
501+
CGovernanceVote vote(dmn->collateralOutpoint, hash, eVoteSignal, eVoteOutcome);
502+
if (!vote.Sign(key, key.GetPubKey().GetID())) {
535503
nFailed++;
536504
statusObj.push_back(Pair("result", "failed"));
537505
statusObj.push_back(Pair("errorMessage", "Failure to sign."));
538-
resultsObj.push_back(Pair(mne.getAlias(), statusObj));
506+
resultsObj.push_back(Pair(proTxHash.ToString(), statusObj));
539507
continue;
540508
}
541509

@@ -549,7 +517,7 @@ UniValue VoteWithMasternodeList(const std::vector<CMasternodeConfig::CMasternode
549517
statusObj.push_back(Pair("errorMessage", exception.GetMessage()));
550518
}
551519

552-
resultsObj.push_back(Pair(mne.getAlias(), statusObj));
520+
resultsObj.push_back(Pair(proTxHash.ToString(), statusObj));
553521
}
554522

555523
UniValue returnObj(UniValue::VOBJ);
@@ -559,11 +527,12 @@ UniValue VoteWithMasternodeList(const std::vector<CMasternodeConfig::CMasternode
559527
return returnObj;
560528
}
561529

530+
#ifdef ENABLE_WALLET
562531
void gobject_vote_many_help()
563532
{
564533
throw std::runtime_error(
565534
"gobject vote-many <governance-hash> <vote> <vote-outcome>\n"
566-
"Vote on a governance object by all masternodes (using masternode.conf setup)\n"
535+
"Vote on a governance object by all masternodes for which the voting key is present in the local wallet\n"
567536
"\nArguments:\n"
568537
"1. governance-hash (string, required) hash of the governance object\n"
569538
"2. vote (string, required) vote, possible values: [funding|valid|delete|endorsed]\n"
@@ -592,66 +561,33 @@ UniValue gobject_vote_many(const JSONRPCRequest& request)
592561
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid vote outcome. Please use one of the following: 'yes', 'no' or 'abstain'");
593562
}
594563

595-
std::vector<CMasternodeConfig::CMasternodeEntry> entries = masternodeConfig.getEntries();
596-
597-
#ifdef ENABLE_WALLET
598-
// This is a hack to maintain code-level backwards compatibility with masternode.conf and the deterministic masternodes.
599-
// Deterministic masternode keys are managed inside the wallet instead of masternode.conf
600-
// This allows voting on proposals when you have the MN voting key in your wallet
601-
// We can remove this when we remove support for masternode.conf and only support wallet based masternode
602-
// management
603-
if (deterministicMNManager->IsDIP3Active()) {
604-
if (!pwalletMain) {
605-
throw JSONRPCError(RPC_INVALID_PARAMETER, "vote-many not supported when wallet is disabled.");
606-
}
607-
entries.clear();
608-
609-
auto mnList = deterministicMNManager->GetListAtChainTip();
610-
mnList.ForEachMN(true, [&](const CDeterministicMNCPtr& dmn) {
611-
bool found = false;
612-
for (const auto &mne : entries) {
613-
uint256 nTxHash;
614-
nTxHash.SetHex(mne.getTxHash());
615-
616-
int nOutputIndex = 0;
617-
if(!ParseInt32(mne.getOutputIndex(), &nOutputIndex)) {
618-
continue;
619-
}
620-
621-
if (nTxHash == dmn->collateralOutpoint.hash && (uint32_t)nOutputIndex == dmn->collateralOutpoint.n) {
622-
found = true;
623-
break;
624-
}
625-
}
626-
if (!found) {
627-
CKey ownerKey;
628-
if (pwalletMain->GetKey(dmn->pdmnState->keyIDVoting, ownerKey)) {
629-
CBitcoinSecret secret(ownerKey);
630-
CMasternodeConfig::CMasternodeEntry mne(dmn->proTxHash.ToString(), dmn->pdmnState->addr.ToStringIPPort(false), secret.ToString(), dmn->collateralOutpoint.hash.ToString(), itostr(dmn->collateralOutpoint.n));
631-
entries.push_back(mne);
632-
}
633-
}
634-
});
635-
}
636-
#else
637-
if (deterministicMNManager->IsDIP3Active()) {
564+
if (!pwalletMain) {
638565
throw JSONRPCError(RPC_INVALID_PARAMETER, "vote-many not supported when wallet is disabled.");
639566
}
640-
#endif
641567

642-
return VoteWithMasternodeList(entries, hash, eVoteSignal, eVoteOutcome);
568+
std::map<uint256, CKey> votingKeys;
569+
570+
auto mnList = deterministicMNManager->GetListAtChainTip();
571+
mnList.ForEachMN(true, [&](const CDeterministicMNCPtr& dmn) {
572+
CKey votingKey;
573+
if (pwalletMain->GetKey(dmn->pdmnState->keyIDVoting, votingKey)) {
574+
votingKeys.emplace(dmn->proTxHash, votingKey);
575+
}
576+
});
577+
578+
return VoteWithMasternodes(votingKeys, hash, eVoteSignal, eVoteOutcome);
643579
}
644580

645581
void gobject_vote_alias_help()
646582
{
647583
throw std::runtime_error(
648584
"gobject vote-alias <governance-hash> <vote> <vote-outcome> <alias-name>\n"
649-
"Vote on a governance object by masternode alias (using masternode.conf setup)\n"
585+
"Vote on a governance object by masternode's voting key (if present in local wallet)\n"
650586
"\nArguments:\n"
651587
"1. governance-hash (string, required) hash of the governance object\n"
652588
"2. vote (string, required) vote, possible values: [funding|valid|delete|endorsed]\n"
653589
"3. vote-outcome (string, required) vote outcome, possible values: [yes|no|abstain]\n"
654-
"4. alias-name (string, required) masternode alias or proTxHash after DIP3 activation"
590+
"4. protx-hash (string, required) masternode's proTxHash"
655591
);
656592
}
657593

@@ -676,41 +612,27 @@ UniValue gobject_vote_alias(const JSONRPCRequest& request)
676612
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid vote outcome. Please use one of the following: 'yes', 'no' or 'abstain'");
677613
}
678614

679-
std::vector<CMasternodeConfig::CMasternodeEntry> entries;
680-
681-
if (deterministicMNManager->IsDIP3Active()) {
682-
#ifdef ENABLE_WALLET
683-
if (!pwalletMain) {
684-
throw JSONRPCError(RPC_INVALID_PARAMETER, "vote-alias not supported when wallet is disabled");
685-
}
686-
687-
uint256 proTxHash = ParseHashV(request.params[4], "alias-name");
688-
auto dmn = deterministicMNManager->GetListAtChainTip().GetValidMN(proTxHash);
689-
if (!dmn) {
690-
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid or unknown proTxHash");
691-
}
615+
if (!pwalletMain) {
616+
throw JSONRPCError(RPC_INVALID_PARAMETER, "vote-alias not supported when wallet is disabled");
617+
}
692618

693-
CKey votingKey;
694-
if (!pwalletMain->GetKey(dmn->pdmnState->keyIDVoting, votingKey)) {
695-
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Voting ekey %s not known by wallet", CBitcoinAddress(dmn->pdmnState->keyIDVoting).ToString()));
696-
}
619+
uint256 proTxHash = ParseHashV(request.params[4], "protx-hash");
620+
auto dmn = deterministicMNManager->GetListAtChainTip().GetValidMN(proTxHash);
621+
if (!dmn) {
622+
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid or unknown proTxHash");
623+
}
697624

698-
CBitcoinSecret secret(votingKey);
699-
CMasternodeConfig::CMasternodeEntry mne(dmn->proTxHash.ToString(), dmn->pdmnState->addr.ToStringIPPort(false), secret.ToString(), dmn->collateralOutpoint.hash.ToString(), itostr(dmn->collateralOutpoint.n));
700-
entries.push_back(mne);
701-
#else
702-
throw JSONRPCError(RPC_INVALID_PARAMETER, "vote-alias not supported when wallet is disabled");
703-
#endif
704-
} else {
705-
std::string strAlias = request.params[4].get_str();
706-
for (const auto& mne : masternodeConfig.getEntries()) {
707-
if (strAlias == mne.getAlias())
708-
entries.push_back(mne);
709-
}
625+
CKey votingKey;
626+
if (!pwalletMain->GetKey(dmn->pdmnState->keyIDVoting, votingKey)) {
627+
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Voting key %s not known by wallet", CBitcoinAddress(dmn->pdmnState->keyIDVoting).ToString()));
710628
}
711629

712-
return VoteWithMasternodeList(entries, hash, eVoteSignal, eVoteOutcome);
630+
std::map<uint256, CKey> votingKeys;
631+
votingKeys.emplace(proTxHash, votingKey);
632+
633+
return VoteWithMasternodes(votingKeys, hash, eVoteSignal, eVoteOutcome);
713634
}
635+
#endif
714636

715637
UniValue ListObjects(const std::string& strCachedSignal, const std::string& strType, int nStartTime)
716638
{
@@ -1063,10 +985,12 @@ UniValue gobject(const JSONRPCRequest& request)
1063985
return gobject_submit(request);
1064986
} else if (strCommand == "vote-conf") {
1065987
return gobject_vote_conf(request);
988+
#ifdef ENABLE_WALLET
1066989
} else if (strCommand == "vote-many") {
1067990
return gobject_vote_many(request);
1068991
} else if (strCommand == "vote-alias") {
1069992
return gobject_vote_alias(request);
993+
#endif
1070994
} else if (strCommand == "list") {
1071995
// USERS CAN QUERY THE SYSTEM FOR A LIST OF VARIOUS GOVERNANCE ITEMS
1072996
return gobject_list(request);
@@ -1133,10 +1057,9 @@ UniValue voteraw(const JSONRPCRequest& request)
11331057
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
11341058
}
11351059

1136-
CMasternode mn;
1137-
bool fMnFound = mnodeman.Get(outpoint, mn);
1060+
auto dmn = deterministicMNManager->GetListAtChainTip().GetValidMNByCollateral(outpoint);
11381061

1139-
if (!fMnFound) {
1062+
if (!dmn) {
11401063
throw JSONRPCError(RPC_INTERNAL_ERROR, "Failure to find masternode in list : " + outpoint.ToStringShort());
11411064
}
11421065

0 commit comments

Comments
 (0)