mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Refactor MN payee logic in preparation for DIP3 (#2215)
* Refactor block payee filling/validation 1. Move out old budget validation into it's own function (IsOldBudgetBlockValueValid) 2. Refactor IsBlockValueValid to bail out early instead of using deep nested if/else blocks. IMHO, I feel that this makes the code much easier to read and less error prone. 3. Refactor/rename CreateSuperblock and CMasternodePayments::FillBlockPayee to be getters without actually modifying the coinbase TX. The coinbase is now only modified from the global FillBlockPayments function. Makes later changes in DIP3 easier (allowing superblock and MN rewards in same block) * Use __func__ for logging in block payee code * Fix code style nit
This commit is contained in:
parent
d946f21bd9
commit
4d3518fe04
@ -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<CTxOut>& voutSuperblockRet)
|
||||
bool CSuperblockManager::GetSuperblockPayments(int nBlockHeight, std::vector<CTxOut>& 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);
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
|
||||
static bool IsSuperblockTriggered(int nBlockHeight);
|
||||
|
||||
static void CreateSuperblock(CMutableTransaction& txNewRet, int nBlockHeight, std::vector<CTxOut>& voutSuperblockRet);
|
||||
static bool GetSuperblockPayments(int nBlockHeight, std::vector<CTxOut>& voutSuperblockRet);
|
||||
static void ExecuteBestSuperblock(int nBlockHeight);
|
||||
|
||||
static std::string GetRequiredPaymentsString(int nBlockHeight);
|
||||
|
@ -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 = "";
|
||||
|
||||
if (!IsOldBudgetBlockValueValid(block, nBlockHeight, blockReward, strErrorRet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// superblocks started
|
||||
|
||||
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 (!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
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
LogPrintf("IsBlockPayeeValid -- ERROR: Invalid superblock detected at height %d: %s", nBlockHeight, txNew.ToString());
|
||||
} 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;
|
||||
}
|
||||
// continue validation, should pay MN
|
||||
LogPrint("gobject", "IsBlockPayeeValid -- No triggered superblock detected at height %d\n", nBlockHeight);
|
||||
} else {
|
||||
LogPrint("gobject", "%s -- No triggered superblock detected at height %d\n", __func__, 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);
|
||||
LogPrint("gobject", "%s -- triggered superblock creation at height %d\n", __func__, nBlockHeight);
|
||||
CSuperblockManager::GetSuperblockPayments(nBlockHeight, voutSuperblockRet);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// FILL BLOCK PAYEE WITH MASTERNODE PAYMENT OTHERWISE
|
||||
mnpayments.FillBlockPayee(txNew, nBlockHeight, blockReward, txoutMasternodeRet);
|
||||
LogPrint("mnpayments", "FillBlockPayments -- nBlockHeight %d blockReward %lld txoutMasternodeRet %s txNew %s",
|
||||
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;
|
||||
|
||||
|
@ -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(); }
|
||||
|
Loading…
Reference in New Issue
Block a user