22 #define BUDGET_ORPHAN_VOTES_CLEANUP_SECONDS (60 * 60)
24 static const std::string BUDGET_SYNC_REQUEST_RECV =
"budget-sync-recv";
29 bool CheckCollateral(
const uint256& nTxCollateralHash,
const uint256& nExpectedHash, std::string& strError, int64_t& nTime,
int nCurrentHeight,
bool fBudgetFinalization);
33 const auto reloadSeenMap = [](
auto& mutex1,
auto& mutex2,
const auto& mapBudgets,
auto& mapSeen,
auto& mapOrphans) {
34 LOCK2(mutex1, mutex2);
37 for (
const auto& b : mapBudgets) {
38 for (
const auto& it : b.second.mapVotes) {
39 const auto& vote = it.second;
41 mapSeen.emplace(vote.GetHash(), vote);
56 auto itProposal =
mapProposals.find(itOrphanVotes->first);
61 for (
const CBudgetVote& vote : itOrphanVotes->second.first) {
102 static int nSubmittedHeight = 0;
106 int nBlockStart = nCurrentHeight - nCurrentHeight % nBlocksPerCycle + nBlocksPerCycle;
107 if (nSubmittedHeight >= nBlockStart){
109 __func__, nSubmittedHeight, nBlockStart);
114 int finalizationWindow = ((nBlocksPerCycle / 30) * 2);
120 finalizationWindow = 64;
123 int nFinalizationStart = nBlockStart - finalizationWindow;
125 int nOffsetToStart = nFinalizationStart - nCurrentHeight;
127 if (nBlockStart - nCurrentHeight > finalizationWindow) {
128 LogPrint(
BCLog::MNBUDGET,
"%s: Too early for finalization. Current block is %ld, next Superblock is %ld.\n", __func__, nCurrentHeight, nBlockStart);
129 LogPrint(
BCLog::MNBUDGET,
"%s: First possible block for finalization: %ld. Last possible block for finalization: %ld. "
130 "You have to wait for %ld block(s) until Budget finalization will be possible\n", __func__, nFinalizationStart, nBlockStart, nOffsetToStart);
134 std::vector<CBudgetProposal> vBudgetProposals =
GetBudget();
135 std::string strBudgetName =
"main";
136 std::vector<CTxBudgetPayment> vecTxBudgetPayments;
138 for (
const auto& p : vBudgetProposals) {
141 txBudgetPayment.
payee = p.GetPayee();
142 txBudgetPayment.
nAmount = p.GetAllotted();
143 vecTxBudgetPayments.push_back(txBudgetPayment);
146 if (vecTxBudgetPayments.size() < 1) {
155 nSubmittedHeight = nCurrentHeight;
174 if (!
vpwallets[0]->CreateBudgetFeeTX(wtx, budgetHash, keyChange, BUDGET_FEE_TX)) {
181 const uint256& collateraltxid = wtx->GetHash();
195 nSubmittedHeight = nCurrentHeight;
203 std::string strProposals =
"";
206 for (
const uint256& hash: vHashes) {
208 strProposals += (strProposals ==
"" ?
"" :
", ") + token;
220 std::string retBadHashes =
"";
221 std::string retBadPayeeOrAmount =
"";
225 for (
int nBlockHeight = nBlockStart; nBlockHeight <= nBlockEnd; nBlockHeight++) {
239 retBadPayeeOrAmount += (retBadPayeeOrAmount ==
"" ?
"" :
", ") + budgetPayment.
nProposalHash.
ToString();
243 if (retBadHashes ==
"" && retBadPayeeOrAmount ==
"")
return "OK";
245 if (retBadHashes !=
"") retBadHashes =
"Unknown proposal(s) hash! Check this proposal(s) before voting: " + retBadHashes;
246 if (retBadPayeeOrAmount !=
"") retBadPayeeOrAmount =
"Budget payee/nAmount doesn't match our proposal(s)! "+ retBadPayeeOrAmount;
248 return retBadHashes +
" -- " + retBadPayeeOrAmount;
266 std::string strError;
277 if (!finalizedBudget.
UpdateValid(nCurrentHeight)) {
283 std::vector<CBudgetProposal> vBudget =
GetBudget();
284 std::map<uint256, CBudgetProposal> mapWinningProposals;
285 for (
const CBudgetProposal& p: vBudget) { mapWinningProposals.emplace(p.GetHash(), p); }
343 std::string strError;
355 if (!budgetProposal.
UpdateValid(nCurrentHeight, mnCount)) {
374 std::map<uint256, CFinalizedBudget> tmpMapFinalizedBudgets;
375 std::map<uint256, CBudgetProposal> tmpMapProposals;
386 if (!pbudgetProposal->
UpdateValid(nCurrentHeight, mnCount)) {
392 tmpMapProposals.emplace(pbudgetProposal->
GetHash(), *pbudgetProposal);
406 if (!pfinalizedBudget->
UpdateValid(nCurrentHeight)) {
412 tmpMapFinalizedBudgets.emplace(pfinalizedBudget->
GetHash(), *pfinalizedBudget);
433 LogPrintf(
"%s: Removing proposal %s (collateral disconnected, id=%s)\n", __func__, p->
GetName(), feeTxId.
ToString());
437 for (
const auto& vote: p->
GetVotes()) {
438 const uint256& hash{vote.second.GetHash()};
459 LogPrintf(
"%s: Removing finalized budget %s (collateral disconnected, id=%s)\n", __func__, b->
GetName(), feeTxId.
ToString());
480 int highestVoteCount = 0;
485 if (voteCount > highestVoteCount &&
488 pHighestBudget = pfinalizedBudget;
489 highestVoteCount = voteCount;
492 return {pHighestBudget, highestVoteCount};
498 return (highestBudFin.m_budget_fin ? highestBudFin.m_vote_count : -1);
509 return pfb && pfb->
GetPayeeAndAmount(chainHeight, payeeRet, nAmountRet) && highestBudFin.m_vote_count > nCountThreshold;
520 if (nHeight <= 0)
return false;
531 const bool fPayCoinstake = fProofOfStake &&
536 unsigned int i = txCoinstake.
vout.size();
537 txCoinstake.
vout.resize(i + 1);
538 txCoinstake.
vout[i].scriptPubKey = payee;
539 txCoinstake.
vout[i].nValue = nAmount;
541 txCoinbase.
vout.resize(1);
542 txCoinbase.
vout[0].scriptPubKey = payee;
543 txCoinbase.
vout[0].nValue = nAmount;
547 txCoinbase.
vout[0].nValue = blockValue;
548 txCoinbase.
vout.resize(2);
551 txCoinbase.
vout[1].scriptPubKey = payee;
552 txCoinbase.
vout[1].nValue = nAmount;
584 std::vector<CBudgetProposal> vBudget =
GetBudget();
585 if (vBudget.empty()) {
590 std::map<uint256, CBudgetProposal> mapWinningProposals;
592 mapWinningProposals.emplace(p.GetHash(), p);
595 std::vector<uint256> vBudgetHashes;
611 vBudgetHashes.emplace_back(pfb->
GetHash());
616 for (
const uint256& budgetHash: vBudgetHashes) {
618 if (mnKey != nullopt) {
620 if (!vote.
Sign(*mnKey, mnKey->GetPubKey().GetID())) {
621 LogPrintf(
"%s: Failure to sign budget %s\n", __func__, budgetHash.ToString());
626 if (!vote.
Sign(blsKey)) {
627 LogPrintf(
"%s: Failure to sign budget %s with DMN\n", __func__, budgetHash.ToString());
631 std::string strError =
"";
633 LogPrintf(
"%s: Error submitting vote - %s\n", __func__, strError);
653 int64_t nYesCountMax = std::numeric_limits<int64_t>::min();
659 if (proposal.
GetName() == strProposalName && nYesCount > nYesCountMax) {
660 pbudgetProposal = &proposal;
661 nYesCountMax = nYesCount;
665 return pbudgetProposal;
672 return it !=
mapProposals.end() ? &(it->second) :
nullptr;
697 int nFivePercent = nCountEnabled / 20;
699 nCountThreshold = nHighestCount - (nCountEnabled / 10);
701 if (nCountThreshold == nHighestCount) nCountThreshold--;
704 __func__, nHighestCount, nFivePercent);
707 return (nHighestCount > nFivePercent);
718 int nCountThreshold = 0;
725 bool fThreshold =
false;
731 if (highestVotesBudget) {
733 if (highestBudFin.m_vote_count > nCountThreshold) {
753 std::vector<CBudgetProposal*> vBudgetProposalRet;
757 vBudgetProposalRet.push_back(pbudgetProposal);
760 return vBudgetProposalRet;
775 std::vector<CBudgetProposal> vBudgetProposalsRet;
779 int nBlockStart = nHeight - nHeight % nBlocksPerCycle + nBlocksPerCycle;
780 int nBlockEnd = nBlockStart + nBlocksPerCycle - 1;
787 if (pbudgetProposal->IsPassing(nBlockStart, nBlockEnd, mnCount)) {
788 LogPrint(
BCLog::MNBUDGET,
"%s: - Check 1 passed: valid=%d | %ld <= %ld | %ld >= %ld | Yeas=%d Nays=%d Count=%d | established=%d\n",
789 __func__, pbudgetProposal->IsValid(), pbudgetProposal->GetBlockStart(), nBlockStart, pbudgetProposal->GetBlockEnd(),
790 nBlockEnd, pbudgetProposal->GetYeas(), pbudgetProposal->GetNays(), mnCount / 10, pbudgetProposal->IsEstablished());
792 if (pbudgetProposal->GetAmount() + nBudgetAllocated <= nTotalBudget) {
793 pbudgetProposal->SetAllotted(pbudgetProposal->GetAmount());
794 nBudgetAllocated += pbudgetProposal->GetAmount();
795 vBudgetProposalsRet.emplace_back(*pbudgetProposal);
798 pbudgetProposal->SetAllotted(0);
803 LogPrint(
BCLog::MNBUDGET,
"%s: - Check 1 failed: valid=%d | %ld <= %ld | %ld >= %ld | Yeas=%d Nays=%d Count=%d | established=%d\n",
804 __func__, pbudgetProposal->IsValid(), pbudgetProposal->GetBlockStart(), nBlockStart, pbudgetProposal->GetBlockEnd(),
805 nBlockEnd, pbudgetProposal->GetYeas(), pbudgetProposal->GetNays(),
mnodeman.
CountEnabled() / 10,
806 pbudgetProposal->IsEstablished());
811 return vBudgetProposalsRet;
818 std::vector<CFinalizedBudget*> vFinalizedBudgetsRet;
822 vFinalizedBudgetsRet.push_back(&(it.second));
826 return vFinalizedBudgetsRet;
833 std::string ret =
"unknown-budget";
841 if (ret ==
"unknown-budget") {
891 while (it != prop->
mapVotes.end()) {
893 auto dmn = mnList.GetMNByCollateral(it->first);
895 (*it).second.SetValid(!dmn->IsPoSeBanned());
899 (*it).second.SetValid(pmn && pmn->
IsEnabled());
915 while (it != fbud->
mapVotes.end()) {
917 auto dmn = mnList.GetMNByCollateral(it->first);
919 (*it).second.SetValid(!dmn->IsPoSeBanned());
923 (*it).second.SetValid(pmn && pmn->
IsEnabled());
981 if (nCurrentHeight % 14 != 0)
return;
994 manager->
Sync(pnode,
true);
1018 const auto cleanOrphans = [now](
auto& mutex,
auto& mapOrphans,
auto& mapSeen) {
1020 for (
auto it = mapOrphans.begin() ; it != mapOrphans.end();) {
1021 int64_t lastReceivedVoteTime = it->second.second;
1024 for (
const auto& voteIt : it->second.first) {
1025 mapSeen.erase(voteIt.GetHash());
1028 it = mapOrphans.erase(it);
1100 err =
strprintf(
"new vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n",
1102 return state.
Invalid(
false, REJECT_INVALID,
"bad-mvote", err);
1109 auto dmn = mnList.GetMNByCollateral(voteVin.
prevout);
1111 const std::string& mn_protx_id = dmn->proTxHash.ToString();
1113 if (dmn->IsPoSeBanned()) {
1114 err =
strprintf(
"masternode (%s) not valid or PoSe banned", mn_protx_id);
1115 return state.
DoS(0,
false, REJECT_INVALID,
"bad-mvote",
false, err);
1121 err =
strprintf(
"invalid mvote sig from dmn: %s", mn_protx_id);
1122 return state.
DoS(100,
false, REJECT_INVALID,
"bad-mvote-sig",
false, err);
1126 return state.
DoS(0,
false, REJECT_INVALID,
"bad-mvote",
false,
strprintf(
"%s (%s)", err, mn_protx_id));
1145 return state.
DoS(0,
false, REJECT_INVALID,
"bad-mvote",
false, err);
1149 return state.
DoS(0,
false, REJECT_INVALID,
"bad-mvote",
false,
"masternode not valid");
1157 return state.
DoS(20,
false, REJECT_INVALID,
"bad-mvote-sig",
false, err);
1163 return state.
DoS(0,
false, REJECT_INVALID,
"bad-mvote",
false, err);
1209 err =
strprintf(
"new vote is too far ahead of current time - %s - nTime %lli - Max Time %lli\n",
1211 return state.
Invalid(
false, REJECT_INVALID,
"bad-fbvote", err);
1218 auto dmn = mnList.GetMNByCollateral(voteVin.
prevout);
1220 const std::string& mn_protx_id = dmn->proTxHash.ToString();
1222 if (dmn->IsPoSeBanned()) {
1223 err =
strprintf(
"masternode (%s) not valid or PoSe banned", mn_protx_id);
1224 return state.
DoS(0,
false, REJECT_INVALID,
"bad-fbvote",
false, err);
1229 if (!vote.
CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) {
1230 err =
strprintf(
"invalid fbvote sig from dmn: %s", mn_protx_id);
1231 return state.
DoS(100,
false, REJECT_INVALID,
"bad-fbvote-sig",
false, err);
1235 return state.
DoS(0,
false, REJECT_INVALID,
"bad-fbvote",
false,
strprintf(
"%s (%s)", err, mn_protx_id));
1253 return state.
DoS(0,
false, REJECT_INVALID,
"bad-fbvote",
false, err);
1257 return state.
DoS(0,
false, REJECT_INVALID,
"bad-fbvote",
false,
"masternode not valid");
1265 return state.
DoS(20,
false, REJECT_INVALID,
"bad-fbvote-sig",
false, err);
1271 return state.
DoS(0,
false, REJECT_INVALID,
"bad-fbvote",
false, err);
1286 return banScore == 0;
1382 if (pbudgetProposal && pbudgetProposal->
IsValid()) {
1392 if (pfinalizedBudget && pfinalizedBudget->
IsValid()) {
1400 template<
typename T>
1401 static bool relayItemIfFound(
const uint256& itemHash,
CNode* pfrom,
RecursiveMutex& cs, std::map<uint256, T>& map,
const char* type)
1405 const auto& it = map.find(itemHash);
1406 if (it == map.end())
return false;
1407 T* item = &(it->second);
1408 if (!item->IsValid())
return true;
1409 g_connman->PushMessage(pfrom, msgMaker.Make(type, item->GetBroadcast()));
1411 item->SyncVotes(pfrom,
false , nInvCount);
1416 template<
typename T>
1417 static void relayInventoryItems(
CNode* pfrom,
RecursiveMutex& cs, std::map<uint256, T>& map,
bool fPartial,
GetDataMsg invType,
const int mn_sync_budget_type)
1423 for (
auto& it: map) {
1424 T* item = &(it.second);
1425 if (item && item->IsValid()) {
1428 item->SyncVotes(pfrom, fPartial, nInvCount);
1438 if (nProp.
IsNull())
return;
1464 template<
typename T>
1465 static void TryAppendOrphanVoteMap(
const T& vote,
1467 std::map<
uint256, std::pair<std::vector<T>, int64_t>>& mapOrphan,
1468 std::map<uint256, T>& mapSeen)
1472 mapSeen.erase(vote.GetHash());
1475 const auto& it = mapOrphan.find(parentHash);
1476 if (it != mapOrphan.end()) {
1480 mapSeen.erase(vote.GetHash());
1482 it->second.first.emplace_back(vote);
1483 it->second.second =
GetTime();
1486 mapOrphan.emplace(parentHash, std::make_pair<std::vector<T>, int64_t>({vote},
GetTime()));
1496 const auto& itProposal =
mapProposals.find(nProposalHash);
1515 strError =
"Proposal not found!";
1520 return itProposal->second.AddOrUpdateVote(vote, strError);
1546 strError =
"Finalized Budget " + nBudgetHash.
ToString() +
" not found!";
1558 unsigned int nSeenVotes = 0, nOrphanVotes = 0;
1565 unsigned int nSeenFinalizedVotes = 0, nOrphanFinalizedVotes = 0;
1572 return strprintf(
"Proposals: %d - Finalized Budgets: %d - "
1573 "Proposal Votes: %d (orphan: %d) - "
1574 "Finalized Budget Votes: %d (orphan: %d)",
1575 nProposals, nBudgets,
1576 nSeenVotes, nOrphanVotes, nSeenFinalizedVotes, nOrphanFinalizedVotes);
1586 const int nConf = nCurrentHeight - nProposalHeight + 1;
1588 if (nConf < nRequiredConfs) {
1589 strError =
strprintf(
"Collateral requires at least %d confirmations - %d confirmations (current height: %d, fee tx height: %d)",
1590 nRequiredConfs, nConf, nCurrentHeight, nProposalHeight);
1597 bool CheckCollateral(
const uint256& nTxCollateralHash,
const uint256& nExpectedHash, std::string& strError, int64_t& nTime,
int nCurrentHeight,
bool fBudgetFinalization)
1601 if (!
GetTransaction(nTxCollateralHash, txCollateral, nBlockHash,
true)) {
1602 strError =
strprintf(
"Can't find collateral tx %s", nTxCollateralHash.
ToString());
1606 if (txCollateral->vout.size() < 1)
return false;
1607 if (txCollateral->nLockTime != 0)
return false;
1612 bool foundOpReturn =
false;
1613 for (
const CTxOut &o : txCollateral->vout) {
1615 strError =
strprintf(
"Invalid Script %s", txCollateral->ToString());
1618 if (fBudgetFinalization) {
1625 if(o.
nValue >= BUDGET_FEE_TX) {
1626 foundOpReturn =
true;
1635 if(o.
nValue >= PROPOSAL_FEE_TX) {
1636 foundOpReturn =
true;
1643 if (!foundOpReturn) {
1644 strError =
strprintf(
"Couldn't find opReturn %s in %s", nExpectedHash.
ToString(), txCollateral->ToString());
1650 if (nBlockHash.
IsNull()) {
1651 strError =
strprintf(
"Collateral transaction %s is unconfirmed", nTxCollateralHash.
ToString());
1655 int nProposalHeight = 0;
1660 nProposalHeight = pindex->
nHeight;
1661 nTime = pindex->
nTime;
1665 if (!nProposalHeight) {
1666 strError =
strprintf(
"Collateral transaction %s not in Active chain", nTxCollateralHash.
ToString());
bool GetActiveMasternodeKeys(CTxIn &vin, Optional< CKey > &key, CBLSSecretKey &blsKey)
int64_t CAmount
Amount in PIV (Can be negative)
CBudgetManager g_budgetman
#define BUDGET_ORPHAN_VOTES_CLEANUP_SECONDS
bool CheckCollateralConfs(const uint256 &nTxCollateralHash, int nCurrentHeight, int nProposalHeight, std::string &strError)
bool CheckCollateral(const uint256 &nTxCollateralHash, const uint256 &nExpectedHash, std::string &strError, int64_t &nTime, int nCurrentHeight, bool fBudgetFinalization)
#define ORPHAN_VOTES_CACHE_LIMIT
const CChainParams & Params()
Return the currently selected parameters.
void reserve(size_type n)
The block chain is a tree shaped structure starting with the genesis block at the root,...
int nHeight
height of the entry in the chain. The genesis block has height 0
int GetBestHeight() const
bool AddProposal(CBudgetProposal &budgetProposal)
int GetHighestVoteCount(int chainHeight) const
std::map< uint256, BudVotesAndLastVoteReceivedTime > mapOrphanFinalizedBudgetVotes
std::string strBudgetMode
bool ProcessProposalVote(CBudgetVote &proposal, CNode *pfrom, CValidationState &state)
bool HaveSeenProposalVote(const uint256 &voteHash) const
bool HaveProposal(const uint256 &propHash) const
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
CDataStream GetProposalVoteSerialized(const uint256 &voteHash) const
static CAmount GetTotalBudget(int nHeight)
std::map< uint256, uint256 > mapUnconfirmedFeeTx
std::map< uint256, uint256 > mapFeeTxToBudget
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)
bool GetFinalizedBudget(const uint256 &nHash, CFinalizedBudget &fb) const
bool ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, int &banScore)
bool HaveFinalizedBudget(const uint256 &budgetHash) const
std::string ToString() const
std::map< uint256, CFinalizedBudget > mapFinalizedBudgets
std::map< uint256, CBudgetVote > mapSeenProposalVotes
CBudgetProposal * FindProposal(const uint256 &nHash)
RecursiveMutex cs_budgets
std::map< uint256, CBudgetProposal > mapProposals
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
CDataStream GetProposalSerialized(const uint256 &propHash) const
uint256 SubmitFinalBudget()
std::map< uint256, PropVotesAndLastVoteReceivedTime > mapOrphanProposalVotes
CDataStream GetFinalizedBudgetSerialized(const uint256 &budgetHash) const
std::map< uint256, uint256 > mapFeeTxToProposal
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.
bool HaveSeenFinalizedBudgetVote(const uint256 &voteHash) const
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)
bool IsBudgetPaymentBlock(int nBlockHeight) const
std::string GetFinalizedBudgetStatus(const uint256 &nHash) const
std::map< uint256, CFinalizedBudgetVote > mapSeenFinalizedBudgetVotes
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)
std::map< COutPoint, CBudgetVote > mapVotes
int GetBlockStart() const
std::map< COutPoint, CBudgetVote > GetVotes() const
std::string GetName() const
const uint256 & GetFeeTXHash() const
bool ParseBroadcast(CDataStream &broadcast)
void SetSynced(bool synced)
void SetStrInvalid(const std::string &_strInvalid)
bool AddOrUpdateVote(const CBudgetVote &vote, std::string &strError)
static bool PtrHigherYes(CBudgetProposal *a, CBudgetProposal *b)
CAmount GetAmount() const
bool UpdateValid(int nHeight, int mnCount)
bool IsWellFormed(const CAmount &nTotalBudget)
std::string IsInvalidLogStr() const
uint256 GetProposalHash() const
void SetValid(bool _fValid)
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
const Consensus::Params & GetConsensus() const
bool GetPayeeAndAmount(int64_t nBlockHeight, CScript &payee, CAmount &nAmount) const
std::string IsInvalidLogStr() const
void SetAutoChecked(bool _fAutoChecked)
static bool PtrGreater(CFinalizedBudget *a, CFinalizedBudget *b)
std::string GetProposalsStr() const
bool GetBudgetPaymentByBlock(int64_t nBlockHeight, CTxBudgetPayment &payment) const
bool UpdateValid(int nHeight)
std::string GetName() const
void SetProposalsStr(const std::string _strProposals)
void SetSynced(bool synced)
const uint256 & GetFeeTXHash() const
bool AddOrUpdateVote(const CFinalizedBudgetVote &vote, std::string &strError)
TrxValidationStatus IsTransactionValid(const CTransaction &txNew, const uint256 &nBlockHash, int nBlockHeight) const
bool ParseBroadcast(CDataStream &broadcast)
bool CheckProposals(const std::map< uint256, CBudgetProposal > &mapWinningProposals) const
std::map< COutPoint, CFinalizedBudgetVote > mapVotes
void SetStrInvalid(const std::string &_strInvalid)
bool IsWellFormed(const CAmount &nTotalBudget)
bool IsAutoChecked() const
std::vector< uint256 > GetVotesHashes() const
std::vector< uint256 > GetProposalsHashes() const
int GetBlockStart() const
uint256 GetBudgetHash() const
void SetValid(bool _fValid)
int CountEnabled(bool only_legacy=false) const
void AskForMN(CNode *pnode, const CTxIn &vin)
Ask (source) node for mnb.
CMasternode * Find(const COutPoint &collateralOut)
Find an entry.
void AddFulfilledRequest(const CService &addr, const std::string &strRequest)
void AddItemRequest(const CService &addr, const uint256 &itemHash)
bool HasFulfilledRequest(const CService &addr, const std::string &strRequest) const
bool HasItemRequest(const CService &addr, const uint256 &itemHash) const
CSerializedNetMsg Make(int nFlags, std::string sCommand, Args &&... args)
Information about a peer.
std::atomic< int > nVersion
int GetSendVersion() const
void PushInventory(const CInv &inv)
std::string ToString() const
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
A key allocated from the key pool.
Serialized script, used inside transaction inputs and outputs.
bool IsUnspendable() const
Returns whether the script is guaranteed to fail at execution, regardless of the initial stack.
bool IsPayToPublicKeyHash() const
bool Sign(const CKey &key, const CKeyID &keyID)
CSignedMessage Class Functions inherited by network signed-messages.
bool CheckSignature(const CKeyID &keyID) const
The basic transaction that is broadcasted on the network and contained in blocks.
An input of a transaction.
An output of a transaction.
Capture information about block/transaction validation.
bool Invalid(bool ret=false, unsigned int _chRejectCode=0, const std::string &_strRejectReason="", const std::string &_strDebugMessage="")
bool DoS(int level, bool ret=false, unsigned int chRejectCodeIn=0, std::string strRejectReasonIn="", bool corruptionIn=false, const std::string &strDebugMessageIn="")
bool IsBlockchainSynced() const
bool IsMasternodeListSynced() const
void AddedBudgetItem(const uint256 &hash)
std::string ToString() const
std::unique_ptr< CDeterministicMNManager > deterministicMNManager
@ Valid
Transaction verification failed.
@ VoteThreshold
Transaction successfully verified, but includes a double-budget-payment.
#define T(expected, seed, data)
std::unique_ptr< CConnman > g_connman
#define LogPrint(category,...)
CMasternodeMan mnodeman
Masternode manager.
const char * BUDGETVOTESYNC
The budgetvotesync message is used to request budget vote data from connected peers.
const char * FINALBUDGETVOTE
The finalbudgetvote message is used to broadcast or relay finalized budget votes to connected peers.
const char * FINALBUDGET
The finalbudget message is used to broadcast or relay finalized budget metadata to connected peers.
const char * BUDGETVOTE
The budgetvote message is used to broadcast or relay budget proposal votes to connected peers.
const char * SYNCSTATUSCOUNT
The syncstatuscount message is used to track the layer 2 syncing process.
const char * BUDGETPROPOSAL
The budgetproposal message is used to broadcast or relay budget proposal metadata to connected peers.
std::string EncodeDestination(const CWDestination &address, const CChainParams::Base58Type addrType)
RecursiveMutex cs_main
Global state.
CNetFulfilledRequestManager g_netfulfilledman(DEFAULT_ITEMS_FILTER_SIZE)
boost::optional< T > Optional
Substitute for C++17 std::optional.
GetDataMsg
getdata message types
@ MSG_BUDGET_FINALIZED_VOTE
int GetRandInt(int nMax) noexcept
std::vector< unsigned char > ToByteVector(const T &in)
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet, bool fColdStake)
Parse a standard scriptPubKey for the destination address.
boost::variant< CNoDestination, CKeyID, CScriptID, CExchangeKeyID > CTxDestination
A txout script template with a specific destination.
A mutable version of CTransaction.
std::vector< CTxOut > vout
CWallet::CommitStatus status
int nBudgetFeeConfirmations
bool NetworkUpgradeActive(int nHeight, Consensus::UpgradeIndex idx) const
Returns true if the given network upgrade is active as of the given block height.
#define AssertLockNotHeld(cs)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define AssertLockHeld(cs)
std::atomic< bool > fMasterNode
TierTwoSyncState g_tiertwo_sync_state
#define MASTERNODE_SYNC_BUDGET_PROP
#define MASTERNODE_SYNC_BUDGET
#define MASTERNODE_SYNC_BUDGET_FIN
std::shared_ptr< const CTransaction > CTransactionRef
const uint256 UINT256_ZERO
constant uint256 instances
std::string FormatStateMessage(const CValidationState &state)
Convert CValidationState to a human-readable message for logging.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
int ActiveProtocol()
See whether the protocol update is enforced for connected nodes.
bool GetTransaction(const uint256 &hash, CTransactionRef &txOut, uint256 &hashBlock, bool fAllowSlow, CBlockIndex *blockIndex)
Return transaction in tx, and if it was found inside a block, its hash is placed in hashBlock.
CAmount GetBlockValue(int nHeight)
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
std::vector< CWalletRef > vpwallets