diff --git a/src/governance-classes.cpp b/src/governance-classes.cpp index 6722efe266..e21232fa62 100644 --- a/src/governance-classes.cpp +++ b/src/governance-classes.cpp @@ -366,14 +366,14 @@ bool CSuperblockManager::GetBestSuperblock(CSuperblock_sptr& pSuperblockRet, int } /** -* Create Superblock Payments +* Get Superblock Payments * -* - Create the correct payment structure for a given superblock +* - Returns payments for superblock */ -void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBlockHeight, std::vector& voutSuperblockRet) +bool CSuperblockManager::GetSuperblockPayments(int nBlockHeight, std::vector& voutSuperblockRet) { - DBG( std::cout << "CSuperblockManager::CreateSuperblock Start" << std::endl; ); + DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Start" << std::endl; ); LOCK(governance.cs); @@ -381,18 +381,18 @@ void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBl CSuperblock_sptr pSuperblock; if(!CSuperblockManager::GetBestSuperblock(pSuperblock, nBlockHeight)) { - LogPrint("gobject", "CSuperblockManager::CreateSuperblock -- Can't find superblock for height %d\n", nBlockHeight); - DBG( std::cout << "CSuperblockManager::CreateSuperblock Failed to get superblock for height, returning" << std::endl; ); - return; + LogPrint("gobject", "CSuperblockManager::GetSuperblockPayments -- Can't find superblock for height %d\n", nBlockHeight); + DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Failed to get superblock for height, returning" << std::endl; ); + return false; } // make sure it's empty, just in case voutSuperblockRet.clear(); - // CONFIGURE SUPERBLOCK OUTPUTS + // GET SUPERBLOCK OUTPUTS - // Superblock payments are appended to the end of the coinbase vout vector - DBG( std::cout << "CSuperblockManager::CreateSuperblock Number payments: " << pSuperblock->CountPayments() << std::endl; ); + // Superblock payments will be appended to the end of the coinbase vout vector + DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Number payments: " << pSuperblock->CountPayments() << std::endl; ); // TODO: How many payments can we add before things blow up? // Consider at least following limits: @@ -400,13 +400,12 @@ void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBl // - max "budget" available for(int i = 0; i < pSuperblock->CountPayments(); i++) { CGovernancePayment payment; - DBG( std::cout << "CSuperblockManager::CreateSuperblock i = " << i << std::endl; ); + DBG( std::cout << "CSuperblockManager::GetSuperblockPayments i = " << i << std::endl; ); if(pSuperblock->GetPayment(i, payment)) { - DBG( std::cout << "CSuperblockManager::CreateSuperblock Payment found " << std::endl; ); + DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Payment found " << std::endl; ); // SET COINBASE OUTPUT TO SUPERBLOCK SETTING CTxOut txout = CTxOut(payment.nAmount, payment.script); - txNewRet.vout.push_back(txout); voutSuperblockRet.push_back(txout); // PRINT NICE LOG OUTPUT FOR SUPERBLOCK PAYMENT @@ -417,15 +416,17 @@ void CSuperblockManager::CreateSuperblock(CMutableTransaction& txNewRet, int nBl // TODO: PRINT NICE N.N DASH OUTPUT - DBG( std::cout << "CSuperblockManager::CreateSuperblock Before LogPrintf call, nAmount = " << payment.nAmount << std::endl; ); + DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Before LogPrintf call, nAmount = " << payment.nAmount << std::endl; ); LogPrintf("NEW Superblock : output %d (addr %s, amount %d)\n", i, address2.ToString(), payment.nAmount); - DBG( std::cout << "CSuperblockManager::CreateSuperblock After LogPrintf call " << std::endl; ); + DBG( std::cout << "CSuperblockManager::GetSuperblockPayments After LogPrintf call " << std::endl; ); } else { - DBG( std::cout << "CSuperblockManager::CreateSuperblock Payment not found " << std::endl; ); + DBG( std::cout << "CSuperblockManager::GetSuperblockPayments Payment not found " << std::endl; ); } } - DBG( std::cout << "CSuperblockManager::CreateSuperblock End" << std::endl; ); + DBG( std::cout << "CSuperblockManager::GetSuperblockPayments End" << std::endl; ); + + return true; } bool CSuperblockManager::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) @@ -679,7 +680,7 @@ bool CSuperblock::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount b int nOutputs = txNew.vout.size(); int nPayments = CountPayments(); - int nMinerPayments = nOutputs - nPayments; + int nMinerAndMasternodePayments = nOutputs - nPayments; LogPrint("gobject", "CSuperblock::IsValid nOutputs = %d, nPayments = %d, GetDataAsHexString = %s\n", nOutputs, nPayments, GetGovernanceObject()->GetDataAsHexString()); @@ -687,7 +688,7 @@ bool CSuperblock::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount b // We require an exact match (including order) between the expected // superblock payments and the payments actually in the block. - if(nMinerPayments < 0) { + if(nMinerAndMasternodePayments < 0) { // This means the block cannot have all the superblock payments // so it is not valid. // TODO: could that be that we just hit coinbase size limit? @@ -703,7 +704,7 @@ bool CSuperblock::IsValid(const CTransaction& txNew, int nBlockHeight, CAmount b return false; } - // miner should not get more than he would usually get + // miner and masternodes should not get more than they would usually get CAmount nBlockValue = txNew.GetValueOut(); if(nBlockValue > blockReward + nPaymentsTotalAmount) { LogPrintf("CSuperblock::IsValid -- ERROR: Block invalid, block value limit exceeded: block %lld, limit %lld\n", nBlockValue, blockReward + nPaymentsTotalAmount); diff --git a/src/governance-classes.h b/src/governance-classes.h index bb6aa0d452..ccd14f793c 100644 --- a/src/governance-classes.h +++ b/src/governance-classes.h @@ -67,7 +67,7 @@ public: static bool IsSuperblockTriggered(int nBlockHeight); - static void CreateSuperblock(CMutableTransaction& txNewRet, int nBlockHeight, std::vector& voutSuperblockRet); + static bool GetSuperblockPayments(int nBlockHeight, std::vector& voutSuperblockRet); static void ExecuteBestSuperblock(int nBlockHeight); static std::string GetRequiredPaymentsString(int nBlockHeight); diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index e737de6eff..dd28b5e410 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -23,6 +23,45 @@ CCriticalSection cs_vecPayees; CCriticalSection cs_mapMasternodeBlocks; CCriticalSection cs_mapMasternodePaymentVotes; +bool IsOldBudgetBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockReward, std::string& strErrorRet) { + const Consensus::Params& consensusParams = Params().GetConsensus(); + + if (nBlockHeight >= consensusParams.nSuperblockStartBlock) { + // switched to new budget system (superblocks) + return true; + } + + bool isBlockRewardValueMet = (block.vtx[0]->GetValueOut() <= blockReward); + + // we are still using budgets, but we have no data about them anymore, + // all we know is predefined budget cycle and window + + int nOffset = nBlockHeight % consensusParams.nBudgetPaymentsCycleBlocks; + if(nBlockHeight >= consensusParams.nBudgetPaymentsStartBlock && + nOffset < consensusParams.nBudgetPaymentsWindowBlocks) { + // NOTE: old budget system is disabled since 12.1 + if(masternodeSync.IsSynced()) { + // no old budget blocks should be accepted here on mainnet, + // testnet/devnet/regtest should produce regular blocks only + LogPrint("gobject", "%s -- WARNING: Client synced but old budget system is disabled, checking block value against block reward\n", __func__); + if(!isBlockRewardValueMet) { + strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, old budgets are disabled", + nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); + } + return isBlockRewardValueMet; + } + // when not synced, rely on online nodes (all networks) + LogPrint("gobject", "%s -- WARNING: Skipping old budget block value checks, accepting block\n", __func__); + return true; + } + // LogPrint("gobject", "%s -- Block is not in budget cycle window, checking block value against block reward\n", __func__); + if(!isBlockRewardValueMet) { + strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, block is not in old budget cycle window", + nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); + } + return isBlockRewardValueMet; +} + /** * IsBlockValueValid * @@ -38,105 +77,82 @@ bool IsBlockValueValid(const CBlock& block, int nBlockHeight, CAmount blockRewar { strErrorRet = ""; - bool isBlockRewardValueMet = (block.vtx[0]->GetValueOut() <= blockReward); - if(fDebug) LogPrintf("block.vtx[0]->GetValueOut() %lld <= blockReward %lld\n", block.vtx[0]->GetValueOut(), blockReward); - - // we are still using budgets, but we have no data about them anymore, - // all we know is predefined budget cycle and window - - const Consensus::Params& consensusParams = Params().GetConsensus(); - - if(nBlockHeight < consensusParams.nSuperblockStartBlock) { - int nOffset = nBlockHeight % consensusParams.nBudgetPaymentsCycleBlocks; - if(nBlockHeight >= consensusParams.nBudgetPaymentsStartBlock && - nOffset < consensusParams.nBudgetPaymentsWindowBlocks) { - // NOTE: old budget system is disabled since 12.1 - if(masternodeSync.IsSynced()) { - // no old budget blocks should be accepted here on mainnet, - // testnet/devnet/regtest should produce regular blocks only - LogPrint("gobject", "IsBlockValueValid -- WARNING: Client synced but old budget system is disabled, checking block value against block reward\n"); - if(!isBlockRewardValueMet) { - strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, old budgets are disabled", - nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); - } - return isBlockRewardValueMet; - } - // when not synced, rely on online nodes (all networks) - LogPrint("gobject", "IsBlockValueValid -- WARNING: Skipping old budget block value checks, accepting block\n"); - return true; - } - // LogPrint("gobject", "IsBlockValueValid -- Block is not in budget cycle window, checking block value against block reward\n"); - if(!isBlockRewardValueMet) { - strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, block is not in old budget cycle window", - nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); - } - return isBlockRewardValueMet; + if (!IsOldBudgetBlockValueValid(block, nBlockHeight, blockReward, strErrorRet)) { + return false; } - // superblocks started + bool isBlockRewardValueMet = (block.vtx[0]->GetValueOut() <= blockReward); + if(fDebug) LogPrintf("block.vtx[0]->GetValueOut() %lld <= blockReward %lld\n", block.vtx[0]->GetValueOut(), blockReward); CAmount nSuperblockMaxValue = blockReward + CSuperblock::GetPaymentsLimit(nBlockHeight); bool isSuperblockMaxValueMet = (block.vtx[0]->GetValueOut() <= nSuperblockMaxValue); LogPrint("gobject", "block.vtx[0]->GetValueOut() %lld <= nSuperblockMaxValue %lld\n", block.vtx[0]->GetValueOut(), nSuperblockMaxValue); - if(!masternodeSync.IsSynced() || fLiteMode) { - // not enough data but at least it must NOT exceed superblock max value - if(CSuperblock::IsValidBlockHeight(nBlockHeight)) { - if(fDebug) LogPrintf("IsBlockPayeeValid -- WARNING: Not enough data, checking superblock max bounds only\n"); - if(!isSuperblockMaxValueMet) { - strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded superblock max value", - nBlockHeight, block.vtx[0]->GetValueOut(), nSuperblockMaxValue); - } - return isSuperblockMaxValueMet; - } - if(!isBlockRewardValueMet) { + if (!CSuperblock::IsValidBlockHeight(nBlockHeight)) { + // can't possibly be a superblock, so lets just check for block reward limits + if (!isBlockRewardValueMet) { 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", nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); } - // it MUST be a regular block otherwise return isBlockRewardValueMet; } - // we are synced, let's try to check as much data as we can + // bail out in case superblock limits were exceeded + if (!isSuperblockMaxValueMet) { + strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded superblock max value", + nBlockHeight, block.vtx[0]->GetValueOut(), nSuperblockMaxValue); + return false; + } - if(sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED)) { - if(CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) { - if(CSuperblockManager::IsValid(*block.vtx[0], nBlockHeight, blockReward)) { - LogPrint("gobject", "IsBlockValueValid -- Valid superblock at height %d: %s", nBlockHeight, block.vtx[0]->ToString()); - // all checks are done in CSuperblock::IsValid, nothing to do here - return true; - } + if(!masternodeSync.IsSynced() || fLiteMode) { + if(fDebug) LogPrintf("%s -- WARNING: Not enough data, checked superblock max bounds only\n", __func__); + // not enough data for full checks but at least we know that the superblock limits were honored. + // We rely on the network to have followed the correct chain in this case + return true; + } - // triggered but invalid? that's weird - LogPrintf("IsBlockValueValid -- ERROR: Invalid superblock detected at height %d: %s", nBlockHeight, block.vtx[0]->ToString()); - // should NOT allow invalid superblocks, when superblocks are enabled - strErrorRet = strprintf("invalid superblock detected at height %d", nBlockHeight); - return false; - } - LogPrint("gobject", "IsBlockValueValid -- No triggered superblock detected at height %d\n", nBlockHeight); - if(!isBlockRewardValueMet) { - strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, no triggered superblock detected", - nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); - } - } else { + // we are synced and possibly on a superblock now + + if (!sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED)) { // should NOT allow superblocks at all, when superblocks are disabled - LogPrint("gobject", "IsBlockValueValid -- Superblocks are disabled, no superblocks allowed\n"); + // revert to block reward limits in this case + LogPrint("gobject", "%s -- Superblocks are disabled, no superblocks allowed\n", __func__); if(!isBlockRewardValueMet) { strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, superblocks are disabled", nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); } + return isBlockRewardValueMet; } - // it MUST be a regular block - return isBlockRewardValueMet; + if (!CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) { + // we are on a valid superblock height but a superblock was not triggered + // revert to block reward limits in this case + if(!isBlockRewardValueMet) { + strErrorRet = strprintf("coinbase pays too much at height %d (actual=%d vs limit=%d), exceeded block reward, no triggered superblock detected", + nBlockHeight, block.vtx[0]->GetValueOut(), blockReward); + } + return isBlockRewardValueMet; + } + + // this actually also checks for correct payees and not only amount + if (!CSuperblockManager::IsValid(*block.vtx[0], nBlockHeight, blockReward)) { + // triggered but invalid? that's weird + LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, block.vtx[0]->ToString()); + // should NOT allow invalid superblocks, when superblocks are enabled + strErrorRet = strprintf("invalid superblock detected at height %d", nBlockHeight); + return false; + } + + // we got a valid superblock + return true; } bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) { if(!masternodeSync.IsSynced() || fLiteMode) { //there is no budget data to use to check anything, let's just accept the longest chain - if(fDebug) LogPrintf("IsBlockPayeeValid -- WARNING: Not enough data, skipping block payee checks\n"); + if(fDebug) LogPrintf("%s -- WARNING: Not enough data, skipping block payee checks\n", __func__); return true; } @@ -149,7 +165,7 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount bloc // NOTE: old budget system is disabled since 12.1 and we should never enter this branch // anymore when sync is finished (on mainnet). We have no old budget data but these blocks // have tons of confirmations and can be safely accepted without payee verification - LogPrint("gobject", "IsBlockPayeeValid -- WARNING: Client synced but old budget system is disabled, accepting any payee\n"); + LogPrint("gobject", "%s -- WARNING: Client synced but old budget system is disabled, accepting any payee\n", __func__); return true; } @@ -159,33 +175,33 @@ bool IsBlockPayeeValid(const CTransaction& txNew, int nBlockHeight, CAmount bloc if(sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED)) { if(CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) { if(CSuperblockManager::IsValid(txNew, nBlockHeight, blockReward)) { - LogPrint("gobject", "IsBlockPayeeValid -- Valid superblock at height %d: %s", nBlockHeight, txNew.ToString()); + LogPrint("gobject", "%s -- Valid superblock at height %d: %s", __func__, nBlockHeight, txNew.ToString()); return true; + } else { + LogPrintf("%s -- ERROR: Invalid superblock detected at height %d: %s", __func__, nBlockHeight, txNew.ToString()); + // should NOT allow such superblocks, when superblocks are enabled + return false; } - - LogPrintf("IsBlockPayeeValid -- ERROR: Invalid superblock detected at height %d: %s", nBlockHeight, txNew.ToString()); - // should NOT allow such superblocks, when superblocks are enabled - return false; + } else { + LogPrint("gobject", "%s -- No triggered superblock detected at height %d\n", __func__, nBlockHeight); } - // continue validation, should pay MN - LogPrint("gobject", "IsBlockPayeeValid -- No triggered superblock detected at height %d\n", nBlockHeight); } else { // should NOT allow superblocks at all, when superblocks are disabled - LogPrint("gobject", "IsBlockPayeeValid -- Superblocks are disabled, no superblocks allowed\n"); + LogPrint("gobject", "%s -- Superblocks are disabled, no superblocks allowed\n", __func__); } - // IF THIS ISN'T A SUPERBLOCK OR SUPERBLOCK IS INVALID, IT SHOULD PAY A MASTERNODE DIRECTLY - if(mnpayments.IsTransactionValid(txNew, nBlockHeight)) { - LogPrint("mnpayments", "IsBlockPayeeValid -- Valid masternode payment at height %d: %s", nBlockHeight, txNew.ToString()); + // If this isn't a superblock or spork15 is activated, check for correct masternode payment + if(mnpayments.IsTransactionValid(txNew, nBlockHeight, blockReward)) { + LogPrint("mnpayments", "%s -- Valid masternode payment at height %d: %s", __func__, nBlockHeight, txNew.ToString()); return true; } if(sporkManager.IsSporkActive(SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT)) { - LogPrintf("IsBlockPayeeValid -- ERROR: Invalid masternode payment detected at height %d: %s", nBlockHeight, txNew.ToString()); + LogPrintf("%s -- ERROR: Invalid masternode payment detected at height %d: %s", __func__, nBlockHeight, txNew.ToString()); return false; } - LogPrintf("IsBlockPayeeValid -- WARNING: Masternode payment enforcement is disabled, accepting any payee\n"); + LogPrintf("%s -- WARNING: Masternode payment enforcement is disabled, accepting any payee\n", __func__); return true; } @@ -195,14 +211,33 @@ void FillBlockPayments(CMutableTransaction& txNew, int nBlockHeight, CAmount blo // (height should be validated inside) if(sporkManager.IsSporkActive(SPORK_9_SUPERBLOCKS_ENABLED) && CSuperblockManager::IsSuperblockTriggered(nBlockHeight)) { - LogPrint("gobject", "FillBlockPayments -- triggered superblock creation at height %d\n", nBlockHeight); - CSuperblockManager::CreateSuperblock(txNew, nBlockHeight, voutSuperblockRet); - return; + LogPrint("gobject", "%s -- triggered superblock creation at height %d\n", __func__, nBlockHeight); + CSuperblockManager::GetSuperblockPayments(nBlockHeight, voutSuperblockRet); } - // FILL BLOCK PAYEE WITH MASTERNODE PAYMENT OTHERWISE - mnpayments.FillBlockPayee(txNew, nBlockHeight, blockReward, txoutMasternodeRet); - LogPrint("mnpayments", "FillBlockPayments -- nBlockHeight %d blockReward %lld txoutMasternodeRet %s txNew %s", + // TODO this is a placeholder until DIP3 is merged, which will allow superblock payments and MN reward payments + // in the same block. We set this to false for now, which means that we'll always get into the next if statement + // when a superblock payment is present + bool allowSuperblockAndMNReward = false; + + // don't allow payments to superblocks AND masternodes before spork15 activation + if (!voutSuperblockRet.empty() && !allowSuperblockAndMNReward) { + txNew.vout.insert(txNew.vout.end(), voutSuperblockRet.begin(), voutSuperblockRet.end()); + return; + } + + if (!mnpayments.GetMasternodeTxOut(nBlockHeight, blockReward, txoutMasternodeRet)) { + // no idea whom to pay (MN list empty?), lets hope for the best + return; + } + + txNew.vout.emplace_back(txoutMasternodeRet); + txNew.vout.insert(txNew.vout.end(), voutSuperblockRet.begin(), voutSuperblockRet.end()); + + // subtract MN payment from miner reward + txNew.vout[0].nValue -= txoutMasternodeRet.nValue; + + LogPrint("mnpayments", "%s -- nBlockHeight %d blockReward %lld txoutMasternodeRet %s txNew %s", __func__, nBlockHeight, blockReward, txoutMasternodeRet.ToString(), txNew.ToString()); } @@ -244,10 +279,10 @@ bool CMasternodePayments::UpdateLastVote(const CMasternodePaymentVote& vote) /** * FillBlockPayee * -* Fill Masternode ONLY payment block +* Get masternode payment tx output */ -void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int nBlockHeight, CAmount blockReward, CTxOut& txoutMasternodeRet) const +bool CMasternodePayments::GetMasternodeTxOut(int nBlockHeight, CAmount blockReward, CTxOut& txoutMasternodeRet) const { // make sure it's not filled yet txoutMasternodeRet = CTxOut(); @@ -260,8 +295,8 @@ void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int nBlockH masternode_info_t mnInfo; if(!mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount, mnInfo)) { // ...and we can't calculate it on our own - LogPrintf("CMasternodePayments::FillBlockPayee -- Failed to detect masternode to pay\n"); - return; + LogPrintf("CMasternodePayments::%s -- Failed to detect masternode to pay\n", __func__); + return false; } // fill payee with locally calculated winner and hope for the best payee = GetScriptForDestination(mnInfo.keyIDCollateralAddress); @@ -269,18 +304,15 @@ void CMasternodePayments::FillBlockPayee(CMutableTransaction& txNew, int nBlockH // GET MASTERNODE PAYMENT VARIABLES SETUP CAmount masternodePayment = GetMasternodePayment(nBlockHeight, blockReward); - - // split reward between miner ... - txNew.vout[0].nValue -= masternodePayment; - // ... and masternode txoutMasternodeRet = CTxOut(masternodePayment, payee); - txNew.vout.push_back(txoutMasternodeRet); CTxDestination address1; ExtractDestination(payee, address1); CBitcoinAddress address2(address1); - LogPrintf("CMasternodePayments::FillBlockPayee -- Masternode payment %lld to %s\n", masternodePayment, address2.ToString()); + LogPrintf("CMasternodePayments::%s -- Masternode payment %lld to %s\n", __func__, masternodePayment, address2.ToString()); + + return true; } int CMasternodePayments::GetMinMasternodePaymentsProto() const { @@ -445,12 +477,12 @@ bool CMasternodePaymentVote::Sign() uint256 hash = GetSignatureHash(); if(!CHashSigner::SignHash(hash, activeMasternodeInfo.keyMasternode, vchSig)) { - LogPrintf("CMasternodePaymentVote::Sign -- SignHash() failed\n"); + LogPrintf("CMasternodePaymentVote::%s -- SignHash() failed\n", __func__); return false; } if (!CHashSigner::VerifyHash(hash, activeMasternodeInfo.keyIDMasternode, vchSig, strError)) { - LogPrintf("CMasternodePaymentVote::Sign -- VerifyHash() failed, error: %s\n", strError); + LogPrintf("CMasternodePaymentVote::%s -- VerifyHash() failed, error: %s\n", __func__, strError); return false; } } else { @@ -459,12 +491,12 @@ bool CMasternodePaymentVote::Sign() ScriptToAsmStr(payee); if(!CMessageSigner::SignMessage(strMessage, vchSig, activeMasternodeInfo.keyMasternode)) { - LogPrintf("CMasternodePaymentVote::Sign -- SignMessage() failed\n"); + LogPrintf("CMasternodePaymentVote::%s -- SignMessage() failed\n", __func__); return false; } if(!CMessageSigner::VerifyMessage(activeMasternodeInfo.keyIDMasternode, vchSig, strMessage, strError)) { - LogPrintf("CMasternodePaymentVote::Sign -- VerifyMessage() failed, error: %s\n", strError); + LogPrintf("CMasternodePaymentVote::%s -- VerifyMessage() failed, error: %s\n", __func__, strError); return false; } } @@ -518,7 +550,7 @@ bool CMasternodePayments::AddOrUpdatePaymentVote(const CMasternodePaymentVote& v auto it = mapMasternodeBlocks.emplace(vote.nBlockHeight, CMasternodeBlockPayees(vote.nBlockHeight)).first; it->second.AddPayee(vote); - LogPrint("mnpayments", "CMasternodePayments::AddOrUpdatePaymentVote -- added, hash=%s\n", nVoteHash.ToString()); + LogPrint("mnpayments", "CMasternodePayments::%s -- added, hash=%s\n", __func__, nVoteHash.ToString()); return true; } @@ -551,7 +583,7 @@ bool CMasternodeBlockPayees::GetBestPayee(CScript& payeeRet) const LOCK(cs_vecPayees); if(vecPayees.empty()) { - LogPrint("mnpayments", "CMasternodeBlockPayees::GetBestPayee -- ERROR: couldn't find any payee\n"); + LogPrint("mnpayments", "CMasternodeBlockPayees::%s -- ERROR: couldn't find any payee\n", __func__); return false; } @@ -576,7 +608,7 @@ bool CMasternodeBlockPayees::HasPayeeWithVotes(const CScript& payeeIn, int nVote } } - LogPrint("mnpayments", "CMasternodeBlockPayees::HasPayeeWithVotes -- ERROR: couldn't find any payee with %d+ votes\n", nVotesReq); + LogPrint("mnpayments", "CMasternodeBlockPayees::%s -- ERROR: couldn't find any payee with %d+ votes\n", __func__, nVotesReq); return false; } @@ -604,7 +636,7 @@ bool CMasternodeBlockPayees::IsTransactionValid(const CTransaction& txNew) const if (payee.GetVoteCount() >= MNPAYMENTS_SIGNATURES_REQUIRED) { for (const auto& txout : txNew.vout) { if (payee.GetPayee() == txout.scriptPubKey && nMasternodePayment == txout.nValue) { - LogPrint("mnpayments", "CMasternodeBlockPayees::IsTransactionValid -- Found required payment\n"); + LogPrint("mnpayments", "CMasternodeBlockPayees::%s -- Found required payment\n", __func__); return true; } } @@ -621,7 +653,7 @@ bool CMasternodeBlockPayees::IsTransactionValid(const CTransaction& txNew) const } } - LogPrintf("CMasternodeBlockPayees::IsTransactionValid -- ERROR: Missing required payment, possible payees: '%s', amount: %f DASH\n", strPayeesPossible, (float)nMasternodePayment/COIN); + LogPrintf("CMasternodeBlockPayees::%s -- ERROR: Missing required payment, possible payees: '%s', amount: %f DASH\n", __func__, strPayeesPossible, (float)nMasternodePayment/COIN); return false; } @@ -657,10 +689,9 @@ std::string CMasternodePayments::GetRequiredPaymentsString(int nBlockHeight) con return it == mapMasternodeBlocks.end() ? "Unknown" : it->second.GetRequiredPaymentsString(); } -bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlockHeight) const +bool CMasternodePayments::IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const { LOCK(cs_mapMasternodeBlocks); - const auto it = mapMasternodeBlocks.find(nBlockHeight); return it == mapMasternodeBlocks.end() ? true : it->second.IsTransactionValid(txNew); } @@ -678,14 +709,14 @@ void CMasternodePayments::CheckAndRemove() CMasternodePaymentVote vote = (*it).second; if(nCachedBlockHeight - vote.nBlockHeight > nLimit) { - LogPrint("mnpayments", "CMasternodePayments::CheckAndRemove -- Removing old Masternode payment: nBlockHeight=%d\n", vote.nBlockHeight); + LogPrint("mnpayments", "CMasternodePayments::%s -- Removing old Masternode payment: nBlockHeight=%d\n", __func__, vote.nBlockHeight); mapMasternodePaymentVotes.erase(it++); mapMasternodeBlocks.erase(vote.nBlockHeight); } else { ++it; } } - LogPrintf("CMasternodePayments::CheckAndRemove -- %s\n", ToString()); + LogPrintf("CMasternodePayments::%s -- %s\n", __func__, ToString()); } bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::string& strError, CConnman& connman) const @@ -723,7 +754,7 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s int nRank; if(!mnodeman.GetMasternodeRank(masternodeOutpoint, nRank, nBlockHeight - 101, nMinRequiredProtocol)) { - LogPrint("mnpayments", "CMasternodePaymentVote::IsValid -- Can't calculate rank for masternode %s\n", + LogPrint("mnpayments", "CMasternodePaymentVote::%s -- Can't calculate rank for masternode %s\n", __func__, masternodeOutpoint.ToStringShort()); return false; } @@ -736,7 +767,7 @@ bool CMasternodePaymentVote::IsValid(CNode* pnode, int nValidationHeight, std::s if(nRank > MNPAYMENTS_SIGNATURES_TOTAL*2 && nBlockHeight > nValidationHeight) { LOCK(cs_main); strError = strprintf("Masternode %s is not in the top %d (%d)", masternodeOutpoint.ToStringShort(), MNPAYMENTS_SIGNATURES_TOTAL*2, nRank); - LogPrintf("CMasternodePaymentVote::IsValid -- Error: %s\n", strError); + LogPrintf("CMasternodePaymentVote::%s -- Error: %s\n", __func__, strError); Misbehaving(pnode->GetId(), 20); } // Still invalid however @@ -760,30 +791,30 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight, CConnman& connman) int nRank; if (!mnodeman.GetMasternodeRank(activeMasternodeInfo.outpoint, nRank, nBlockHeight - 101, GetMinMasternodePaymentsProto())) { - LogPrint("mnpayments", "CMasternodePayments::ProcessBlock -- Unknown Masternode\n"); + LogPrint("mnpayments", "CMasternodePayments::%s -- Unknown Masternode\n", __func__); return false; } if (nRank > MNPAYMENTS_SIGNATURES_TOTAL) { - LogPrint("mnpayments", "CMasternodePayments::ProcessBlock -- Masternode not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL, nRank); + LogPrint("mnpayments", "CMasternodePayments::%s -- Masternode not in the top %d (%d)\n", __func__, MNPAYMENTS_SIGNATURES_TOTAL, nRank); return false; } // LOCATE THE NEXT MASTERNODE WHICH SHOULD BE PAID - LogPrintf("CMasternodePayments::ProcessBlock -- Start: nBlockHeight=%d, masternode=%s\n", nBlockHeight, activeMasternodeInfo.outpoint.ToStringShort()); + LogPrintf("CMasternodePayments::%s -- Start: nBlockHeight=%d, masternode=%s\n", __func__, nBlockHeight, activeMasternodeInfo.outpoint.ToStringShort()); // pay to the oldest MN that still had no payment but its input is old enough and it was active long enough int nCount = 0; masternode_info_t mnInfo; if (!mnodeman.GetNextMasternodeInQueueForPayment(nBlockHeight, true, nCount, mnInfo)) { - LogPrintf("CMasternodePayments::ProcessBlock -- ERROR: Failed to find masternode to pay\n"); + LogPrintf("CMasternodePayments::%s -- ERROR: Failed to find masternode to pay\n", __func__); return false; } - LogPrintf("CMasternodePayments::ProcessBlock -- Masternode found by GetNextMasternodeInQueueForPayment(): %s\n", mnInfo.outpoint.ToStringShort()); + LogPrintf("CMasternodePayments::%s -- Masternode found by GetNextMasternodeInQueueForPayment(): %s\n", __func__, mnInfo.outpoint.ToStringShort()); CScript payee = GetScriptForDestination(mnInfo.keyIDCollateralAddress); @@ -794,13 +825,13 @@ bool CMasternodePayments::ProcessBlock(int nBlockHeight, CConnman& connman) ExtractDestination(payee, address1); CBitcoinAddress address2(address1); - LogPrintf("CMasternodePayments::ProcessBlock -- vote: payee=%s, nBlockHeight=%d\n", address2.ToString(), nBlockHeight); + LogPrintf("CMasternodePayments::%s -- vote: payee=%s, nBlockHeight=%d\n", address2.ToString(), nBlockHeight); // SIGN MESSAGE TO NETWORK WITH OUR MASTERNODE KEYS - LogPrintf("CMasternodePayments::ProcessBlock -- Signing vote\n"); + LogPrintf("CMasternodePayments::%s -- Signing vote\n", __func__); if (voteNew.Sign()) { - LogPrintf("CMasternodePayments::ProcessBlock -- AddOrUpdatePaymentVote()\n"); + LogPrintf("CMasternodePayments::%s -- AddOrUpdatePaymentVote()\n", __func__); if (AddOrUpdatePaymentVote(voteNew)) { voteNew.Relay(connman); @@ -817,13 +848,13 @@ void CMasternodePayments::CheckBlockVotes(int nBlockHeight) CMasternodeMan::rank_pair_vec_t mns; if (!mnodeman.GetMasternodeRanks(mns, nBlockHeight - 101, GetMinMasternodePaymentsProto())) { - LogPrintf("CMasternodePayments::CheckBlockVotes -- nBlockHeight=%d, GetMasternodeRanks failed\n", nBlockHeight); + LogPrintf("CMasternodePayments::%s -- nBlockHeight=%d, GetMasternodeRanks failed\n", __func__, nBlockHeight); return; } std::string debugStr; - debugStr += strprintf("CMasternodePayments::CheckBlockVotes -- nBlockHeight=%d,\n Expected voting MNs:\n", nBlockHeight); + debugStr += strprintf("CMasternodePayments::%s -- nBlockHeight=%d,\n Expected voting MNs:\n", __func__, nBlockHeight); LOCK2(cs_mapMasternodeBlocks, cs_mapMasternodePaymentVotes); @@ -885,7 +916,7 @@ void CMasternodePaymentVote::Relay(CConnman& connman) const { // Do not relay until fully synced if(!masternodeSync.IsSynced()) { - LogPrint("mnpayments", "CMasternodePayments::Relay -- won't relay until fully synced\n"); + LogPrint("mnpayments", "CMasternodePayments::%s -- won't relay until fully synced\n", __func__); return; } @@ -974,7 +1005,7 @@ void CMasternodePayments::Sync(CNode* pnode, CConnman& connman) const } } - LogPrintf("CMasternodePayments::Sync -- Sent %d votes to peer=%d\n", nInvCount, pnode->id); + LogPrintf("CMasternodePayments::%s -- Sent %d votes to peer=%d\n", __func__, nInvCount, pnode->id); CNetMsgMaker msgMaker(pnode->GetSendVersion()); connman.PushMessage(pnode, msgMaker.Make(NetMsgType::SYNCSTATUSCOUNT, MASTERNODE_SYNC_MNW, nInvCount)); } @@ -999,7 +1030,7 @@ void CMasternodePayments::RequestLowDataPaymentBlocks(CNode* pnode, CConnman& co vToFetch.push_back(CInv(MSG_MASTERNODE_PAYMENT_BLOCK, pindex->GetBlockHash())); // We should not violate GETDATA rules if(vToFetch.size() == MAX_INV_SZ) { - LogPrintf("CMasternodePayments::RequestLowDataPaymentBlocks -- asking peer=%d for %d blocks\n", pnode->id, MAX_INV_SZ); + LogPrintf("CMasternodePayments::%s -- asking peer=%d for %d blocks\n", __func__, pnode->id, MAX_INV_SZ); connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch)); // Start filling new batch vToFetch.clear(); @@ -1045,7 +1076,7 @@ void CMasternodePayments::RequestLowDataPaymentBlocks(CNode* pnode, CConnman& co } // We should not violate GETDATA rules if(vToFetch.size() == MAX_INV_SZ) { - LogPrintf("CMasternodePayments::RequestLowDataPaymentBlocks -- asking peer=%d for %d payment blocks\n", pnode->id, MAX_INV_SZ); + LogPrintf("CMasternodePayments::%s -- asking peer=%d for %d payment blocks\n", __func__, pnode->id, MAX_INV_SZ); connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch)); // Start filling new batch vToFetch.clear(); @@ -1053,7 +1084,7 @@ void CMasternodePayments::RequestLowDataPaymentBlocks(CNode* pnode, CConnman& co } // Ask for the rest of it if(!vToFetch.empty()) { - LogPrintf("CMasternodePayments::RequestLowDataPaymentBlocks -- asking peer=%d for %d payment blocks\n", pnode->id, vToFetch.size()); + LogPrintf("CMasternodePayments::%s -- asking peer=%d for %d payment blocks\n", __func__, pnode->id, vToFetch.size()); connman.PushMessage(pnode, msgMaker.Make(NetMsgType::GETDATA, vToFetch)); } } @@ -1085,7 +1116,7 @@ void CMasternodePayments::UpdatedBlockTip(const CBlockIndex *pindex, CConnman& c if(!pindex) return; nCachedBlockHeight = pindex->nHeight; - LogPrint("mnpayments", "CMasternodePayments::UpdatedBlockTip -- nCachedBlockHeight=%d\n", nCachedBlockHeight); + LogPrint("mnpayments", "CMasternodePayments::%s -- nCachedBlockHeight=%d\n", __func__, nCachedBlockHeight); int nFutureBlock = nCachedBlockHeight + 10; diff --git a/src/masternode-payments.h b/src/masternode-payments.h index 3db062d6ff..dca936a123 100644 --- a/src/masternode-payments.h +++ b/src/masternode-payments.h @@ -214,7 +214,7 @@ public: void CheckAndRemove(); bool GetBlockPayee(int nBlockHeight, CScript& payeeRet) const; - bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight) const; + bool IsTransactionValid(const CTransaction& txNew, int nBlockHeight, CAmount blockReward) const; bool IsScheduled(const masternode_info_t& mnInfo, int nNotBlockHeight) const; bool UpdateLastVote(const CMasternodePaymentVote& vote); @@ -222,7 +222,7 @@ public: int GetMinMasternodePaymentsProto() const; void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman); std::string GetRequiredPaymentsString(int nBlockHeight) const; - void FillBlockPayee(CMutableTransaction& txNew, int nBlockHeight, CAmount blockReward, CTxOut& txoutMasternodeRet) const; + bool GetMasternodeTxOut(int nBlockHeight, CAmount blockReward, CTxOut& txoutMasternodeRet) const; std::string ToString() const; int GetBlockCount() const { return mapMasternodeBlocks.size(); }