PIVX Core  5.6.99
P2P Digital Currency
budgetmanager.h
Go to the documentation of this file.
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 
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 //
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 
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)
64 
65  // budget finalization
66  std::string strBudgetMode;
67 
69 
70  void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
71 
72  bool HaveProposal(const uint256& propHash) const { LOCK(cs_proposals); return mapProposals.count(propHash); }
73  bool HaveSeenProposalVote(const uint256& voteHash) const { LOCK(cs_votes); return mapSeenProposalVotes.count(voteHash); }
74  bool HaveFinalizedBudget(const uint256& budgetHash) const { LOCK(cs_budgets); return mapFinalizedBudgets.count(budgetHash); }
75  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);
82 
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;
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  void ResetSync() { SetSynced(false); }
102  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  void SetBestHeight(int height) { nBestHeight.store(height, std::memory_order_release); };
108  int GetBestHeight() const { return nBestHeight.load(std::memory_order_acquire); }
109 
110  bool ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv, int& banScore);
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);
120 
121  // functions returning a pointer in the map. Need cs_proposals/cs_budgets locked from the caller
122  CBudgetProposal* FindProposal(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);
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  int CountProposals() { LOCK(cs_proposals); return mapProposals.size(); }
156 
157  void CheckOrphanVotes();
158  void Clear()
159  {
160  {
162  mapProposals.clear();
163  mapFeeTxToProposal.clear();
164  }
165  {
166  LOCK(cs_budgets);
167  mapFinalizedBudgets.clear();
168  mapFeeTxToBudget.clear();
169  mapUnconfirmedFeeTx.clear();
170  }
171  {
172  LOCK(cs_votes);
173  mapSeenProposalVotes.clear();
174  mapOrphanProposalVotes.clear();
175  }
176  {
180  }
181  LogPrintf("Budget object cleared\n");
182  }
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 
190  {
191  {
192  LOCK(obj.cs_proposals);
193  READWRITE(obj.mapProposals, obj.mapFeeTxToProposal);
194  }
195  {
196  LOCK(obj.cs_votes);
197  READWRITE(obj.mapSeenProposalVotes, obj.mapOrphanProposalVotes);
198  }
199  {
200  LOCK(obj.cs_budgets);
201  READWRITE(obj.mapFinalizedBudgets, obj.mapFeeTxToBudget, obj.mapUnconfirmedFeeTx);
202  }
203  {
204  LOCK(obj.cs_finalizedvotes);
205  READWRITE(obj.mapSeenFinalizedBudgetVotes, obj.mapOrphanFinalizedBudgetVotes);
206  }
207  }
208 };
209 
211 
212 #endif // PIVX_BUDGET_BUDGETMANAGER_H
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
CBudgetManager g_budgetman
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:139
int GetBestHeight() const
bool AddProposal(CBudgetProposal &budgetProposal)
int GetHighestVoteCount(int chainHeight) const
std::map< uint256, BudVotesAndLastVoteReceivedTime > mapOrphanFinalizedBudgetVotes
Definition: budgetmanager.h:40
std::string strBudgetMode
Definition: budgetmanager.h:66
bool ProcessProposalVote(CBudgetVote &proposal, CNode *pfrom, CValidationState &state)
bool HaveSeenProposalVote(const uint256 &voteHash) const
Definition: budgetmanager.h:73
bool HaveProposal(const uint256 &propHash) const
Definition: budgetmanager.h:72
void SyncSingleItem(CNode *pfrom, const uint256 &nProp)
void SetBudgetProposalsStr(CFinalizedBudget &finalizedBudget) const
void SetSynced(bool synced)
HighestFinBudget GetBudgetWithHighestVoteCount(int chainHeight) const
bool UpdateProposal(const CBudgetVote &vote, CNode *pfrom, std::string &strError)
TrxValidationStatus IsTransactionValid(const CTransaction &txNew, const uint256 &nBlockHash, int nBlockHeight) const
bool GetProposal(const uint256 &nHash, CBudgetProposal &bp) const
RecursiveMutex cs_finalizedvotes
Definition: budgetmanager.h:62
CDataStream GetProposalVoteSerialized(const uint256 &voteHash) const
static CAmount GetTotalBudget(int nHeight)
std::map< uint256, uint256 > mapUnconfirmedFeeTx
Definition: budgetmanager.h:25
std::map< uint256, uint256 > mapFeeTxToBudget
Definition: budgetmanager.h:30
bool HasAnyProposal() const
bool FillBlockPayee(CMutableTransaction &txCoinbase, CMutableTransaction &txCoinstake, const int nHeight, bool fProofOfStake) const
bool GetPayeeAndAmount(int chainHeight, CScript &payeeRet, CAmount &nAmountRet) const
bool AddFinalizedBudget(CFinalizedBudget &finalizedBudget, CNode *pfrom=nullptr)
std::atomic< int > nBestHeight
Definition: budgetmanager.h:43
bool GetFinalizedBudget(const uint256 &nHash, CFinalizedBudget &fb) const
bool ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, int &banScore)
SERIALIZE_METHODS(CBudgetManager, obj)
bool HaveFinalizedBudget(const uint256 &budgetHash) const
Definition: budgetmanager.h:74
std::pair< std::vector< CBudgetVote >, int64_t > PropVotesAndLastVoteReceivedTime
Definition: budgetmanager.h:36
std::string ToString() const
std::map< uint256, CFinalizedBudget > mapFinalizedBudgets
Definition: budgetmanager.h:33
std::map< uint256, CBudgetVote > mapSeenProposalVotes
Definition: budgetmanager.h:35
void CheckOrphanVotes()
CBudgetProposal * FindProposal(const uint256 &nHash)
RecursiveMutex cs_budgets
Definition: budgetmanager.h:60
std::map< uint256, CBudgetProposal > mapProposals
Definition: budgetmanager.h:32
int ProcessProposal(CBudgetProposal &proposal)
std::vector< CBudgetProposal > GetBudget()
const CBudgetProposal * FindProposalByName(const std::string &strProposalName) const
bool ProcessFinalizedBudgetVote(CFinalizedBudgetVote &vote, CNode *pfrom, CValidationState &state)
RecursiveMutex cs_proposals
Definition: budgetmanager.h:61
CDataStream GetProposalSerialized(const uint256 &propHash) const
uint256 SubmitFinalBudget()
std::map< uint256, PropVotesAndLastVoteReceivedTime > mapOrphanProposalVotes
Definition: budgetmanager.h:37
RecursiveMutex cs_votes
Definition: budgetmanager.h:63
CDataStream GetFinalizedBudgetSerialized(const uint256 &budgetHash) const
std::map< uint256, uint256 > mapFeeTxToProposal
Definition: budgetmanager.h:29
void VoteOnFinalizedBudgets()
std::string GetRequiredPaymentsString(int nBlockHeight)
std::vector< CBudgetProposal * > GetAllProposalsOrdered()
bool GetExpectedPayeeAmount(int chainHeight, CAmount &nAmountRet) const
CDataStream GetFinalizedBudgetVoteSerialized(const uint256 &voteHash) const
CFinalizedBudget * FindFinalizedBudget(const uint256 &nHash)
std::vector< CFinalizedBudget * > GetFinalizedBudgets()
void RemoveByFeeTxId(const uint256 &feeTxId)
void RemoveStaleVotesOnFinalBudget(CFinalizedBudget *fbud)
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override
Notifies listeners when the block chain tip advances.
void SetBestHeight(int height)
bool HaveSeenFinalizedBudgetVote(const uint256 &voteHash) const
Definition: budgetmanager.h:75
int ProcessFinalizedBudget(CFinalizedBudget &finalbudget, CNode *pfrom)
int ProcessBudgetVoteSync(const uint256 &nProp, CNode *pfrom)
int ProcessMessageInner(CNode *pfrom, std::string &strCommand, CDataStream &vRecv)
Process the message and returns the ban score (0 if no banning is needed)
void Sync(CNode *node, bool fPartial)
void AddSeenFinalizedBudgetVote(const CFinalizedBudgetVote &vote)
std::pair< std::vector< CFinalizedBudgetVote >, int64_t > BudVotesAndLastVoteReceivedTime
Definition: budgetmanager.h:39
bool IsBudgetPaymentBlock(int nBlockHeight) const
std::string GetFinalizedBudgetStatus(const uint256 &nHash) const
std::map< uint256, CFinalizedBudgetVote > mapSeenFinalizedBudgetVotes
Definition: budgetmanager.h:38
void ForceAddFinalizedBudget(const uint256 &nHash, const uint256 &feeTxId, const CFinalizedBudget &finalizedBudget)
void AddSeenProposalVote(const CBudgetVote &vote)
bool AddAndRelayProposalVote(const CBudgetVote &vote, std::string &strError)
bool UpdateFinalizedBudget(const CFinalizedBudgetVote &vote, CNode *pfrom, std::string &strError)
void RemoveStaleVotesOnProposal(CBudgetProposal *prop)
Information about a peer.
Definition: net.h:669
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:244
Implement this to subscribe to events generated in validation.
Capture information about block/transaction validation.
Definition: validation.h:24
256-bit opaque blob.
Definition: uint256.h:138
TrxValidationStatus
@ LOCK
Definition: lockunlock.h:16
#define READWRITE(...)
Definition: serialize.h:183
const CFinalizedBudget * m_budget_fin
Definition: budgetmanager.h:46
A mutable version of CTransaction.
Definition: transaction.h:409
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:247