mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
Fix multiple issues with governance voting after spork15 activation (#2526)
* Check resulting signature for validity when signing with BLS operator keys * Support specifying proTxHash when using "gobject vote-alias" The "alias-name" is now interpreted as proTxHash when deterministic MN lists are active. The classical "alias" as found in masternode.conf has no meaning after spork15 activation. * Don't use masternode.conf list in gobject_vote_many when spork15 is active Keys don't match anymore so we should only rely on the deterministic list and the local wallet's keys. * Check for pwalletMain not being null in gobject_vote_many * Allow to use vote-conf for non-proposal votes when spork15 is active This fixes sentinel not being able to create triggers on testnet. * Fix error message * Fix no-wallet compilation and check for pwalletMain at runtime
This commit is contained in:
parent
60867978d6
commit
d2ca9eddee
@ -333,6 +333,9 @@ bool CGovernanceObject::CheckSignature(const CKeyID& keyID) const
|
||||
bool CGovernanceObject::Sign(const CBLSSecretKey& key)
|
||||
{
|
||||
CBLSSignature sig = key.Sign(GetSignatureHash());
|
||||
if (!key.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
sig.GetBuf(vchSig);
|
||||
return true;
|
||||
}
|
||||
|
@ -218,6 +218,9 @@ bool CGovernanceVote::Sign(const CBLSSecretKey& key)
|
||||
{
|
||||
uint256 hash = GetSignatureHash();
|
||||
CBLSSignature sig = key.Sign(hash);
|
||||
if (!sig.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
sig.GetBuf(vchSig);
|
||||
return true;
|
||||
}
|
||||
|
@ -1152,6 +1152,9 @@ bool CTxLockVote::Sign()
|
||||
uint256 hash = GetSignatureHash();
|
||||
|
||||
CBLSSignature sig = activeMasternodeInfo.blsKeyOperator->Sign(hash);
|
||||
if (!sig.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
sig.GetBuf(vchMasternodeSignature);
|
||||
} else if (sporkManager.IsSporkActive(SPORK_6_NEW_SIGS)) {
|
||||
uint256 hash = GetSignatureHash();
|
||||
|
@ -55,6 +55,9 @@ bool CPrivateSendQueue::Sign()
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
uint256 hash = GetSignatureHash();
|
||||
CBLSSignature sig = activeMasternodeInfo.blsKeyOperator->Sign(hash);
|
||||
if (!sig.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
sig.GetBuf(vchSig);
|
||||
} else if (sporkManager.IsSporkActive(SPORK_6_NEW_SIGS)) {
|
||||
uint256 hash = GetSignatureHash();
|
||||
@ -148,6 +151,9 @@ bool CPrivateSendBroadcastTx::Sign()
|
||||
uint256 hash = GetSignatureHash();
|
||||
|
||||
CBLSSignature sig = activeMasternodeInfo.blsKeyOperator->Sign(hash);
|
||||
if (!sig.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
sig.GetBuf(vchSig);
|
||||
} else if (sporkManager.IsSporkActive(SPORK_6_NEW_SIGS)) {
|
||||
uint256 hash = GetSignatureHash();
|
||||
|
@ -376,10 +376,6 @@ UniValue gobject_vote_conf(const JSONRPCRequest& request)
|
||||
if (request.fHelp || request.params.size() != 4)
|
||||
gobject_vote_conf_help();
|
||||
|
||||
if(deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Can't use vote-conf when deterministic masternodes are active");
|
||||
}
|
||||
|
||||
uint256 hash;
|
||||
|
||||
hash = ParseHashV(request.params[1], "Object hash");
|
||||
@ -430,7 +426,19 @@ UniValue gobject_vote_conf(const JSONRPCRequest& request)
|
||||
}
|
||||
|
||||
CGovernanceVote vote(mn.outpoint, hash, eVoteSignal, eVoteOutcome);
|
||||
if (!vote.Sign(activeMasternodeInfo.legacyKeyOperator, activeMasternodeInfo.legacyKeyIDOperator)) {
|
||||
|
||||
bool signSuccess = false;
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
if (govObjType == GOVERNANCE_OBJECT_PROPOSAL && eVoteSignal == VOTE_SIGNAL_FUNDING) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Can't use vote-conf for proposals when deterministic masternodes are active");
|
||||
}
|
||||
if (activeMasternodeInfo.blsKeyOperator) {
|
||||
signSuccess = vote.Sign(*activeMasternodeInfo.blsKeyOperator);
|
||||
}
|
||||
} else {
|
||||
signSuccess = vote.Sign(activeMasternodeInfo.legacyKeyOperator, activeMasternodeInfo.legacyKeyIDOperator);
|
||||
}
|
||||
if (!signSuccess) {
|
||||
nFailed++;
|
||||
statusObj.push_back(Pair("result", "failed"));
|
||||
statusObj.push_back(Pair("errorMessage", "Failure to sign."));
|
||||
@ -593,6 +601,11 @@ UniValue gobject_vote_many(const JSONRPCRequest& request)
|
||||
// We can remove this when we remove support for masternode.conf and only support wallet based masternode
|
||||
// management
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
if (!pwalletMain) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "vote-many not supported when wallet is disabled.");
|
||||
}
|
||||
entries.clear();
|
||||
|
||||
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||
mnList.ForEachMN(true, [&](const CDeterministicMNCPtr& dmn) {
|
||||
bool found = false;
|
||||
@ -620,6 +633,10 @@ UniValue gobject_vote_many(const JSONRPCRequest& request)
|
||||
}
|
||||
});
|
||||
}
|
||||
#else
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "vote-many not supported when wallet is disabled.");
|
||||
}
|
||||
#endif
|
||||
|
||||
return VoteWithMasternodeList(entries, hash, eVoteSignal, eVoteOutcome);
|
||||
@ -634,7 +651,7 @@ void gobject_vote_alias_help()
|
||||
"1. governance-hash (string, required) hash of the governance object\n"
|
||||
"2. vote (string, required) vote, possible values: [funding|valid|delete|endorsed]\n"
|
||||
"3. vote-outcome (string, required) vote outcome, possible values: [yes|no|abstain]\n"
|
||||
"4. alias-name (string, required) masternode alias"
|
||||
"4. alias-name (string, required) masternode alias or proTxHash after DIP3 activation"
|
||||
);
|
||||
}
|
||||
|
||||
@ -647,8 +664,6 @@ UniValue gobject_vote_alias(const JSONRPCRequest& request)
|
||||
std::string strVoteSignal = request.params[2].get_str();
|
||||
std::string strVoteOutcome = request.params[3].get_str();
|
||||
|
||||
std::string strAlias = request.params[4].get_str();
|
||||
|
||||
vote_signal_enum_t eVoteSignal = CGovernanceVoting::ConvertVoteSignal(strVoteSignal);
|
||||
if (eVoteSignal == VOTE_SIGNAL_NONE) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER,
|
||||
@ -662,10 +677,37 @@ UniValue gobject_vote_alias(const JSONRPCRequest& request)
|
||||
}
|
||||
|
||||
std::vector<CMasternodeConfig::CMasternodeEntry> entries;
|
||||
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
#ifdef ENABLE_WALLET
|
||||
if (!pwalletMain) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "vote-alias not supported when wallet is disabled");
|
||||
}
|
||||
|
||||
uint256 proTxHash = ParseHashV(request.params[4], "alias-name");
|
||||
auto dmn = deterministicMNManager->GetListAtChainTip().GetValidMN(proTxHash);
|
||||
if (!dmn) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid or unknown proTxHash");
|
||||
}
|
||||
|
||||
CKey votingKey;
|
||||
if (!pwalletMain->GetKey(dmn->pdmnState->keyIDVoting, votingKey)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Voting ekey %s not known by wallet", CBitcoinAddress(dmn->pdmnState->keyIDVoting).ToString()));
|
||||
}
|
||||
|
||||
CBitcoinSecret secret(votingKey);
|
||||
CMasternodeConfig::CMasternodeEntry mne(dmn->proTxHash.ToString(), dmn->pdmnState->addr.ToStringIPPort(false), secret.ToString(), dmn->collateralOutpoint.hash.ToString(), itostr(dmn->collateralOutpoint.n));
|
||||
entries.push_back(mne);
|
||||
#else
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "vote-alias not supported when wallet is disabled");
|
||||
#endif
|
||||
} else {
|
||||
std::string strAlias = request.params[4].get_str();
|
||||
for (const auto& mne : masternodeConfig.getEntries()) {
|
||||
if (strAlias == mne.getAlias())
|
||||
entries.push_back(mne);
|
||||
}
|
||||
}
|
||||
|
||||
return VoteWithMasternodeList(entries, hash, eVoteSignal, eVoteOutcome);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user