2021-04-20 21:33:02 +02:00
|
|
|
// Copyright (c) 2014-2021 The Dash Core developers
|
2016-11-13 18:52:34 +01:00
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2021-10-01 21:19:08 +02:00
|
|
|
#include <governance/votedb.h>
|
2016-11-13 18:52:34 +01:00
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
CGovernanceObjectVoteFile::CGovernanceObjectVoteFile() :
|
|
|
|
nMemoryVotes(0),
|
|
|
|
listVotes(),
|
|
|
|
mapVoteIndex()
|
|
|
|
{
|
|
|
|
}
|
2016-11-13 18:52:34 +01:00
|
|
|
|
2018-09-28 09:56:17 +02:00
|
|
|
CGovernanceObjectVoteFile::CGovernanceObjectVoteFile(const CGovernanceObjectVoteFile& other) :
|
|
|
|
nMemoryVotes(other.nMemoryVotes),
|
|
|
|
listVotes(other.listVotes),
|
|
|
|
mapVoteIndex()
|
2016-11-13 18:52:34 +01:00
|
|
|
{
|
|
|
|
RebuildIndex();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CGovernanceObjectVoteFile::AddVote(const CGovernanceVote& vote)
|
|
|
|
{
|
2018-03-19 14:08:32 +01:00
|
|
|
uint256 nHash = vote.GetHash();
|
|
|
|
// make sure to never add/update already known votes
|
|
|
|
if (HasVote(nHash))
|
|
|
|
return;
|
2016-11-13 18:52:34 +01:00
|
|
|
listVotes.push_front(vote);
|
2018-03-19 14:08:32 +01:00
|
|
|
mapVoteIndex.emplace(nHash, listVotes.begin());
|
2016-11-13 18:52:34 +01:00
|
|
|
++nMemoryVotes;
|
2019-04-01 13:10:01 +02:00
|
|
|
RemoveOldVotes(vote);
|
2016-11-13 18:52:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool CGovernanceObjectVoteFile::HasVote(const uint256& nHash) const
|
|
|
|
{
|
2018-03-20 12:04:59 +01:00
|
|
|
return mapVoteIndex.find(nHash) != mapVoteIndex.end();
|
2016-11-13 18:52:34 +01:00
|
|
|
}
|
|
|
|
|
2018-02-21 17:35:37 +01:00
|
|
|
bool CGovernanceObjectVoteFile::SerializeVoteToStream(const uint256& nHash, CDataStream& ss) const
|
2016-11-13 18:52:34 +01:00
|
|
|
{
|
2021-01-26 04:31:31 +01:00
|
|
|
auto it = mapVoteIndex.find(nHash);
|
2018-09-28 09:56:17 +02:00
|
|
|
if (it == mapVoteIndex.end()) {
|
2016-11-13 18:52:34 +01:00
|
|
|
return false;
|
|
|
|
}
|
2018-02-21 17:35:37 +01:00
|
|
|
ss << *(it->second);
|
2016-11-13 18:52:34 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<CGovernanceVote> CGovernanceObjectVoteFile::GetVotes() const
|
|
|
|
{
|
|
|
|
std::vector<CGovernanceVote> vecResult;
|
2021-04-23 00:32:03 +02:00
|
|
|
vecResult.reserve(listVotes.size());
|
|
|
|
std::copy(std::begin(listVotes), std::end(listVotes), std::back_inserter(vecResult));
|
2016-11-13 18:52:34 +01:00
|
|
|
return vecResult;
|
|
|
|
}
|
|
|
|
|
2017-09-11 16:13:48 +02:00
|
|
|
void CGovernanceObjectVoteFile::RemoveVotesFromMasternode(const COutPoint& outpointMasternode)
|
2016-11-13 18:52:34 +01:00
|
|
|
{
|
2021-01-26 04:31:31 +01:00
|
|
|
auto it = listVotes.begin();
|
2018-09-28 09:56:17 +02:00
|
|
|
while (it != listVotes.end()) {
|
|
|
|
if (it->GetMasternodeOutpoint() == outpointMasternode) {
|
2017-04-03 22:06:33 +02:00
|
|
|
--nMemoryVotes;
|
2017-01-21 06:26:35 +01:00
|
|
|
mapVoteIndex.erase(it->GetHash());
|
2016-11-13 18:52:34 +01:00
|
|
|
listVotes.erase(it++);
|
2018-09-28 09:56:17 +02:00
|
|
|
} else {
|
2016-11-13 18:52:34 +01:00
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-11 10:35:36 +01:00
|
|
|
std::set<uint256> CGovernanceObjectVoteFile::RemoveInvalidVotes(const CDeterministicMNList& tip_mn_list, const COutPoint& outpointMasternode, bool fProposal)
|
2018-12-20 14:27:48 +01:00
|
|
|
{
|
|
|
|
std::set<uint256> removedVotes;
|
|
|
|
|
2021-01-26 04:31:31 +01:00
|
|
|
auto it = listVotes.begin();
|
2018-12-20 14:27:48 +01:00
|
|
|
while (it != listVotes.end()) {
|
2019-03-30 15:54:22 +01:00
|
|
|
if (it->GetMasternodeOutpoint() == outpointMasternode) {
|
|
|
|
bool useVotingKey = fProposal && (it->GetSignal() == VOTE_SIGNAL_FUNDING);
|
2024-03-11 10:35:36 +01:00
|
|
|
if (!it->IsValid(tip_mn_list, useVotingKey)) {
|
2018-12-20 14:27:48 +01:00
|
|
|
removedVotes.emplace(it->GetHash());
|
|
|
|
--nMemoryVotes;
|
|
|
|
mapVoteIndex.erase(it->GetHash());
|
|
|
|
listVotes.erase(it++);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
return removedVotes;
|
|
|
|
}
|
|
|
|
|
2019-04-01 13:10:01 +02:00
|
|
|
void CGovernanceObjectVoteFile::RemoveOldVotes(const CGovernanceVote& vote)
|
|
|
|
{
|
2021-01-26 04:31:31 +01:00
|
|
|
auto it = listVotes.begin();
|
2019-04-01 13:10:01 +02:00
|
|
|
while (it != listVotes.end()) {
|
|
|
|
if (it->GetMasternodeOutpoint() == vote.GetMasternodeOutpoint() // same masternode
|
|
|
|
&& it->GetParentHash() == vote.GetParentHash() // same governance object (e.g. same proposal)
|
|
|
|
&& it->GetSignal() == vote.GetSignal() // same signal (e.g. "funding", "delete", etc.)
|
|
|
|
&& it->GetTimestamp() < vote.GetTimestamp()) // older than new vote
|
|
|
|
{
|
|
|
|
--nMemoryVotes;
|
|
|
|
mapVoteIndex.erase(it->GetHash());
|
|
|
|
listVotes.erase(it++);
|
|
|
|
} else {
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-13 18:52:34 +01:00
|
|
|
void CGovernanceObjectVoteFile::RebuildIndex()
|
|
|
|
{
|
|
|
|
mapVoteIndex.clear();
|
2017-04-03 22:06:33 +02:00
|
|
|
nMemoryVotes = 0;
|
2021-01-26 04:31:31 +01:00
|
|
|
auto it = listVotes.begin();
|
2018-09-28 09:56:17 +02:00
|
|
|
while (it != listVotes.end()) {
|
2021-06-26 15:09:09 +02:00
|
|
|
const CGovernanceVote& vote = *it;
|
2017-04-03 22:06:33 +02:00
|
|
|
uint256 nHash = vote.GetHash();
|
2018-09-28 09:56:17 +02:00
|
|
|
if (mapVoteIndex.find(nHash) == mapVoteIndex.end()) {
|
2017-04-03 22:06:33 +02:00
|
|
|
mapVoteIndex[nHash] = it;
|
|
|
|
++nMemoryVotes;
|
|
|
|
++it;
|
2018-09-28 09:56:17 +02:00
|
|
|
} else {
|
2017-04-03 22:06:33 +02:00
|
|
|
listVotes.erase(it++);
|
|
|
|
}
|
2016-11-13 18:52:34 +01:00
|
|
|
}
|
|
|
|
}
|