neobytes/src/governance-votedb.cpp
UdjinM6 a87909ec35
Keep the most recent gobject votes only (#2815)
* Keep the most recent gobject vote only

We don't need to store full vote data for old votes - we never relay them to other nodes anyway.
Still keep old hashes to avoid re-requesting data etc.

* add comment

* Drop getvotes rpc

* Compare vote signals, do not compare hashes

Also add comments
2019-04-01 14:10:01 +03:00

129 lines
3.7 KiB
C++

// Copyright (c) 2014-2018 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "governance-votedb.h"
CGovernanceObjectVoteFile::CGovernanceObjectVoteFile() :
nMemoryVotes(0),
listVotes(),
mapVoteIndex()
{
}
CGovernanceObjectVoteFile::CGovernanceObjectVoteFile(const CGovernanceObjectVoteFile& other) :
nMemoryVotes(other.nMemoryVotes),
listVotes(other.listVotes),
mapVoteIndex()
{
RebuildIndex();
}
void CGovernanceObjectVoteFile::AddVote(const CGovernanceVote& vote)
{
uint256 nHash = vote.GetHash();
// make sure to never add/update already known votes
if (HasVote(nHash))
return;
listVotes.push_front(vote);
mapVoteIndex.emplace(nHash, listVotes.begin());
++nMemoryVotes;
RemoveOldVotes(vote);
}
bool CGovernanceObjectVoteFile::HasVote(const uint256& nHash) const
{
return mapVoteIndex.find(nHash) != mapVoteIndex.end();
}
bool CGovernanceObjectVoteFile::SerializeVoteToStream(const uint256& nHash, CDataStream& ss) const
{
vote_m_cit it = mapVoteIndex.find(nHash);
if (it == mapVoteIndex.end()) {
return false;
}
ss << *(it->second);
return true;
}
std::vector<CGovernanceVote> CGovernanceObjectVoteFile::GetVotes() const
{
std::vector<CGovernanceVote> vecResult;
for (vote_l_cit it = listVotes.begin(); it != listVotes.end(); ++it) {
vecResult.push_back(*it);
}
return vecResult;
}
void CGovernanceObjectVoteFile::RemoveVotesFromMasternode(const COutPoint& outpointMasternode)
{
vote_l_it it = listVotes.begin();
while (it != listVotes.end()) {
if (it->GetMasternodeOutpoint() == outpointMasternode) {
--nMemoryVotes;
mapVoteIndex.erase(it->GetHash());
listVotes.erase(it++);
} else {
++it;
}
}
}
std::set<uint256> CGovernanceObjectVoteFile::RemoveInvalidVotes(const COutPoint& outpointMasternode, bool fProposal)
{
std::set<uint256> removedVotes;
vote_l_it it = listVotes.begin();
while (it != listVotes.end()) {
if (it->GetMasternodeOutpoint() == outpointMasternode) {
bool useVotingKey = fProposal && (it->GetSignal() == VOTE_SIGNAL_FUNDING);
if (!it->IsValid(useVotingKey)) {
removedVotes.emplace(it->GetHash());
--nMemoryVotes;
mapVoteIndex.erase(it->GetHash());
listVotes.erase(it++);
continue;
}
}
++it;
}
return removedVotes;
}
void CGovernanceObjectVoteFile::RemoveOldVotes(const CGovernanceVote& vote)
{
vote_l_it it = listVotes.begin();
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;
}
}
}
void CGovernanceObjectVoteFile::RebuildIndex()
{
mapVoteIndex.clear();
nMemoryVotes = 0;
vote_l_it it = listVotes.begin();
while (it != listVotes.end()) {
CGovernanceVote& vote = *it;
uint256 nHash = vote.GetHash();
if (mapVoteIndex.find(nHash) == mapVoteIndex.end()) {
mapVoteIndex[nHash] = it;
++nMemoryVotes;
++it;
} else {
listVotes.erase(it++);
}
}
}