LCOV - code coverage report
Current view: top level - src/governance - votedb.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 54 87 62.1 %
Date: 2026-06-25 07:23:43 Functions: 10 12 83.3 %

          Line data    Source code
       1             : // Copyright (c) 2014-2024 The Dash Core developers
       2             : // Distributed under the MIT/X11 software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #include <governance/votedb.h>
       6             : 
       7             : #include <streams.h>
       8             : 
       9        1814 : CGovernanceObjectVoteFile::CGovernanceObjectVoteFile() :
      10             :     listVotes(),
      11             :     mapVoteIndex()
      12         907 : {
      13         907 : }
      14             : 
      15      125040 : CGovernanceObjectVoteFile::CGovernanceObjectVoteFile(const CGovernanceObjectVoteFile& other) :
      16       62520 :     nMemoryVotes(other.nMemoryVotes),
      17       62520 :     listVotes(other.listVotes),
      18       62520 :     mapVoteIndex()
      19       62520 : {
      20       62520 :     RebuildIndex();
      21      125040 : }
      22             : 
      23        1480 : void CGovernanceObjectVoteFile::AddVote(const CGovernanceVote& vote)
      24             : {
      25        1480 :     uint256 nHash = vote.GetHash();
      26             :     // make sure to never add/update already known votes
      27        1480 :     if (HasVote(nHash))
      28           0 :         return;
      29        1480 :     listVotes.push_front(vote);
      30        1480 :     mapVoteIndex.emplace(nHash, listVotes.begin());
      31        1480 :     ++nMemoryVotes;
      32        1480 :     RemoveOldVotes(vote);
      33        1480 : }
      34             : 
      35        4204 : bool CGovernanceObjectVoteFile::HasVote(const uint256& nHash) const
      36             : {
      37        4204 :     return mapVoteIndex.find(nHash) != mapVoteIndex.end();
      38             : }
      39             : 
      40        1224 : bool CGovernanceObjectVoteFile::SerializeVoteToStream(const uint256& nHash, CDataStream& ss) const
      41             : {
      42        1224 :     auto it = mapVoteIndex.find(nHash);
      43        1224 :     if (it == mapVoteIndex.end()) {
      44           0 :         return false;
      45             :     }
      46        1224 :     ss << *(it->second);
      47        1224 :     return true;
      48        1224 : }
      49             : 
      50        1146 : std::vector<CGovernanceVote> CGovernanceObjectVoteFile::GetVotes() const
      51             : {
      52        1146 :     std::vector<CGovernanceVote> vecResult;
      53        1146 :     vecResult.reserve(listVotes.size());
      54        1146 :     std::copy(std::begin(listVotes), std::end(listVotes), std::back_inserter(vecResult));
      55        1146 :     return vecResult;
      56        1146 : }
      57             : 
      58           0 : void CGovernanceObjectVoteFile::RemoveVotesFromMasternode(const COutPoint& outpointMasternode)
      59             : {
      60           0 :     auto it = listVotes.begin();
      61           0 :     while (it != listVotes.end()) {
      62           0 :         if (it->GetMasternodeOutpoint() == outpointMasternode) {
      63           0 :             --nMemoryVotes;
      64           0 :             mapVoteIndex.erase(it->GetHash());
      65           0 :             listVotes.erase(it++);
      66           0 :         } else {
      67           0 :             ++it;
      68             :         }
      69             :     }
      70           0 : }
      71             : 
      72           0 : std::set<uint256> CGovernanceObjectVoteFile::RemoveInvalidVotes(const CDeterministicMNList& tip_mn_list, const COutPoint& outpointMasternode, bool fProposal)
      73             : {
      74           0 :     std::set<uint256> removedVotes;
      75             : 
      76           0 :     auto it = listVotes.begin();
      77           0 :     while (it != listVotes.end()) {
      78           0 :         if (it->GetMasternodeOutpoint() == outpointMasternode) {
      79           0 :             bool useVotingKey = fProposal && (it->GetSignal() == VOTE_SIGNAL_FUNDING);
      80           0 :             if (!it->IsValid(tip_mn_list, useVotingKey)) {
      81           0 :                 removedVotes.emplace(it->GetHash());
      82           0 :                 --nMemoryVotes;
      83           0 :                 mapVoteIndex.erase(it->GetHash());
      84           0 :                 listVotes.erase(it++);
      85           0 :                 continue;
      86             :             }
      87           0 :         }
      88           0 :         ++it;
      89             :     }
      90             : 
      91           0 :     return removedVotes;
      92           0 : }
      93             : 
      94        1480 : void CGovernanceObjectVoteFile::RemoveOldVotes(const CGovernanceVote& vote)
      95             : {
      96        1480 :     auto it = listVotes.begin();
      97        5880 :     while (it != listVotes.end()) {
      98        5880 :         if (it->GetMasternodeOutpoint() == vote.GetMasternodeOutpoint() // same masternode
      99        4400 :             && it->GetParentHash() == vote.GetParentHash() // same governance object (e.g. same proposal)
     100        1480 :             && it->GetSignal() == vote.GetSignal() // same signal (e.g. "funding", "delete", etc.)
     101        1480 :             && it->GetTimestamp() < vote.GetTimestamp()) // older than new vote
     102             :         {
     103           0 :             --nMemoryVotes;
     104           0 :             mapVoteIndex.erase(it->GetHash());
     105           0 :             listVotes.erase(it++);
     106           0 :         } else {
     107        4400 :             ++it;
     108             :         }
     109             :     }
     110        1480 : }
     111             : 
     112       62520 : void CGovernanceObjectVoteFile::RebuildIndex()
     113             : {
     114       62520 :     mapVoteIndex.clear();
     115       62520 :     nMemoryVotes = 0;
     116       62520 :     auto it = listVotes.begin();
     117      362435 :     while (it != listVotes.end()) {
     118      299915 :         const CGovernanceVote& vote = *it;
     119      299915 :         uint256 nHash = vote.GetHash();
     120      299915 :         if (mapVoteIndex.find(nHash) == mapVoteIndex.end()) {
     121      299915 :             mapVoteIndex[nHash] = it;
     122      299915 :             ++nMemoryVotes;
     123      299915 :             ++it;
     124      299915 :         } else {
     125           0 :             listVotes.erase(it++);
     126             :         }
     127             :     }
     128       62520 : }

Generated by: LCOV version 1.16