mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
Clear votes which were created before spork15 activation and use operator key for non-funding votes (#2512)
* Clear votes which were created before spork15 activation * Reject incoming votes which were created pre-DIP3 * Only use voting keys for VOTE_SIGNAL_FUNDING The other vote signals are meant to be emitted by sentinel and must thus be signed with the operator key. * Simplify GetMinVoteTime * Review suggestions/fixes * Add missing mutex in CGovernanceObject::RemoveOldVotes
This commit is contained in:
parent
f6f6d075dc
commit
0c1b683a06
@ -177,7 +177,7 @@ bool CGovernanceObject::ProcessVote(CNode* pfrom,
|
||||
}
|
||||
}
|
||||
|
||||
bool onlyOwnerAllowed = nObjectType == GOVERNANCE_OBJECT_PROPOSAL;
|
||||
bool onlyOwnerAllowed = nObjectType == GOVERNANCE_OBJECT_PROPOSAL && vote.GetSignal() == VOTE_SIGNAL_FUNDING;
|
||||
|
||||
// Finally check that the vote is actually valid (done last because of cost of signature verification)
|
||||
if (!vote.IsValid(onlyOwnerAllowed)) {
|
||||
@ -790,3 +790,21 @@ void CGovernanceObject::CheckOrphanVotes(CConnman& connman)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint256> CGovernanceObject::RemoveOldVotes(unsigned int nMinTime)
|
||||
{
|
||||
LOCK(cs);
|
||||
|
||||
auto removed = fileVotes.RemoveOldVotes(nMinTime);
|
||||
|
||||
if (!removed.empty()) {
|
||||
std::string removedStr;
|
||||
for (auto& h : removed) {
|
||||
removedStr += strprintf(" %s\n", h.ToString());
|
||||
}
|
||||
LogPrintf("CGovernanceObject::RemoveOldVotes -- Removed %d old (pre-DIP3) votes for %s:\n%s\n", removed.size(), GetHash().ToString(), removedStr);
|
||||
fDirtyCache = true;
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
@ -350,6 +350,9 @@ private:
|
||||
void ClearMasternodeVotes();
|
||||
|
||||
void CheckOrphanVotes(CConnman& connman);
|
||||
|
||||
// TODO can be removed after DIP3 is fully deployed
|
||||
std::vector<uint256> RemoveOldVotes(unsigned int nMinTime);
|
||||
};
|
||||
|
||||
|
||||
|
@ -68,6 +68,23 @@ void CGovernanceObjectVoteFile::RemoveVotesFromMasternode(const COutPoint& outpo
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint256> CGovernanceObjectVoteFile::RemoveOldVotes(unsigned int nMinTime)
|
||||
{
|
||||
std::vector<uint256> removed;
|
||||
vote_l_it it = listVotes.begin();
|
||||
while (it != listVotes.end()) {
|
||||
if (it->GetTimestamp() < nMinTime) {
|
||||
--nMemoryVotes;
|
||||
removed.emplace_back(it->GetHash());
|
||||
mapVoteIndex.erase(it->GetHash());
|
||||
listVotes.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
void CGovernanceObjectVoteFile::RebuildIndex()
|
||||
{
|
||||
mapVoteIndex.clear();
|
||||
|
@ -74,6 +74,9 @@ public:
|
||||
|
||||
void RemoveVotesFromMasternode(const COutPoint& outpointMasternode);
|
||||
|
||||
// TODO can be removed after full DIP3 deployment
|
||||
std::vector<uint256> RemoveOldVotes(unsigned int nMinTime);
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
|
@ -222,6 +222,12 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, const std::string& strComm
|
||||
CGovernanceVote vote;
|
||||
vRecv >> vote;
|
||||
|
||||
// TODO remove this check after full DIP3 deployment
|
||||
if (vote.GetTimestamp() < GetMinVoteTime()) {
|
||||
// Ignore votes pre-DIP3
|
||||
return;
|
||||
}
|
||||
|
||||
uint256 nHash = vote.GetHash();
|
||||
|
||||
{
|
||||
@ -573,6 +579,10 @@ void CGovernanceManager::DoMaintenance(CConnman& connman)
|
||||
{
|
||||
if (fLiteMode || !masternodeSync.IsSynced() || ShutdownRequested()) return;
|
||||
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
ClearPreDIP3Votes();
|
||||
}
|
||||
|
||||
// CHECK OBJECTS WE'VE ASKED FOR, REMOVE OLD ENTRIES
|
||||
|
||||
CleanOrphanObjects();
|
||||
@ -676,7 +686,7 @@ void CGovernanceManager::SyncSingleObjAndItsVotes(CNode* pnode, const uint256& n
|
||||
for (const auto& vote : fileVotes.GetVotes()) {
|
||||
uint256 nVoteHash = vote.GetHash();
|
||||
|
||||
bool onlyOwnerAllowed = govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL;
|
||||
bool onlyOwnerAllowed = govobj.GetObjectType() == GOVERNANCE_OBJECT_PROPOSAL && vote.GetSignal() == VOTE_SIGNAL_FUNDING;
|
||||
|
||||
if (filter.contains(nVoteHash) || !vote.IsValid(onlyOwnerAllowed)) {
|
||||
continue;
|
||||
@ -1291,6 +1301,10 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex* pindex, CConnman& co
|
||||
nCachedBlockHeight = pindex->nHeight;
|
||||
LogPrint("gobject", "CGovernanceManager::UpdatedBlockTip -- nCachedBlockHeight: %d\n", nCachedBlockHeight);
|
||||
|
||||
if (deterministicMNManager->IsDeterministicMNsSporkActive(pindex->nHeight)) {
|
||||
ClearPreDIP3Votes();
|
||||
}
|
||||
|
||||
CheckPostponedObjects(connman);
|
||||
|
||||
CSuperblockManager::ExecuteBestSuperblock(pindex->nHeight);
|
||||
@ -1342,3 +1356,37 @@ void CGovernanceManager::CleanOrphanObjects()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CGovernanceManager::GetMinVoteTime()
|
||||
{
|
||||
LOCK(cs_main);
|
||||
if (!deterministicMNManager->IsDeterministicMNsSporkActive()) {
|
||||
return 0;
|
||||
}
|
||||
int64_t dip3SporkHeight = sporkManager.GetSporkValue(SPORK_15_DETERMINISTIC_MNS_ENABLED);
|
||||
return chainActive[dip3SporkHeight]->nTime;
|
||||
}
|
||||
|
||||
void CGovernanceManager::ClearPreDIP3Votes()
|
||||
{
|
||||
// This removes all votes which were created before DIP3 spork15 activation
|
||||
// All these votes are invalid immediately after spork15 activation due to the introduction of voting keys, which
|
||||
// are not equal to the old masternode private keys
|
||||
|
||||
unsigned int minVoteTime = GetMinVoteTime();
|
||||
|
||||
LOCK(cs);
|
||||
for (auto& p : mapObjects) {
|
||||
auto& obj = p.second;
|
||||
auto removed = obj.RemoveOldVotes(minVoteTime);
|
||||
if (removed.empty()) {
|
||||
continue;
|
||||
}
|
||||
for (auto& voteHash : removed) {
|
||||
cmapVoteToObject.Erase(voteHash);
|
||||
cmapInvalidVotes.Erase(voteHash);
|
||||
cmmapOrphanVotes.Erase(voteHash);
|
||||
setRequestedVotes.erase(voteHash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -448,6 +448,10 @@ private:
|
||||
void RequestOrphanObjects(CConnman& connman);
|
||||
|
||||
void CleanOrphanObjects();
|
||||
|
||||
// TODO can be removed after full DIP3 deployment
|
||||
unsigned int GetMinVoteTime();
|
||||
void ClearPreDIP3Votes();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1086,7 +1086,7 @@ UniValue voteraw(const JSONRPCRequest& request)
|
||||
vote.SetTime(nTime);
|
||||
vote.SetSignature(vchSig);
|
||||
|
||||
bool onlyOwnerAllowed = govObjType == GOVERNANCE_OBJECT_PROPOSAL;
|
||||
bool onlyOwnerAllowed = govObjType == GOVERNANCE_OBJECT_PROPOSAL && vote.GetSignal() == VOTE_SIGNAL_FUNDING;
|
||||
|
||||
if (!vote.IsValid(onlyOwnerAllowed)) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Failure to verify vote.");
|
||||
|
Loading…
Reference in New Issue
Block a user