LCOV - code coverage report
Current view: top level - src/budget - budgetmanager.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 39 40 97.5 %
Date: 2025-02-23 09:33:43 Functions: 8 9 88.9 %

          Line data    Source code
       1             : // Copyright (c) 2014-2015 The Dash developers
       2             : // Copyright (c) 2015-2022 The PIVX Core developers
       3             : // Distributed under the MIT/X11 software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #ifndef PIVX_BUDGET_BUDGETMANAGER_H
       7             : #define PIVX_BUDGET_BUDGETMANAGER_H
       8             : 
       9             : #include "budget/budgetproposal.h"
      10             : #include "budget/finalizedbudget.h"
      11             : #include "validationinterface.h"
      12             : 
      13             : class CValidationState;
      14             : 
      15             : #define ORPHAN_VOTES_CACHE_LIMIT 10000
      16             : 
      17             : //
      18             : // Budget Manager : Contains all proposals for the budget
      19             : //
      20             : class CBudgetManager : public CValidationInterface
      21             : {
      22             : protected:
      23             :     // map budget hash --> CollTx hash.
      24             :     // hold unconfirmed finalized-budgets collateral txes until they mature enough to use
      25             :     std::map<uint256, uint256> mapUnconfirmedFeeTx;                         // guarded by cs_budgets
      26             : 
      27             :     // map CollTx hash --> budget hash
      28             :     // keep track of collaterals for valid budgets/proposals (for reorgs)
      29             :     std::map<uint256, uint256> mapFeeTxToProposal;                          // guarded by cs_proposals
      30             :     std::map<uint256, uint256> mapFeeTxToBudget;                            // guarded by cs_budgets
      31             : 
      32             :     std::map<uint256, CBudgetProposal> mapProposals;                        // guarded by cs_proposals
      33             :     std::map<uint256, CFinalizedBudget> mapFinalizedBudgets;                // guarded by cs_budgets
      34             : 
      35             :     std::map<uint256, CBudgetVote> mapSeenProposalVotes;                    // guarded by cs_votes
      36             :     typedef std::pair<std::vector<CBudgetVote>, int64_t> PropVotesAndLastVoteReceivedTime;
      37             :     std::map<uint256, PropVotesAndLastVoteReceivedTime> mapOrphanProposalVotes;        // guarded by cs_votes
      38             :     std::map<uint256, CFinalizedBudgetVote> mapSeenFinalizedBudgetVotes;    // guarded by cs_finalizedvotes
      39             :     typedef std::pair<std::vector<CFinalizedBudgetVote>, int64_t> BudVotesAndLastVoteReceivedTime;
      40             :     std::map<uint256, BudVotesAndLastVoteReceivedTime> mapOrphanFinalizedBudgetVotes;  // guarded by cs_finalizedvotes
      41             : 
      42             :     // Memory Only. Updated in NewBlock (blocks arrive in order)
      43             :     std::atomic<int> nBestHeight;
      44             : 
      45             :     struct HighestFinBudget {
      46             :         const CFinalizedBudget* m_budget_fin{nullptr};
      47             :         int m_vote_count{0};
      48             :     };
      49             : 
      50             :     // Returns a const pointer to the budget with highest vote count
      51             :     HighestFinBudget GetBudgetWithHighestVoteCount(int chainHeight) const;
      52             :     int GetHighestVoteCount(int chainHeight) const;
      53             :     // Get the payee and amount for the budget with the highest vote count
      54             :     bool GetPayeeAndAmount(int chainHeight, CScript& payeeRet, CAmount& nAmountRet) const;
      55             :     // Marks synced all votes in proposals and finalized budgets
      56             :     void SetSynced(bool synced);
      57             : 
      58             : public:
      59             :     // critical sections to protect the inner data structures (must be locked in this order)
      60             :     mutable RecursiveMutex cs_budgets;
      61             :     mutable RecursiveMutex cs_proposals;
      62             :     mutable RecursiveMutex cs_finalizedvotes;
      63             :     mutable RecursiveMutex cs_votes;
      64             : 
      65             :     // budget finalization
      66             :     std::string strBudgetMode;
      67             : 
      68         486 :     CBudgetManager() {}
      69             : 
      70             :     void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
      71             : 
      72       11984 :     bool HaveProposal(const uint256& propHash) const { LOCK(cs_proposals); return mapProposals.count(propHash); }
      73        1114 :     bool HaveSeenProposalVote(const uint256& voteHash) const { LOCK(cs_votes); return mapSeenProposalVotes.count(voteHash); }
      74         776 :     bool HaveFinalizedBudget(const uint256& budgetHash) const { LOCK(cs_budgets); return mapFinalizedBudgets.count(budgetHash); }
      75        1038 :     bool HaveSeenFinalizedBudgetVote(const uint256& voteHash) const { LOCK(cs_finalizedvotes); return mapSeenFinalizedBudgetVotes.count(voteHash); }
      76             : 
      77             :     // Clears and reloads seen votes in the maps, and clears orphan votes
      78             :     void ReloadMapSeen();
      79             : 
      80             :     void AddSeenProposalVote(const CBudgetVote& vote);
      81             :     void AddSeenFinalizedBudgetVote(const CFinalizedBudgetVote& vote);
      82             : 
      83             :     void RemoveStaleVotesOnProposal(CBudgetProposal* prop);
      84             :     void RemoveStaleVotesOnFinalBudget(CFinalizedBudget* fbud);
      85             : 
      86             :     // Use const operator std::map::at(), thus existence must be checked before calling.
      87             :     CDataStream GetProposalVoteSerialized(const uint256& voteHash) const;
      88             :     CDataStream GetProposalSerialized(const uint256& propHash) const;
      89             :     CDataStream GetFinalizedBudgetVoteSerialized(const uint256& voteHash) const;
      90             :     CDataStream GetFinalizedBudgetSerialized(const uint256& budgetHash) const;
      91             : 
      92             :     bool AddAndRelayProposalVote(const CBudgetVote& vote, std::string& strError);
      93             : 
      94             :     // sets strProposal of a CFinalizedBudget reference
      95             :     void SetBudgetProposalsStr(CFinalizedBudget& finalizedBudget) const;
      96             : 
      97             :     // checks finalized budget proposals (existence, payee, amount) for the finalized budget
      98             :     // in the map, with given nHash. Returns error string if any, or "OK" otherwise
      99             :     std::string GetFinalizedBudgetStatus(const uint256& nHash) const;
     100             : 
     101         894 :     void ResetSync() { SetSynced(false); }
     102        1111 :     void MarkSynced() { SetSynced(true); }
     103             :     // Respond to full budget sync requests and internally triggered partial budget items relay
     104             :     void Sync(CNode* node, bool fPartial);
     105             :     // Respond to single budget item requests (proposals / budget finalization)
     106             :     void SyncSingleItem(CNode* pfrom, const uint256& nProp);
     107       41745 :     void SetBestHeight(int height) { nBestHeight.store(height, std::memory_order_release); };
     108       16448 :     int GetBestHeight() const { return nBestHeight.load(std::memory_order_acquire); }
     109             : 
     110             :     bool ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, int& banScore);
     111             :     /// Process the message and returns the ban score (0 if no banning is needed)
     112             :     int ProcessMessageInner(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
     113             : 
     114             :     int ProcessBudgetVoteSync(const uint256& nProp, CNode* pfrom);
     115             :     int ProcessProposal(CBudgetProposal& proposal);
     116             :     int ProcessFinalizedBudget(CFinalizedBudget& finalbudget, CNode* pfrom);
     117             : 
     118             :     bool ProcessProposalVote(CBudgetVote& proposal, CNode* pfrom, CValidationState& state);
     119             :     bool ProcessFinalizedBudgetVote(CFinalizedBudgetVote& vote, CNode* pfrom, CValidationState& state);
     120             : 
     121             :     // functions returning a pointer in the map. Need cs_proposals/cs_budgets locked from the caller
     122             :     CBudgetProposal* FindProposal(const uint256& nHash);
     123             :     CFinalizedBudget* FindFinalizedBudget(const uint256& nHash);
     124             :     // const functions, copying the budget object to a reference and returning true if found
     125             :     bool GetProposal(const uint256& nHash, CBudgetProposal& bp) const;
     126             :     bool GetFinalizedBudget(const uint256& nHash, CFinalizedBudget& fb) const;
     127             :     // finds the proposal with the given name, with highest net yes count.
     128             :     const CBudgetProposal* FindProposalByName(const std::string& strProposalName) const;
     129             : 
     130             :     // Returns true if there is at least one proposal stored.
     131             :     bool HasAnyProposal() const { return WITH_LOCK(cs_proposals, return !mapProposals.empty()); }
     132             : 
     133             :     static CAmount GetTotalBudget(int nHeight);
     134             :     std::vector<CBudgetProposal> GetBudget();
     135             :     // Get all the budget proposals sorted by votes (highest to lowest)
     136             :     std::vector<CBudgetProposal*> GetAllProposalsOrdered();
     137             :     std::vector<CFinalizedBudget*> GetFinalizedBudgets();
     138             :     bool GetExpectedPayeeAmount(int chainHeight, CAmount& nAmountRet) const;
     139             :     bool IsBudgetPaymentBlock(int nBlockHeight) const;
     140             :     bool IsBudgetPaymentBlock(int nBlockHeight, int& nCountThreshold) const;
     141             :     bool AddProposal(CBudgetProposal& budgetProposal);
     142             :     bool AddFinalizedBudget(CFinalizedBudget& finalizedBudget, CNode* pfrom = nullptr);
     143             :     void ForceAddFinalizedBudget(const uint256& nHash, const uint256& feeTxId, const CFinalizedBudget& finalizedBudget);
     144             :     uint256 SubmitFinalBudget();
     145             : 
     146             :     bool UpdateProposal(const CBudgetVote& vote, CNode* pfrom, std::string& strError);
     147             :     bool UpdateFinalizedBudget(const CFinalizedBudgetVote& vote, CNode* pfrom, std::string& strError);
     148             :     TrxValidationStatus IsTransactionValid(const CTransaction& txNew, const uint256& nBlockHash, int nBlockHeight) const;
     149             :     std::string GetRequiredPaymentsString(int nBlockHeight);
     150             :     bool FillBlockPayee(CMutableTransaction& txCoinbase, CMutableTransaction& txCoinstake, const int nHeight, bool fProofOfStake) const;
     151             : 
     152             :     // Only initialized masternodes: sign and submit votes on valid finalized budgets
     153             :     void VoteOnFinalizedBudgets();
     154             : 
     155           0 :     int CountProposals() { LOCK(cs_proposals); return mapProposals.size(); }
     156             : 
     157             :     void CheckOrphanVotes();
     158           5 :     void Clear()
     159             :     {
     160           5 :         {
     161           5 :             LOCK(cs_proposals);
     162           5 :             mapProposals.clear();
     163           5 :             mapFeeTxToProposal.clear();
     164             :         }
     165           5 :         {
     166           5 :             LOCK(cs_budgets);
     167           5 :             mapFinalizedBudgets.clear();
     168           5 :             mapFeeTxToBudget.clear();
     169           5 :             mapUnconfirmedFeeTx.clear();
     170             :         }
     171           5 :         {
     172           5 :             LOCK(cs_votes);
     173           5 :             mapSeenProposalVotes.clear();
     174           5 :             mapOrphanProposalVotes.clear();
     175             :         }
     176           5 :         {
     177           5 :             LOCK(cs_finalizedvotes);
     178           5 :             mapSeenFinalizedBudgetVotes.clear();
     179           5 :             mapOrphanFinalizedBudgetVotes.clear();
     180             :         }
     181           5 :         LogPrintf("Budget object cleared\n");
     182           5 :     }
     183             :     void CheckAndRemove();
     184             :     std::string ToString() const;
     185             : 
     186             :     // Remove proposal/budget by FeeTx (called when a block is disconnected)
     187             :     void RemoveByFeeTxId(const uint256& feeTxId);
     188             : 
     189         920 :     SERIALIZE_METHODS(CBudgetManager, obj)
     190             :     {
     191             :         {
     192         460 :             LOCK(obj.cs_proposals);
     193         920 :             READWRITE(obj.mapProposals, obj.mapFeeTxToProposal);
     194             :         }
     195             :         {
     196         460 :             LOCK(obj.cs_votes);
     197         920 :             READWRITE(obj.mapSeenProposalVotes, obj.mapOrphanProposalVotes);
     198             :         }
     199             :         {
     200         460 :             LOCK(obj.cs_budgets);
     201         920 :             READWRITE(obj.mapFinalizedBudgets, obj.mapFeeTxToBudget, obj.mapUnconfirmedFeeTx);
     202             :         }
     203             :         {
     204         460 :             LOCK(obj.cs_finalizedvotes);
     205         920 :             READWRITE(obj.mapSeenFinalizedBudgetVotes, obj.mapOrphanFinalizedBudgetVotes);
     206             :         }
     207         460 :     }
     208             : };
     209             : 
     210             : extern CBudgetManager g_budgetman;
     211             : 
     212             : #endif // PIVX_BUDGET_BUDGETMANAGER_H

Generated by: LCOV version 1.14