15 #include <boost/lexical_cast.hpp> 39 bool isBlockRewardValueMet = (block.
vtx[0].GetValueOut() <= blockReward);
40 if(
fDebug)
LogPrintf(
"block.vtx[0].GetValueOut() %lld <= blockReward %lld\n", block.
vtx[0].GetValueOut(), blockReward);
47 if(nBlockHeight < consensusParams.nSuperblockStartBlock) {
49 if(nBlockHeight >= consensusParams.nBudgetPaymentsStartBlock &&
50 nOffset < consensusParams.nBudgetPaymentsWindowBlocks) {
54 LogPrint(
"gobject",
"IsBlockValueValid -- Client synced but budget spork is disabled, checking block value against block reward\n");
55 if(!isBlockRewardValueMet) {
56 strErrorRet =
strprintf(
"coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, budgets are disabled",
57 nBlockHeight, block.
vtx[0].GetValueOut(), blockReward);
59 return isBlockRewardValueMet;
61 LogPrint(
"gobject",
"IsBlockValueValid -- WARNING: Skipping budget block value checks, accepting block\n");
66 if(!isBlockRewardValueMet) {
67 strErrorRet =
strprintf(
"coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, block is not in budget cycle window",
68 nBlockHeight, block.
vtx[0].GetValueOut(), blockReward);
70 return isBlockRewardValueMet;
76 bool isSuperblockMaxValueMet = (block.
vtx[0].GetValueOut() <= nSuperblockMaxValue);
78 LogPrint(
"gobject",
"block.vtx[0].GetValueOut() %lld <= nSuperblockMaxValue %lld\n", block.
vtx[0].GetValueOut(), nSuperblockMaxValue);
83 if(
fDebug)
LogPrintf(
"IsBlockPayeeValid -- WARNING: Client not synced, checking superblock max bounds only\n");
84 if(!isSuperblockMaxValueMet) {
85 strErrorRet =
strprintf(
"coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded superblock max value",
86 nBlockHeight, block.
vtx[0].GetValueOut(), nSuperblockMaxValue);
88 return isSuperblockMaxValueMet;
90 if(!isBlockRewardValueMet) {
91 strErrorRet =
strprintf(
"coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, only regular blocks are allowed at this height",
92 nBlockHeight, block.
vtx[0].GetValueOut(), blockReward);
95 return isBlockRewardValueMet;
103 LogPrint(
"gobject",
"IsBlockValueValid -- Valid superblock at height %d: %s", nBlockHeight, block.
vtx[0].ToString());
109 LogPrintf(
"IsBlockValueValid -- ERROR: Invalid superblock detected at height %d: %s", nBlockHeight, block.
vtx[0].ToString());
111 strErrorRet =
strprintf(
"invalid superblock detected at height %d", nBlockHeight);
114 LogPrint(
"gobject",
"IsBlockValueValid -- No triggered superblock detected at height %d\n", nBlockHeight);
115 if(!isBlockRewardValueMet) {
116 strErrorRet =
strprintf(
"coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, no triggered superblock detected",
117 nBlockHeight, block.
vtx[0].GetValueOut(), blockReward);
121 LogPrint(
"gobject",
"IsBlockValueValid -- Superblocks are disabled, no superblocks allowed\n");
122 if(!isBlockRewardValueMet) {
123 strErrorRet =
strprintf(
"coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, superblocks are disabled",
124 nBlockHeight, block.
vtx[0].GetValueOut(), blockReward);
129 return isBlockRewardValueMet;
136 if(
fDebug)
LogPrintf(
"IsBlockPayeeValid -- WARNING: Client not synced, skipping block payee checks\n");
147 LogPrint(
"mnpayments",
"IsBlockPayeeValid -- Valid masternode payment at height %d: %s", nBlockHeight, txNew.
ToString());
156 LogPrint(
"gobject",
"IsBlockPayeeValid -- ERROR: Client synced but budget spork is disabled and masternode payment is invalid\n");
160 LogPrint(
"gobject",
"IsBlockPayeeValid -- WARNING: Probably valid budget block, have no data, accepting\n");
166 LogPrintf(
"IsBlockPayeeValid -- ERROR: Invalid masternode payment detected at height %d: %s", nBlockHeight, txNew.
ToString());
170 LogPrintf(
"IsBlockPayeeValid -- WARNING: Masternode payment enforcement is disabled, accepting any payee\n");
180 LogPrint(
"gobject",
"IsBlockPayeeValid -- Valid superblock at height %d: %s", nBlockHeight, txNew.
ToString());
184 LogPrintf(
"IsBlockPayeeValid -- ERROR: Invalid superblock detected at height %d: %s", nBlockHeight, txNew.
ToString());
189 LogPrint(
"gobject",
"IsBlockPayeeValid -- No triggered superblock detected at height %d\n", nBlockHeight);
192 LogPrint(
"gobject",
"IsBlockPayeeValid -- Superblocks are disabled, no superblocks allowed\n");
197 LogPrint(
"mnpayments",
"IsBlockPayeeValid -- Valid masternode payment at height %d: %s", nBlockHeight, txNew.
ToString());
202 LogPrintf(
"IsBlockPayeeValid -- ERROR: Invalid masternode payment detected at height %d: %s", nBlockHeight, txNew.
ToString());
206 LogPrintf(
"IsBlockPayeeValid -- WARNING: Masternode payment enforcement is disabled, accepting any payee\n");
216 LogPrint(
"gobject",
"FillBlockPayments -- triggered superblock creation at height %d\n", nBlockHeight);
223 LogPrint(
"mnpayments",
"FillBlockPayments -- nBlockHeight %d blockReward %lld txoutMasternodeRet %s txNew %s",
224 nBlockHeight, blockReward, txoutMasternodeRet.
ToString(), txNew.
ToString());
267 txoutMasternodeRet =
CTxOut();
277 LogPrintf(
"CMasternodePayments::FillBlockPayee -- Failed to detect masternode to pay\n");
288 txNew.
vout[0].nValue -= masternodePayment;
290 txoutMasternodeRet =
CTxOut(masternodePayment, payee);
291 txNew.
vout.push_back(txoutMasternodeRet);
297 LogPrintf(
"CMasternodePayments::FillBlockPayee -- Masternode payment %lld to %s\n", masternodePayment, address2.
ToString());
321 vRecv >> nCountNeeded;
325 LogPrintf(
"MASTERNODEPAYMENTSYNC -- peer already asked me for the list, peer=%d\n", pfrom->
id);
331 Sync(pfrom, connman);
332 LogPrintf(
"MASTERNODEPAYMENTSYNC -- Sent Masternode payment votes to peer %d\n", pfrom->
id);
361 LogPrint(
"mnpayments",
"MASTERNODEPAYMENTVOTE -- vote out of range: nFirstBlock=%d, nBlockHeight=%d, nHeight=%d\n", nFirstBlock, vote.nBlockHeight,
nCachedBlockHeight);
365 std::string strError =
"";
367 LogPrint(
"mnpayments",
"MASTERNODEPAYMENTVOTE -- invalid message, error: %s\n", strError);
371 if(!
CanVote(vote.vinMasternode.prevout, vote.nBlockHeight)) {
372 LogPrintf(
"MASTERNODEPAYMENTVOTE -- masternode already voted, masternode=%s\n", vote.vinMasternode.prevout.ToStringShort());
379 LogPrintf(
"MASTERNODEPAYMENTVOTE -- masternode is missing %s\n", vote.vinMasternode.prevout.ToStringShort());
387 LogPrintf(
"MASTERNODEPAYMENTVOTE -- ERROR: invalid signature\n");
391 LogPrint(
"mnpayments",
"MASTERNODEPAYMENTVOTE -- WARNING: invalid signature\n");
406 LogPrint(
"mnpayments",
"MASTERNODEPAYMENTVOTE -- vote: address=%s, nBlockHeight=%d, nHeight=%d, prevout=%s, hash=%s new\n",
418 std::string strError;
424 LogPrintf(
"CMasternodePaymentVote::Sign -- SignMessage() failed\n");
429 LogPrintf(
"CMasternodePaymentVote::Sign -- VerifyMessage() failed, error: %s\n", strError);
458 if(h == nNotBlockHeight)
continue;
514 LogPrint(
"mnpayments",
"CMasternodeBlockPayees::GetBestPayee -- ERROR: couldn't find any payee\n");
526 return (nVotes > -1);
539 LogPrint(
"mnpayments",
"CMasternodeBlockPayees::HasPayeeWithVotes -- ERROR: couldn't find any payee with %d+ votes\n", nVotesReq);
547 int nMaxSignatures = 0;
548 std::string strPayeesPossible =
"";
567 LogPrint(
"mnpayments",
"CMasternodeBlockPayees::IsTransactionValid -- Found required payment\n");
576 if(strPayeesPossible ==
"") {
577 strPayeesPossible = address2.ToString();
579 strPayeesPossible +=
"," + address2.ToString();
584 LogPrintf(
"CMasternodeBlockPayees::IsTransactionValid -- ERROR: Missing required payment, possible payees: '%s', amount: %f DASH\n", strPayeesPossible, (
float)nMasternodePayment/
COIN);
592 std::string strRequiredPayments =
"Unknown";
600 if (strRequiredPayments !=
"Unknown") {
601 strRequiredPayments +=
", " + address2.ToString() +
":" + boost::lexical_cast<std::string>(payee.
GetVoteCount());
603 strRequiredPayments = address2.ToString() +
":" + boost::lexical_cast<std::string>(payee.
GetVoteCount());
607 return strRequiredPayments;
645 LogPrint(
"mnpayments",
"CMasternodePayments::CheckAndRemove -- Removing old Masternode payment: nBlockHeight=%d\n", vote.
nBlockHeight);
669 int nMinRequiredProtocol;
679 strError =
strprintf(
"Masternode protocol is too old: nProtocolVersion=%d, nMinRequiredProtocol=%d", mnInfo.
nProtocolVersion, nMinRequiredProtocol);
690 LogPrint(
"mnpayments",
"CMasternodePaymentVote::IsValid -- Can't calculate rank for masternode %s\n",
702 LogPrintf(
"CMasternodePaymentVote::IsValid -- Error: %s\n", strError);
729 LogPrint(
"mnpayments",
"CMasternodePayments::ProcessBlock -- Unknown Masternode\n");
748 LogPrintf(
"CMasternodePayments::ProcessBlock -- ERROR: Failed to find masternode to pay\n");
763 LogPrintf(
"CMasternodePayments::ProcessBlock -- vote: payee=%s, nBlockHeight=%d\n", address2.
ToString(), nBlockHeight);
767 LogPrintf(
"CMasternodePayments::ProcessBlock -- Signing vote\n");
768 if (voteNew.Sign()) {
769 LogPrintf(
"CMasternodePayments::ProcessBlock -- AddPaymentVote()\n");
772 voteNew.Relay(connman);
784 std::string debugStr;
786 debugStr +=
strprintf(
"CMasternodePayments::CheckPreviousBlockVotes -- nPrevBlockHeight=%d, expected voting MNs:\n", nPrevBlockHeight);
790 debugStr +=
"CMasternodePayments::CheckPreviousBlockVotes -- GetMasternodeRanks failed\n";
791 LogPrint(
"mnpayments",
"%s", debugStr);
804 for (
auto &voteHash :
p.GetVoteHashes()) {
806 debugStr +=
strprintf(
"CMasternodePayments::CheckPreviousBlockVotes -- could not find vote %s\n",
807 voteHash.ToString());
811 if (vote.vinMasternode.prevout == mn.second.vin.prevout) {
821 debugStr +=
strprintf(
"CMasternodePayments::CheckPreviousBlockVotes -- %s - no vote received\n",
822 mn.second.vin.prevout.ToStringShort());
831 debugStr +=
strprintf(
"CMasternodePayments::CheckPreviousBlockVotes -- %s - voted for %s\n",
832 mn.second.vin.prevout.ToStringShort(), address2.
ToString());
834 debugStr +=
"CMasternodePayments::CheckPreviousBlockVotes -- Masternodes which missed a vote in the past:\n";
836 debugStr +=
strprintf(
"CMasternodePayments::CheckPreviousBlockVotes -- %s: %d\n", it.first.ToStringShort(), it.second);
839 LogPrint(
"mnpayments",
"%s", debugStr);
860 std::string strError =
"";
876 std::ostringstream info;
881 ", " << (int)
vchSig.size();
899 BOOST_FOREACH(
uint256& hash, vecVoteHashes) {
908 LogPrintf(
"CMasternodePayments::Sync -- Sent %d votes to peer %d\n", nInvCount, pnode->
id);
919 std::vector<CInv> vToFetch;
930 LogPrintf(
"CMasternodePayments::SyncLowDataPaymentBlocks -- asking peer %d for %d blocks\n", pnode->
id,
MAX_INV_SZ);
936 if(!pindex->
pprev)
break;
937 pindex = pindex->
pprev;
963 CTxDestination address1;
964 ExtractDestination(payee.GetPayee(), address1);
965 CBitcoinAddress address2(address1);
966 printf(
"payee %s votes %d\n", address2.ToString().c_str(), payee.GetVoteCount());
968 printf(
"block %d votes total %d\n", it->first, nTotalVotes);
978 LogPrintf(
"CMasternodePayments::SyncLowDataPaymentBlocks -- asking peer %d for %d payment blocks\n", pnode->
id,
MAX_INV_SZ);
986 if(!vToFetch.empty()) {
987 LogPrintf(
"CMasternodePayments::SyncLowDataPaymentBlocks -- asking peer %d for %d payment blocks\n", pnode->
id, vToFetch.size());
994 std::ostringstream info;
bool AddPaymentVote(const CMasternodePaymentVote &vote)
bool GetBlockHash(uint256 &hashRet, int nBlockHeight)
static const int SPORK_10_MASTERNODE_PAY_UPDATED_NODES
void FillBlockPayee(CMutableTransaction &txNew, int nBlockHeight, CAmount blockReward, CTxOut &txoutMasternodeRet)
CCriticalSection cs_vecPayees
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
CMasternodeSync masternodeSync
std::set< uint256 > setAskFor
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
int nSuperblockStartBlock
CAmount GetMasternodePayment(int nHeight, CAmount blockValue)
static std::string GetRequiredPaymentsString(int nBlockHeight)
std::string ToString() const
CActiveMasternode activeMasternode
const char * MASTERNODEPAYMENTVOTE
void AddFulfilledRequest(CAddress addr, std::string strRequest)
uint64_t GetHash(const uint256 &salt) const
const Consensus::Params & GetConsensus() const
bool GetBestPayee(CScript &payeeRet)
static const CAmount COIN
std::string ToString() const
bool CheckSignature(const CPubKey &pubKeyMasternode, int nValidationHeight, int &nDos)
bool IsBlockPayeeValid(const CTransaction &txNew, int nBlockHeight, CAmount blockReward)
CCriticalSection cs_mapMasternodePaymentVotes
int nBudgetPaymentsWindowBlocks
static const int SPORK_9_SUPERBLOCKS_ENABLED
static bool IsSuperblockTriggered(int nBlockHeight)
std::string ToString() const
bool GetMasternodeRanks(rank_pair_vec_t &vecMasternodeRanksRet, int nBlockHeight=-1, int nMinProtocol=0)
const char * SYNCSTATUSCOUNT
void ProcessMessage(CNode *pfrom, std::string &strCommand, CDataStream &vRecv, CConnman &connman)
void RelayInv(CInv &inv, const int minProtoVersion=MIN_PEER_PROTO_VERSION)
const int nMinBlocksToStore
static const int MNPAYMENTS_SIGNATURES_REQUIRED
void AskForMN(CNode *pnode, const COutPoint &outpoint, CConnman &connman)
Ask (source) node for mnb.
CAmount GetValueOut() const
bool IsWinnersListSynced()
void RequestLowDataPaymentBlocks(CNode *pnode, CConnman &connman)
CCriticalSection cs_mapMasternodeBlocks
bool IsValid(CNode *pnode, int nValidationHeight, std::string &strError, CConnman &connman)
bool HasFulfilledRequest(CAddress addr, std::string strRequest)
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
void CheckPreviousBlockVotes(int nPrevBlockHeight)
void AddVoteHash(uint256 hashIn)
void UpdatedBlockTip(const CBlockIndex *pindex, CConnman &connman)
static const int MASTERNODE_SYNC_MNW
std::vector< CTransaction > vtx
std::string ToString() const
static bool IsValid(const CTransaction &txNew, int nBlockHeight, CAmount blockReward)
std::atomic< bool > fDIP0001WasLockedIn
void Misbehaving(NodeId pnode, int howmuch)
static const int MNPAYMENTS_SIGNATURES_TOTAL
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
std::vector< CMasternodePayee > vecPayees
std::map< COutPoint, int > mapMasternodesLastVote
CMasternodePayments mnpayments
std::string GetRequiredPaymentsString(int nBlockHeight)
static int LogPrint(const char *category, const char *format)
static const int SPORK_13_OLD_SUPERBLOCK_FLAG
bool GetMasternodeInfo(const COutPoint &outpoint, masternode_info_t &mnInfoRet)
std::vector< uint256 > GetVoteHashes()
static const int SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT
static bool error(const char *format)
bool GetNextMasternodeInQueueForPayment(int nBlockHeight, bool fFilterSigTime, int &nCountRet, masternode_info_t &mnInfoRet)
Find an entry in the masternode list that is next to be paid.
bool IsScheduled(CMasternode &mn, int nNotBlockHeight)
void PushInventory(const CInv &inv)
bool IsTransactionValid(const CTransaction &txNew)
std::vector< rank_pair_t > rank_pair_vec_t
static bool VerifyMessage(const CPubKey pubkey, const std::vector< unsigned char > &vchSig, const std::string strMessage, std::string &strErrorRet)
Verify the message signature, returns true if succcessful.
bool IsTransactionValid(const CTransaction &txNew, int nBlockHeight)
std::string ToString() const
CScript GetScriptForDestination(const CTxDestination &dest)
static CAmount GetPaymentsLimit(int nBlockHeight)
int size()
Return the number of (unique) Masternodes.
std::string GetRequiredPaymentsString(int nBlockHeight)
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_1
minimum peer version that can receive and send masternode payment messages,
std::vector< CTxOut > vout
static const int MIN_MASTERNODE_PAYMENT_PROTO_VERSION_2
CSporkManager sporkManager
const float nStorageCoeff
bool IsBlockValueValid(const CBlock &block, int nBlockHeight, CAmount blockReward, std::string &strErrorRet)
TODO: all 4 functions do not belong here really, they should be refactored/moved somewhere (main...
int nBudgetPaymentsCycleBlocks
std::vector< unsigned char > vchSig
CPubKey pubKeyCollateralAddress
bool HasPayeeWithVotes(const CScript &payeeIn, int nVotesReq)
bool ProcessBlock(int nBlockHeight, CConnman &connman)
const CChainParams & Params()
std::string GetRequiredPaymentsString()
std::string ToString() const
bool IsBlockchainSynced()
std::string ToString() const
uint256 GetBlockHash() const
CNetFulfilledRequestManager netfulfilledman
const std::vector< CTxOut > vout
CBlockIndex * Tip() const
bool GetMasternodeRank(const COutPoint &outpoint, int &nRankRet, int nBlockHeight=-1, int nMinProtocol=0)
static bool SignMessage(const std::string strMessage, std::vector< unsigned char > &vchSigRet, const CKey key)
Sign the message, returns true if successful.
CBlockIndex * pprev
pointer to the index of the predecessor of this block
bool IsSporkActive(int nSporkID)
std::map< COutPoint, int > mapMasternodesDidNotVote
const char * MASTERNODEPAYMENTSYNC
void BumpAssetLastTime(std::string strFuncName)
int GetMinMasternodePaymentsProto()
void Sync(CNode *node, CConnman &connman)
std::map< uint256, CMasternodePaymentVote > mapMasternodePaymentVotes
void Relay(CConnman &connman)
int nHeight
height of the entry in the chain. The genesis block has height 0
std::string ToStringShort() const
static const unsigned int MAX_INV_SZ
static bool IsValidBlockHeight(int nBlockHeight)
int nBudgetPaymentsStartBlock
bool IsMasternodeListSynced()
bool CanVote(COutPoint outMasternode, int nBlockHeight)
void FillBlockPayments(CMutableTransaction &txNew, int nBlockHeight, CAmount blockReward, CTxOut &txoutMasternodeRet, std::vector< CTxOut > &voutSuperblockRet)
static void CreateSuperblock(CMutableTransaction &txNewRet, int nBlockHeight, std::vector< CTxOut > &voutSuperblockRet)
bool GetBlockPayee(int nBlockHeight, CScript &payee)
void PushMessage(CNode *pnode, const std::string &sCommand, Args &&... args)
std::map< int, CMasternodeBlockPayees > mapMasternodeBlocks
std::atomic< int > nVersion
void AddPayee(const CMasternodePaymentVote &vote)
bool HasVerifiedPaymentVote(uint256 hashIn)